MERSO IT

Automation · Logistics

ViettelPost vs GHN vs GHTK vs J&T: carrier APIs for automation

MERSO IT Insights · Updated July 2026 · 8 min read

Four Vietnamese carrier APIs compared behind a single carrier-abstraction layer

Every Vietnamese seller eventually asks: which carrier should my automation integrate with? The honest answer is that the question is slightly wrong. All four majors — ViettelPost, GHN (Giao Hàng Nhanh), GHTK (Giao Hàng Tiết Kiệm) and J&T Express — are integrable, all have real strengths, and all will disappoint you somewhere. The durable decision is not which carrier to marry but how to build so that switching, or splitting traffic between them, is a configuration change rather than a rewrite.

What actually matters for automation builders

Marketing pages compare price per kilogram. Automation builders should compare different things: how good the API contract is, whether webhooks actually arrive, how COD money comes back, and what happens on the edge cases — rural addresses and returns. Ratings below are qualitative, based on integration experience; every carrier evolves, so verify against current documentation before committing.

DimensionViettelPostGHNGHTKJ&T Express
API style & docs qualityFunctional but dated; docs partly Vietnamese-onlyCleanest developer experience of the fourWorkable; conventions take getting used toImproving; partner-onboarding heavy
Webhook reliabilityGood, with occasional gaps — reconcileGood; still reconcileAdequate; expect duplicatesVariable by region; reconcile aggressively
COD remittance cadenceRegular batches, own reference formatRegular, comparatively clean statementsFrequent; strong COD heritageRegular; format differs again
Pickup reliabilityStrong nationwide networkStrong in major citiesGood; shop-oriented modelGood urban, variable rural
Rural coverageBest of the four (Viettel infrastructure)Good, urban-strongestGoodWide but uneven
Returns flowSupported; track statuses closelySupported, reasonably clearSupported; process-heavySupported; verify per region

Read the table as a map of failure modes, not a scoreboard. GHN's developer experience makes it a pleasant first integration; ViettelPost's rural reach makes it hard to drop entirely if your customers live outside the big cities (and its pickup automation is covered step-by-step in our ViettelPost guide); GHTK's COD-first heritage suits shops whose buyers overwhelmingly pay on delivery; J&T's network keeps expanding but demands the most defensive engineering.

The carrier-abstraction layer

Whatever you pick first, put a boundary between your business logic and the carrier:

  1. One internal shipment model. Your order service creates a Shipment with a canonical address, parcel dimensions, COD amount and service class (economy/express). It never mentions a carrier.
  2. One adapter per carrier. Each adapter translates the internal model to that carrier's API — its field names, its service codes, its authentication — and translates carrier statuses back to your canonical status set (created, picked up, in transit, out for delivery, delivered, failed, returned).
  3. A routing policy. A rule decides which carrier gets which shipment: by destination province, by weight, by COD amount, or by live rate shopping — query two or three adapters for a quote and take the best. The policy is configuration, so "switch carriers" or "send rural COD to ViettelPost, urban express to GHN" is an afternoon, not a project.
Why bother before you need itThe abstraction costs perhaps 15% extra effort on the first integration and saves 80% on the second. More importantly, it converts carrier risk — price hikes, service degradation in your region, an account dispute — from an existential problem into a routing-rule edit. Sellers who integrated one carrier directly into their order code always regret it in year two.

The two traps that bite every multi-carrier build

1. Four carriers, four address-code systems

Each carrier maintains its own numeric codes for provinces, districts and wards, and they do not agree with each other. If you store carrier-specific codes on your customer records, you are locked in at the data layer. Build one canonical address model — your own normalized representation of province/district/ward plus street text — and let each adapter map canonical → carrier codes at booking time, against code tables refreshed from that carrier's API. When Vietnam reorganizes administrative boundaries (it does), you update the mappings in one place.

2. Webhook retries need idempotent handlers

Every carrier retries webhooks on timeout, some retry enthusiastically, and out-of-order delivery is normal. A handler that naively appends events will send customers duplicate "delivered!" messages and corrupt your COD expectations. The pattern: derive a stable event key per (shipment, status), upsert rather than insert, compute customer-facing state from the full status history, and make notification sending exactly-once per state transition. The same discipline pays off downstream when you match COD remittances to orders — see our COD reconciliation article for that half of the money flow.

Recommendation

Start with the carrier whose network fits your customer geography — for most sellers with significant rural COD volume that means ViettelPost, for urban-centric shops GHN is the gentler first integration. Build the abstraction layer from day one even with a single carrier behind it. Add a second carrier when you have volume to split or a failure mode to escape, and let rate shopping pay for the work. This is exactly the fulfilment layer of the end-to-end automation stack — and the layer where defensive engineering most directly translates into customers who actually receive their parcels.

Choosing a carrier — or escaping one?

MERSO IT builds carrier-abstraction layers and multi-carrier routing — and for suitable projects we demonstrate the core workflow before any payment.

Talk to Mersoid, our AI consultant