Charging the right delivery price for Highlands, islands and Northern Ireland postcodes
Your courier charges more for the Highlands, the islands and Northern Ireland, but your checkout charges everyone the same. How to price UK postcodes properly in Magento 2.
Say the courier invoice arrives at the end of the month, and a dozen lines have a surcharge on them. A sofa to Inverness, two parcels to Kirkwall, one to Belfast, a box to St Mary's on the Isles of Scilly. Your checkout charged each of those customers the same £6.95 as someone in Leeds, so the difference came out of your margin.
Many UK carriers charge more for some postcode areas than for the mainland. The exact list depends on the carrier, and even the Scottish Highlands and Islands are drawn differently by different carriers, so check your own carrier's surcharge table. The obvious fix is to charge more for those postcodes at checkout. On Magento, that turns out to be awkward without help.
What Magento's table rates can do
Magento's built-in Table Rates method calculates a price from a CSV table of destinations and one condition: weight, order subtotal or number of items, each against destination1. You pick one condition per website, and only one set of table rate data is active at a time. The method appears as a single option at checkout.
The postcode column is where UK merchants get stuck. Adobe's documentation says it plainly: postcode ranges are not supported1. In the code, a row matches the full postcode exactly, or the part before a hyphen (for American ZIP+4 codes), or * for every postcode2. There is no "starts with". To charge extra for the IV postcode area you would need a row for every full postcode in it, or settle for charging the same price everywhere in the UK.
The other built-in methods do not help here either: Flat Rate is one price per order or per item, and Free Shipping is a threshold. None of them knows that IV1 is in the Highlands.
Matching UK postcodes the way carriers describe them
A UK postcode has a structure: area (IV), district (IV1), sector (IV1 1) and unit (IV1 1AA). Carriers write their surcharge zones in those terms, for example "IV1 to IV28, HS, KW, ZE". A rate table for UK delivery needs to understand the same terms, and it must not confuse IV1 with IV10, or B (Birmingham) with BA (Bath).
That is what we built into Shipping Table Rates. A rate row's postcode column takes a list of patterns: an area such as IV (which matches IV1 to IV63 but B does not match BA1), an outward code such as IV1 (not IV10), a sector, a full postcode, a district range such as IV1-IV28, a "starts with" pattern such as TR*, or a numeric range for other countries. There are also a few ready-made zones: zone:northern-ireland (BT), zone:channel-islands, zone:isle-of-man, zone:isles-of-scilly (TR21 to TR25) and zone:bfpo. Jersey, Guernsey and the Isle of Man have their own country codes in Magento, so those zones match the country codes as well as the postcode areas.
There is deliberately no ready-made "Highlands and Islands" zone. Carriers draw that area differently, so the module would be guessing. Copy the district list from your own carrier's surcharge table into the rows, for example HS, ZE, KW, IV1-IV28.
Several methods, and rows that pick the right price
Instead of a single method, you can create as many as you need, for example Standard, Express and Pallet, each with its own name, delivery time text, store views and customer groups. Each method has its own rate rows. A row has a destination, ranges of weight, subtotal and quantity (from included, to not included, so 0 to 2 kg and 2 to 10 kg do not overlap), and a price made of a base rate plus optional amounts per item, per weight unit and a percentage of the subtotal.
When several rows match, the most specific one wins: a full postcode beats a sector, a sector beats an outward code, then ranges, areas, "starts with" patterns, zones and *. So you can have one * row for mainland UK and a more expensive row for zone:northern-ireland without worrying about the order of the rows. If no row matches, the method is not offered.
Rates can be entered in the admin or imported from CSV. The import checks every line first and writes nothing if any line has an error, with a report per line, and a dry run option to test a file without importing it.
Sometimes the right answer is not a higher price but no offer at all. Your pallet service may not cross to the islands, or a next-day promise cannot be kept for Belfast. Restriction rules hide methods when their conditions are met, and they work on any carrier, including Magento's own Flat Rate and other modules' carriers. Conditions include the delivery address inside or outside countries and postcode patterns, weekdays and times, coupons, customer groups and Magento's cart price rule conditions such as weight or products in the basket. A rule can show a message in place of the hidden method, such as "Flat Rate does not deliver to Northern Ireland. Please choose Standard or Express Delivery."
Testing before customers do
The step that saves most of the trouble is testing. The rate simulator takes SKUs and quantities, a country and postcode, a store view, a customer group and an optional coupon, builds a temporary basket, and shows every method that checkout would offer, with the rate row used and how the price was worked out, and every method a restriction rule hid, with a link to the rule. The basket is deleted afterwards and nothing is ordered.

Run it for a handful of postcodes from your carrier's surcharge list before switching the new methods on. The carrier is switched off after installation, so you can do this before any customer sees it.
What it does not do
The module does not calculate volumetric weight, offer delivery date slots or show a shipping calculator on the product page. The weight unit is the store's own. Amounts are in each website's base currency. Checkout support is the Luma checkout, which Hyvä stores can use through the Luma checkout fallback; Hyvä Checkout has not been tested. The Hyvä cart page's shipping estimate is supported.
If you ship only to mainland Britain at one price, or your carrier does not charge surcharges, Magento's Flat Rate or Table Rates are enough and you do not need this. It is for stores whose carrier invoice keeps telling them otherwise.
The Magento 2 Shipping Table Rates page has the postcode patterns, the CSV format and a sample UK rate table.
Sources
- Adobe Commerce Admin documentation, "Table rate shipping", https://experienceleague.adobe.com/en/docs/commerce-admin/stores-sales/delivery/basic-methods/shipping-table-rate, checked 12 October 2026. ↩1 ↩2
- Magento Open Source 2.4.9 source code,
app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php(dest_zipcompared with the full postcode, the part before a hyphen, empty or*), checked 12 October 2026. ↩
From our shop