Skip to content
July 11, 2026·4 min read

How to Enable Cash on Delivery for Specific Counties Only in WooCommerce

A practical guide to restricting cash on delivery by region in WooCommerce, using shipping zones or one small snippet, no bloated plugins.

Cash on delivery (COD) sells well, but you rarely want to offer it everywhere. Maybe your courier only supports COD in certain areas, maybe you get too many refused parcels in some regions, or you want COD locally and online payment everywhere else. The good news: WooCommerce lets you do exactly that.

The catch is that WooCommerce has no "accept COD in county A and B but not the rest" button. The cash on delivery method is tied to shipping methods, not directly to a region. Once that clicks, the rest is simple. I'll show you two clean paths: one with no code, using Shipping Zones, and one with a small snippet that filters by the address region. Pick whichever fits your store.

Why you can't just tick "COD per county"

In WooCommerce, the Cash on delivery gateway has one setting that matters for restricting it: "Enable for shipping methods." There is no region field in the payment settings.

So the real logic is:

  • The customer's region determines which Shipping Zone the order falls into.
  • The shipping zone determines which shipping methods the customer sees.
  • The shipping method determines whether COD appears at all.

You don't "enable COD per region" directly — you build zones by region and tie COD to the methods inside those zones. It sounds roundabout, but it's stable, depends on no plugin, and survives updates. Make sure your checkout actually asks for the state/region field under Settings > General, otherwise there's nothing for the filter to read.

Method 1 (no code): Shipping Zones + "Enable for shipping methods"

The cleanest approach, recommended if you'd rather not touch code.

  • Go to WooCommerce > Settings > Shipping > Shipping Zones.
  • Create a zone called "COD allowed" and add only the regions where you accept COD. WooCommerce lets you add individual states/regions to a zone.
  • In that zone, add the shipping method you want COD to ride on (e.g. "Courier delivery").
  • Create a second zone (or use "Locations not covered") for the rest of the country, with the same shipping methods, but there you'll block COD.
  • Go to WooCommerce > Settings > Payments > Cash on delivery > "Enable for shipping methods" and select ONLY the method from the "COD allowed" zone.

Result: a customer in an allowed region sees COD, one outside it doesn't. No code, no plugin.

Method 2 (with code): a snippet that filters by region

If zones would complicate your shipping too much (you already have per-zone rates and don't want to duplicate them), you can hide COD directly based on the address region. Put the snippet in your child theme's functions.php or a snippets plugin (Code Snippets):

```php

add_filter( 'woocommerce_available_payment_gateways', 'mpo_cod_by_region' );

function mpo_cod_by_region( $gateways ) {

if ( is_admin() && ! wp_doing_ajax() ) {

return $gateways;

}

// Regions where you ACCEPT COD (WooCommerce state codes)

$allowed = array( 'CJ', 'TM', 'IF', 'B' );

$state = WC()->customer ? WC()->customer->get_shipping_state() : '';

if ( ! in_array( $state, $allowed, true ) && isset( $gateways['cod'] ) ) {

unset( $gateways['cod'] );

}

return $gateways;

}

```

The codes are WooCommerce's state codes for your country. Edit the list and you're done. To flip the logic (COD everywhere EXCEPT a few regions), put the blocked regions in the array and invert the in_array condition.

Testing and common pitfalls

Before you celebrate, check:

  • Test with real addresses from different regions. Add a product to the cart, go to checkout and change the shipping region — payment methods update via AJAX, so you should see COD appear and disappear live.
  • Watch billing vs. shipping region. The snippet above reads the shipping region (shipping_state). If your store only uses the billing address, switch to get_billing_state().
  • Cache can lie to you. If you run a cache plugin or CDN, purge it after changes, or you'll see the old checkout.
  • Don't forget the COD fee. Region restriction decides who can pay cash, but adding a COD surcharge is a separate setting (a fee on the payment method, or via a woocommerce_cart_calculate_fees snippet).

Always test on a staging environment before going live, especially if you touch functions.php.

When it's worth getting help (and how we work)

If you have one simple rule — a few regions with COD, online payment for the rest — you can do it yourself in minutes with the methods above. Help pays off when the logic gets tangled: COD only above a certain order value, another rule per product category, plus a variable COD fee per zone. That's where a conditional-payments plugin or custom code saves hours and prevents lost orders from rules that fight each other.

At MPO Web Studio we build and maintain WooCommerce stores remotely, for clients nationwide. We can set up your zones, region-based COD and fees correctly, or show you on a demo how it would look before you pay anything. If you want a hand, message us on WhatsApp and we'll tell you honestly whether it's a 10-minute DIY or genuinely worth a proper fix.

Frequently asked questions

Can I accept COD everywhere except a few regions?+

Yes. It's easier with the snippet: put the BLOCKED regions in the array and invert the condition — if the customer's region is in the list, remove the cod gateway. With zones you do the reverse: put the exceptions in a separate zone with no COD-linked shipping method.

Which region codes does WooCommerce use?+

Short codes per country. In WooCommerce each state/region has a code you can find in the country's states file, or by inspecting the value in the region dropdown at checkout. Use exactly those codes in your allowed list, or the match will fail.

Does the filter read billing or shipping address?+

Whichever you pick. In the snippet, get_shipping_state() uses the shipping address and get_billing_state() the billing one. For COD the shipping address makes sense, since that's where the parcel goes. Choose based on which fields you request at checkout.

Do I need a plugin?+

Not for simple cases. The Shipping Zones method is fully native to WooCommerce, and the snippet only needs access to functions.php or a free snippets plugin. A dedicated conditional-payments plugin is only worth it when you combine rules (value + category + region).

Why doesn't COD show up at all, even though I set everything?+

Most often: the checkout cache wasn't purged, the customer's region doesn't exactly match a code in your list, or the state/region field is disabled in Settings. Purge the cache and test at checkout, changing the region to confirm the payment methods refresh.

Free guide

7 mistakes that drive clients away from your website

Leave your email and get the guide right here, instantly. No spam.

By submitting, you agree to the Privacy Policy.
MThe MPO teamWe reply personally

Want to see what your business's website could look like?

Message us on WhatsApp and we'll build you a free demo website with your business name on it. See it first, then decide — no strings attached.

Ask for a free demo websiteWe usually reply within a few minutes