I found the problem with the international shipping, have corrected it and, in addition, upgraded the logic for shipping selection in the module to remove some unnecessary options at the checkout.

it turns out that the royal mail module error was a duplicated array name in the catalog/model/shipping/royal_mail.php file.

$quote_data['airsure'] = array(
    	'id'           => 'royal_mail.surface',

should have read:

    $quote_data['surface'] = array(
    	'id'           => 'royal_mail.surface',

(I’m told that this has already been fixed for the 1.4.9.5 release.)_

Before the change, this meant the surface shipping details were overwriting the details for airsure, but when selected at the checkout, the .surface in the id meant it was still looking for $quote_data[‘surface’] to grab the shipping details – which doesn’t exist.

Custom royal_mail module

While I was in and fiddling with code, there were some other changes that I wanted to make, so I:

  • Excluded international delivery options for domestic delivery.

    • Includes Channel Islands in domestic delivery rates.
  • Excluded domestic delivery options for international delivery.

  • Updated service costs to include up to 2kg for Airmail.

  • Excluded services if the checkout value exceeds the insurance rate.

  • Updated compensation costs for Airsure & International Signed.

  • Added shipping times for each service.

  • Consolidated the Special Delivery service into one option - service choice is calculated from cart value.

And to make the shipping choice a bit simpler to the customer, I’ve added some logic to reduce the number of options at the checkout by removing some of the slower delivery choices where they are not cost effective.

  • Ignore Surface Mail quote if more expensive than Airmail.

  • Ignore Standard Parcels quote if more expensive than First Class.

  • Ignore International Signed quote if an Airsure quote exists.

This full module code available at github (github.com/DefProc/opencart-royal_mail-custom) either with or without the additional logic.