DHL Express live rates
This example shows how to integrate DHL Express live carrier rates into JsRates using the MyDHL API (DHL Express) Rating service.
It demonstrates how to:
- Authenticate with DHL Express using Basic Auth (
DHL_API_KEY/DHL_API_SECRET) - Read product dimensions from Shopify metafields via
enrichItemDetails - Build a DHL Express Rate request with shipper/receiver, account number, and packages
- Fetch available DHL Express products/services + prices + ETA
- Convert DHL Express products into Shopify shipping rates for checkout
This sample is designed for stores that want real-time DHL Express pricing instead of flat-rate or rule-based shipping.
Prerequisites
1) Required DHL Express credentials (JsRates Secrets)
Create the following secrets in Settings → Secrets (see more information here):
DHL_API_KEYDHL_API_SECRETDHL_ACCOUNT_NUMBER(your DHL Express shipper account number)
DHL Express (MyDHL API) uses pre-emptive Basic Authentication (Base64 of
API_KEY:API_SECRET).
2) Product dimensions metafields
This sample reads item dimensions from the custom variant metafield namespace (first 10 values). Make sure to use the correct namespace defined in your store.
Example keys per item (as strings or numbers):
lengthwidthheight
Note: DHL Express rate requests in this example use metric units:
- weight in KG (converted from
DATA.items[*].grams)- dimensions in CM (read from metafields)
DHL Express API Reference
DHL Express live rates in this example are fetched using the MyDHL API (DHL Express) Rating endpoint:
- Base URLs (Test + Production) are listed in DHL’s MyDHL API overview.
- Authentication is BasicAuth as noted above.
If you need to support additional DHL request fields (currency selection, value-added services, customs items, etc.), refer to the MyDHL API documentation and update the request payload accordingly.
Sample code
Copy the following code and paste it to a blank calculateShippingRates.js module and save it.
import { enrichItemDetails } from "./modules.js"; // Enriches item data with metafields like dimensions
// 🔐 DHL Express (MyDHL API) uses pre-emptive Basic Auth: base64(API_KEY:API_SECRET)
function getDHLAuthHeader(env) {
if (!env.DHL_API_KEY || !env.DHL_API_SECRET) return "";
return "Basic " + btoa(`${env.DHL_API_KEY}:${env.DHL_API_SECRET}`);
}
// 🚚 Main shipping rate calculator
export async function calculateShippingRates(DATA, env) {
try {
// 1) Enrich item dimensions via metafields
DATA = await enrichItemDetails(DATA, [
{
namespace: "custom",
size: 10,
},
]);
// 2) Choose URL
// Test URL: https://express.api.dhl.com/mydhlapi/test/rates
// Prod URL: https://express.api.dhl.com/mydhlapi/rates
const endpoint = "https://express.api.dhl.com/mydhlapi/rates";
const origin = DATA.origin;
const destination = DATA.destination;
// 3) Build DHL packages array (weight in KG, dimensions in CM)
const packages = DATA.items.map((item) => {
const dims = item.metafields?.custom || {};
return {
weight: Number(((item?.grams || 0) / 1000).toFixed(3)), // g -> kg
dimensions: {
length: Number(dims.length || 10),
width: Number(dims.width || 10),
height: Number(dims.height || 10),
},
// Optional, but commonly used in examples:
// typeCode: "3BX"
};
});
// 4) Construct DHL Rate request payload (MyDHL API /rates)
// NOTE: Leaving productCode empty asks DHL to return all applicable products/services.
const payload = {
customerDetails: {
shipperDetails: {
postalCode: origin.postal_code,
cityName: origin.city,
countryCode: origin.country_code || origin.country,
addressLine1: origin.address1 || "",
},
receiverDetails: {
postalCode: destination.postal_code,
cityName: destination.city,
countryCode: destination.country_code || destination.country,
addressLine1: destination.address1 || "",
},
},
accounts: [
{
typeCode: "shipper",
number: env.DHL_ACCOUNT_NUMBER,
},
],
productCode: "", // Return all available DHL Express products
plannedShippingDateAndTime: new Date().toISOString(),
unitOfMeasurement: "metric",
isCustomsDeclarable: (destination.country_code || destination.country) !== (origin.country_code || origin.country),
packages,
};
// 5) Fetch DHL rates
const response = await fetch(endpoint, {
method: "POST",
headers: {
Authorization: getDHLAuthHeader(env),
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
const data = await response.json();
// 6) Transform DHL response to Shopify carrier service format
const products = Array.isArray(data?.products) ? data.products : [];
const rates = products
.map((product) => {
const total = Array.isArray(product?.totalPrice) ? product.totalPrice[0] : null;
const price = total?.price;
// Some responses provide estimated delivery date/time under deliveryCapabilities
const eta =
product?.deliveryCapabilities?.estimatedDeliveryDateAndTime ||
product?.deliveryCapabilities?.estimatedDeliveryDate ||
"";
if (price == null) return null;
return {
service_name: product.productName || product.productCode || "DHL Express",
service_code: product.productCode || product.localProductCode || "DHL",
total_price: (Number(price) * 100).toFixed(0), // dollars -> cents as string
currency: total?.priceCurrency || DATA.currency || "USD",
min_delivery_date: eta || "",
max_delivery_date: eta || "",
};
})
.filter(Boolean);
return { rates };
} catch (error) {
console.error("DHL Rate Error:", error?.message || error);
return { rates: [] };
}
}
Notes
- Environment: DHL provides separate
/testand production base URLs for MyDHL API. - Units: This example sends
unitOfMeasurement: "metric", weights in KG, and dimensions in CM. - Services returned: DHL returns only the products/services available for the specific origin/destination, shipment date, and package characteristics. (Use the returned
products[*].productCodeas yourservice_code.) - Customs:
isCustomsDeclarableshould be true for international shipments. For real international rating, you may need to include additional customs data depending on your DHL account configuration and shipment type.
Payload reference (quick view)
The request payload fields used above match common MyDHL API Rating examples (shipper/receiver details, accounts, planned shipping date/time, unit of measurement, packages).
