Documentation You are here: start » v » 2.0 » shipping » custom_code » postmen

Custom Shipping Code Postmen Integration

The following page details integrating Postmen into your Foxy store for fetching shipping rates from any of their supported providers, using the Custom Shipping Code functionality available for Foxy stores.

Requirements

  • A Foxy store on version 2.0
  • At least one category configured with a delivery type of “Shipped using live shipping rates”
  • An active Postmen account

Installation

Below is the custom shipping code you'll use to connect to Postmen, and below that is the steps to install it on your store.

// Set to the API key of your Postmen account
let api_key = 'YOUR-POSTMEN-API-KEY';
// Set to false to use test shipper accounts
let is_production = true;
// Shipper accounts
let shipper_accounts = [
    { 'id': 'SHIPPER-ACCOUNT-ID-1' },
    { 'id': 'SHIPPER-ACCOUNT-ID-2' }
];
// Weight units for the store ('lb' or 'kg')
let weight_unit = 'lb';
// Length units for the store ('in' or 'cm')
let length_unit = 'in';
// Parcel dimensions
let parcel_width = 20,
    parcel_height = 10,
    parcel_depth = 10;
 
 
 
const shipment = cart['_embedded']['fx:shipment'];
 
let payload = {
    'async': false,
    'shipper_accounts': shipper_accounts,
    'shipment': {
        'parcels': [
            {
                'box_type': 'custom',
                'weight': {
                    'value': shipment['total_weight'],
                    'unit': weight_unit
                },
                'dimension': {
                    'width': parcel_width,
                    'height': parcel_height,
                    'depth': parcel_depth,
                    'unit': length_unit
                },
                'items': [
                    // Populated below
                ]
            }
        ],
        'ship_from': {
            'state': shipment['origin_region'],
            'postal_code': shipment['origin_postal_code'],
            'country': country_to_3(shipment['origin_country']),
        },
        'ship_to': {
            // Populated below
            'country': country_to_3(shipment['country']),
            'type': shipment['is_residential'] ? 'residential' : 'business'
        }
    },
    'is_document': false
};
 
// Ship to address
if (shipment['first_name']) {
    payload.shipment.ship_to['contact_name'] = shipment['first_name'] + " " + shipment['last_name'];
}
if (shipment['address1']) {
    payload.shipment.ship_to['street1'] = shipment['address1'];
}
if (shipment['city']) {
    payload.shipment.ship_to['city'] = shipment['city'];
}
if (shipment['region']) {
    payload.shipment.ship_to['state'] = shipment['region'];
}
if (shipment['postal_code']) {
    payload.shipment.ship_to['postal_code'] = shipment['postal_code'];
}
 
// Items
for (let p in cart['_embedded']['fx:items']) {
    let item = cart['_embedded']['fx:items'][p];
 
    let item_details = {
        'description': item.name,
        'quantity': item.quantity,
        'price': {
            'amount': item.price,
            'currency': cart.currency_code
        },
        'weight': {
            'value': item.weight,
            'unit': weight_unit
        }
    }
 
    if (item.sku) {
        item_details['sku'] = item.code
    }
 
    payload.shipment.parcels[0].items.push(item_details);
}
 
try {
    const endpoint = is_production ? 'https://production-api.postmen.com/v3' : 'https://sandbox-api.postmen.com/v3'
    const response = await fetch(endpoint + '/rates', {
        method: 'POST', 
        body: JSON.stringify(payload),
        headers: {
            "postmen-api-key": api_key,
            "Content-Type": "application/json"
        }
    });
    const data = await response.json();
 
    if (data.meta.code != 200) {
        console.log(data.meta)
    }
 
    for (let r = 0; r < data.data.rates.length; r++) {
        const rate = data.data.rates[r];
 
        if (rate.service_name) {
            rates.add(10000+r, rate.total_charge.amount, '', rate.service_name);
        } else if (rate.error_message) {
            console.log(rate.error_message);
        }
    }
} catch(err) {
  console.log(err);
}
 
function country_to_3(country) {
    const iso3166_3 = {
        AF: 'AFG', AX: 'ALA', AL: 'ALB', DZ: 'DZA', AS: 'ASM', AD: 'AND', AO: 'AGO', AI: 'AIA', AQ: 'ATA', AG: 'ATG', AR: 'ARG', AM: 'ARM', AW: 'ABW', AU: 'AUS', AT: 'AUT', AZ: 'AZE', BS: 'BHS', BH: 'BHR', BD: 'BGD', BB: 'BRB', BY: 'BLR', BE: 'BEL', BZ: 'BLZ', BJ: 'BEN', BM: 'BMU', BT: 'BTN', BO: 'BOL', BA: 'BIH', BW: 'BWA', BV: 'BVT', BR: 'BRA', VG: 'VGB', IO: 'IOT', BN: 'BRN', BG: 'BGR', BF: 'BFA', BI: 'BDI', KH: 'KHM', CM: 'CMR', CA: 'CAN', CV: 'CPV', KY: 'CYM', CF: 'CAF', TD: 'TCD', CL: 'CHL', CN: 'CHN', HK: 'HKG', MO: 'MAC', CX: 'CXR', CC: 'CCK', CO: 'COL', KM: 'COM', CG: 'COG', CD: 'COD', CK: 'COK', CR: 'CRI', CI: 'CIV', HR: 'HRV', CU: 'CUB', CY: 'CYP', CZ: 'CZE', DK: 'DNK', DJ: 'DJI', DM: 'DMA', DO: 'DOM', EC: 'ECU', EG: 'EGY', SV: 'SLV', GQ: 'GNQ', ER: 'ERI', EE: 'EST', ET: 'ETH', FK: 'FLK', FO: 'FRO', FJ: 'FJI', FI: 'FIN', FR: 'FRA', GF: 'GUF', PF: 'PYF', TF: 'ATF', GA: 'GAB', GM: 'GMB', GE: 'GEO', DE: 'DEU', GH: 'GHA', GI: 'GIB', GR: 'GRC', GL: 'GRL', GD: 'GRD', GP: 'GLP', GU: 'GUM', GT: 'GTM', GG: 'GGY', GN: 'GIN', GW: 'GNB', GY: 'GUY', HT: 'HTI', HM: 'HMD', VA: 'VAT', HN: 'HND', HU: 'HUN', IS: 'ISL', IN: 'IND', ID: 'IDN', IR: 'IRN', IQ: 'IRQ', IE: 'IRL', IM: 'IMN', IL: 'ISR', IT: 'ITA', JM: 'JAM', JP: 'JPN', JE: 'JEY', JO: 'JOR', KZ: 'KAZ', KE: 'KEN', KI: 'KIR', KP: 'PRK', KR: 'KOR', KW: 'KWT', KG: 'KGZ', LA: 'LAO', LV: 'LVA', LB: 'LBN', LS: 'LSO', LR: 'LBR', LY: 'LBY', LI: 'LIE', LT: 'LTU', LU: 'LUX', MK: 'MKD', MG: 'MDG', MW: 'MWI', MY: 'MYS', MV: 'MDV', ML: 'MLI', MT: 'MLT', MH: 'MHL', MQ: 'MTQ', MR: 'MRT', MU: 'MUS', YT: 'MYT', MX: 'MEX', FM: 'FSM', MD: 'MDA', MC: 'MCO', MN: 'MNG', ME: 'MNE', MS: 'MSR', MA: 'MAR', MZ: 'MOZ', MM: 'MMR', NA: 'NAM', NR: 'NRU', NP: 'NPL', NL: 'NLD', AN: 'ANT', NC: 'NCL', NZ: 'NZL', NI: 'NIC', NE: 'NER', NG: 'NGA', NU: 'NIU', NF: 'NFK', MP: 'MNP', NO: 'NOR', OM: 'OMN', PK: 'PAK', PW: 'PLW', PS: 'PSE', PA: 'PAN', PG: 'PNG', PY: 'PRY', PE: 'PER', PH: 'PHL', PN: 'PCN', PL: 'POL', PT: 'PRT', PR: 'PRI', QA: 'QAT', RE: 'REU', RO: 'ROU', RU: 'RUS', RW: 'RWA', BL: 'BLM', SH: 'SHN', KN: 'KNA', LC: 'LCA', MF: 'MAF', PM: 'SPM', VC: 'VCT', WS: 'WSM', SM: 'SMR', ST: 'STP', SA: 'SAU', SN: 'SEN', RS: 'SRB', SC: 'SYC', SL: 'SLE', SG: 'SGP', SK: 'SVK', SI: 'SVN', SB: 'SLB', SO: 'SOM', ZA: 'ZAF', GS: 'SGS', SS: 'SSD', ES: 'ESP', LK: 'LKA', SD: 'SDN', SR: 'SUR', SJ: 'SJM', SZ: 'SWZ', SE: 'SWE', CH: 'CHE', SY: 'SYR', TW: 'TWN', TJ: 'TJK', TZ: 'TZA', TH: 'THA', TL: 'TLS', TG: 'TGO', TK: 'TKL', TO: 'TON', TT: 'TTO', TN: 'TUN', TR: 'TUR', TM: 'TKM', TC: 'TCA', TV: 'TUV', UG: 'UGA', UA: 'UKR', AE: 'ARE', GB: 'GBR', US: 'USA', UM: 'UMI', UY: 'URY', UZ: 'UZB', VU: 'VUT', VE: 'VEN', VN: 'VNM', VI: 'VIR', WF: 'WLF', EH: 'ESH', YE: 'YEM', ZM: 'ZMB', ZW: 'ZWE', XK: 'XKX'
    };
 
    return iso3166_3[country];
}

Steps

  1. Log in to your store's Foxy administration
  2. Head to the “Shipping” page
  3. Scroll down until you see the “Custom Shipping Code” option, and check the option for “use custom code”.
  4. In the code editor that appears, copy and paste the code shown above. Don't save it just yet.
  5. In a new tab, log in to your Postmen account
  6. Go to API keys section
  7. Within the “Tokens” section, click the “Add new api key” button and complete the form
  8. Copy the API key generated to your clipboard from either the Production or Testing tabs (depending which type you created), and in the code you pasted into your Foxy admin above on this line:
    let api_key = 'YOUR-POSTMEN-API-KEY';


    Replace the YOUR-POSTMEN-API-KEY text with your copied API key

  9. Update this line to false instead of true if you are using a Testing API key:
    let is_production = true;
  10. Update the shipper_accounts array to list out all of the shipper accounts you want to request rates from. Shipper accounts are created within Postmen in the Shipper Accounts section. Ensure you get from Production or Testing to match your API key type.
  11. Configure the remainder of the configuration options for weight/length units and package size
  12. Click the “Update” button to save your new settings
  13. Wait ~10-15 seconds and refresh the page (the custom shipping code feature is a separate system, so takes a moment to initialize, you should see your custom code again after refreshing if it was successful)
  14. You're done! Now you can test it out!

To test our the new rates after saving, you can simply add a product to your cart that belongs to a live rate shippable category. On the cart or checkout, after entering a shipping address, you should see your rates returning from your Postmen account.

Taking It Further

This integration is fairly basic - it just returns all rates from Postmen, and passes it some default values. You can review the Postmen documentation on rate requests with their API here to customise the integration above further as needed.

You can also customise the rates returned, to only output specific rates or work with them further using our custom shipping code API documented here.

Site Tools