An India-headquartered cross-border courier company connecting India ↔ UAE ↔ UK was operating across three currencies, six partner carriers, and eight customs document formats — manually. We shipped a unified platform with multi-currency billing, automatic customs paperwork, and live carrier-API integration; on-time delivery hit 99.4% within four months.
Cross-border is harder than domestic by an order of magnitude. Three currencies means three rate cards. Six carriers means six API surfaces. Eight customs document formats means a wrong field on any one means the parcel sits at customs for three weeks. The client was running this on Excel and email and was ready to fold the international lane.
A platform with three layers: a customer-facing booking portal, an ops admin, and a carrier-integration layer that abstracts the six carriers behind a single internal API. The non-obvious decision was building the customs document engine as a configurable rules engine rather than per-lane templates.
Quote → book → pay → track → invoice. Quotes in customer's currency. Documents auto-generated from the booking form. Tracking aggregated from all carriers in their journey. Embedded support chat with WhatsApp + email continuity.
Single shipment board across all lanes and carriers. SLA-clock per leg. Customs-doc validator (catches 'no IEC for export' before the parcel leaves the warehouse). Reconciliation against carrier invoices. Multi-currency P&L reports.
Six adapters, one internal interface. Each adapter handles auth (OAuth / token / API key), rate-pull, booking, label generation, tracking, and proof-of-delivery in the carrier's native format and translates to our canonical model.
JSON-driven rules engine: per-lane (India→UK, India→UAE, UAE→UK, etc) it defines required documents, fields, validations, and currency. Generating commercial invoice + packing list + CN22 for an India-UK shipment is a single API call.
Postgres for source of truth (multi-currency money columns with currency code, never a float for cash), Redis for FX-rate cache (refreshed every 4 hours from a paid feed), Bull queue for carrier API calls and webhook ingestion.
We picked the stack for fit, performance under realistic load, and operational simplicity. Here is the breakdown:
Multi-currency money is non-trivial: we stored every monetary value as (amount_minor, currency_code) tuples — never as floats, never as a single 'amount' column. FX is applied at booking, never at invoice. The 9% customer dispute rate dropped to under 0.5% in two months because invoices matched quotes exactly.
Carrier adapter pattern: behind the internal API, each carrier has its own adapter class with the same six methods. Adding a seventh carrier (Singapore Post, planned) is a 5-day project, not a 5-month one.
Stripe for AED + GBP, Razorpay for INR: regulatory reality. Stripe doesn't support INR receiver-side; Razorpay doesn't support AED + GBP. Two PSPs, one unified payment-status surface in our app.
Customs paperwork that doesn't get the parcel stuck.
The hardest engineering problem on the platform. Customs paperwork is harsh: get the HSN code wrong on a commercial invoice and the parcel sits at customs for 3-21 days. Get the IEC missing and India customs rejects the export entirely. Get the CN22 weight wrong and Royal Mail returns the parcel to UK origin.
We talked to three customs brokers across the lanes, encoded their rules into a rules engine, and validated every booking against it before it could leave the originating warehouse.
Sample rules: India→UK air parcel under £270 declared value needs CN22 with HSN code; over £270 needs CN23; courier over UK£135 needs UK VAT collected at origin; India-export needs IEC + GSTIN + AD code. Each rule is data, not code.
Customs holds dropped from 11% (eyeballing the prior month) to under 0.4% in three months. That alone returned the platform's build cost.
We launched on the India-UAE lane only — single carrier (Aramex), single currency for invoicing initially (INR with FX-locked AED display). Got the platform proven on one lane before adding complexity.
Lane-by-lane rollout: India-UK in month two, UAE-UK in month four, multi-carrier per-lane in month six. Singapore lane is in design now. Each lane required its own customs SME conversation; that's the rate-limiter, not engineering.
“Cross-border was always our hardest lane and our most profitable. ITD's platform turned 'hardest' into 'tractable' — the customs engine alone has saved us from at least four customer churns I can name.”
VP Operations
Cross-Border Courier Company · Mumbai & Dubai
Pick one carrier per lane for the v1 cut, not one carrier total. We tried to launch with Aramex everywhere; the India-UK first-mile economics didn't work and we had to add Speedpost in week three. Lane-specific carrier choices are a v1 decision, not a v1.5 patch.
Cross-border platforms break in places domestic platforms never reach. Customs, currencies, carriers, lane-specific SLAs — talk to engineers who have built it before.
Get a Free Consultation