WooCommerce Payment Method Fee Snippet Generator
Add a fee for one payment method, like cash on delivery or a specific card processor, that also updates the block checkout.
Your details
Payment method fee snippet (PHP)
<?php
/**
* Adds the configured payment-method fee for the selected gateway. Reads the payment
* method from the session, which the Store API sets on the same key
* (WC()->session->set('chosen_payment_method', ...)) when a shopper picks a method in
* the block Checkout, so this fee applies there too once the block recalculates the
* order (it does that automatically when the payment step changes).
*/
add_action( 'woocommerce_cart_calculate_fees', 'ea_add_payment_method_fee' );
function ea_add_payment_method_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
$chosen = WC()->session ? WC()->session->get( 'chosen_payment_method' ) : '';
if ( 'cod' !== $chosen ) {
return;
}
$fee = 2.00;
if ( $fee <= 0 ) {
return;
}
$cart->add_fee( 'Cash on delivery fee', $fee, false );
}
/**
* Classic (shortcode) Checkout only: refreshes the totals when the shopper changes
* payment method, so the fee appears without a full page reload. The block Checkout
* already recalculates automatically and doesn't need this.
*/
add_action( 'wp_footer', 'ea_payment_method_fee_refresh_script' );
function ea_payment_method_fee_refresh_script() {
if ( ! function_exists( 'is_checkout' ) || ! is_checkout() || is_order_received_page() ) {
return;
}
?>
<script>
jQuery( function ( $ ) {
$( document.body ).on( 'change', 'input[name="payment_method"]', function () {
$( document.body ).trigger( 'update_checkout' );
} );
} );
</script>
<?php
}
Add this with a code snippet plugin or your child theme's functions.php, then place a test order with that gateway selected to confirm the fee line appears.
Card surcharging rules vary by country and card network. The UK bans surcharging consumers on card payments (Payment Services Regulations 2017), the EU restricts it under PSD2 for regulated card schemes, and several US states restrict it too. Check your own country's rules, your payment processor's terms and Visa/Mastercard's own surcharge caps before charging extra for card payments specifically.
"cod" must match the gateway's ID exactly, not its title. Find it in the URL when you edit the gateway under WooCommerce → Settings → Payments, or in the plugin's own documentation.
Why it also works in the block checkout
The fee is added through woocommerce_cart_calculate_fees, checked against WC()->session->get('chosen_payment_method'). On the classic checkout, that session value updates when a small JS snippet triggers update_checkout after the shopper changes payment method, which this generator includes automatically. On the block Checkout, selecting a payment method already calls the Store API and sets that exact same session key, and the block recalculates the draft order's totals as part of its own flow, so the fee shows up without any extra code on that side.
Default settings
- Gateway
- cod (cash on delivery)
- Fee
- $2 fixed
A cart shows an extra "Cash on delivery fee: $2.00" line the moment cash on delivery is selected as the payment method, on both checkouts.
Where card surcharges are restricted
Charging extra specifically for paying by card is regulated in a lot of places, separate from WooCommerce's technical ability to do it.
- UK: surcharging consumers for card payments (debit or credit) has been banned since the Payment Services Regulations 2017 took effect on 13 January 2018.
- EU: PSD2 restricts surcharging on card schemes covered by the EU's interchange fee regulation, covering most consumer debit and credit cards.
- US: several states restrict or ban credit card surcharging; card network rules (Visa, Mastercard) also cap how much you can add even where it's legal.
- A flat cash-on-delivery handling fee, or a fee that applies to a non-card method, generally isn't a "card surcharge" in the regulatory sense, but check your own country's and processor's rules before charging extra for any specific payment method.
Adding it
- 01
Find the gateway ID
WooCommerce → Settings → Payments, open the gateway you want, and check the URL or its documentation for its exact ID (not its display title).
- 02
Add the snippet
Paste it into a code snippet plugin or your child theme's
functions.php, then place a test order to confirm the fee appears.
Questions people ask
Will this fee show up before the shopper reaches the payment step?
No, it only appears once a payment method is actually selected, since that's what the fee is conditional on. Before that, the cart total won't include it.
Does this work for a percentage-based processing fee?
Yes, switch "Fee type" to percentage, calculated on the cart subtotal.
Is charging a fee for cash on delivery legal?
Generally yes, since it's not a card surcharge, but check your own country's consumer protection rules, since some places regulate any payment-method-based fee, not just card surcharges.
Why is the gateway ID important, not the title?
WooCommerce identifies each payment method internally by a fixed ID (like cod, bacs, paypal); the title is just what's shown to shoppers and can be renamed, which is why the snippet checks the ID.
Does the fee get taxed?
Only if you turn on "Charge tax on the fee", which follows the same tax rules as any other WooCommerce fee.
