Store Builder

Connecting Giao Hàng Nhanh (GHN)

Where to find your Token and Shop ID, how the three sections of the GHN card work, and the GHN-specific quirks — sandbox, webhook, addresses since the 2025 merger.

This page is about Giao Hàng Nhanh (GHN) specifically: getting an account, connecting it, and the things only GHN does. The mechanics every carrier shares — pickup address, the fallback when a carrier does not answer in time, pairing a carrier with a delivery method, what a waybill status does to the order — are covered in The Shipping app.

What connecting GHN is for

Once GHN is connected, the shop gains four things: a shopper sees GHN's own real fee at checkout instead of a guessed flat rate, you book a waybill straight from an order (Book a carrier shipment) with no separate GHN login, you print the waybill label right there (Print label), and the order's status keeps itself current every time GHN reports an event over its webhook — no manual lookup, no typing a status by hand.

Getting a GHN account

GHN runs two genuinely separate environments, each with its own account:

Environment Portal What it is for
Sandbox (testing) 5sao.ghn.dev Test the connection, test booking a waybill — no cost, no real pickup
Live khachhang.ghn.vn Real waybills, a real courier actually comes to collect

The Token and Shop ID for the two environments are two different pairs — a sandbox token does not work against the live environment, and vice versa. The API token field on the GHN card spells out where to get it:

"GHN portal → Chủ cửa hàng → Xem, to find your API token."

And the Shop ID field:

"GHN portal → Quản lý cửa hàng, to find your shop ID."

GHN's own dashboard is shown in Vietnamese; the card quotes its labels exactly as they appear there rather than translating them — translating them would send you looking for a menu item that does not exist under that name.

It is worth also filling in a shop address on that GHN account — the address GHN keeps from when you signed up. That is a separate thing from the pickup address you fill in on Store Builder's own GHN card (see The Shipping app §Pickup address): Store Builder calls GHN's API with the Token and Shop ID and never reads an address back off GHN's own account, so the two addresses can end up different without either one being wrong.

Connecting it in the Shipping app

Manage → Apps → Built in → Shipping, open the Giao Hàng Nhanh (GHN) card. The card is split into three sections: Connection, Pickup address, Webhook.

Test connection tries exactly the values you have typed on the card, even before you press Save — pressing it saves nothing. If the API token field is left blank it uses the token already saved. That lets you check the Token + Shop ID pair first and save afterwards. If Enable this carrier is on, Save only succeeds once the API token, Shop ID, Pickup province and Pickup ward are all present — if one is missing, nothing is saved. So the pickup address comes after the check. The order:

  1. Turn on Sandbox / testing mode if you are using a sandbox token — the switch itself says "Uses the carrier's test environment — nothing here books a real pickup."

  2. Paste the API token and Shop ID matching whichever environment you just chose. The token field only ever shows •••• saved once it has been saved — it does not read back; leaving it blank on save keeps whatever token was already there.

  3. Press Test connection. The card asks GHN using the Token and Shop ID you just typed and reports back immediately. A wrong token, or a token belonging to the other environment than the Sandbox switch is currently set to, reports:

    "The token or shop code is not correct — check the credentials above and try again."

    A correct token with a Shop ID that is not on that token's account reports:

    "This Shop ID does not belong to this account — check the Shop ID on the GHN portal."

    Both also raise a toast titled "Could not connect"; success reports "Connected".

  4. Fill in Pickup address and Default parcel weight — these work the same way as for any other carrier, see The Shipping app for each field.

  5. Turn Enable this carrier on, then press Save.

The Testing label next to the Connected badge reflects the saved state, not the switch you just moved — it only appears after you Save with sandbox turned on. The Open the merchant portal link, on the other hand, is always shown (it does not need sandbox on first) and its target updates the moment you flip the switch, even before you save: 5sao.ghn.dev while sandbox is on, khachhang.ghn.vn while it is off. Sign up for a test account is the one link that is actually gated on sandbox — it only shows while the switch is on. GHN has no dedicated sandbox signup page, so this link also opens 5sao.ghn.dev; you create the test account right there.

Webhook

The Webhook section on the GHN card spells out how to wire this particular carrier's callback:

"Send this URL to GHN support so they can configure the webhook for your shop — if your GHN dashboard has a webhook settings field, you can paste it there instead."

In other words, GHN has no confirmed self-service webhook screen that every account is guaranteed to have — the reliable route is pressing Show webhook URL (only a role with permission to edit store settings can press it) and sending that URL to GHN support. If your own GHN account happens to have a webhook field in its admin pages, pasting it there works too. Regenerate webhook URL issues a new one and invalidates the old one immediately — tell GHN about the new URL right after you press it.

Charging the GHN fee on a delivery method

Go to Settings → Delivery → Delivery options, open a method, switch Fee source from Flat / by zone to A connected carrier, choose Giao Hàng Nhanh (GHN), then pick a Service — leave it at Carrier's default service, or choose Light goods (E-commerce) directly, the only service GHN offers on this platform today.

From then on, the shopper sees GHN's own real fee as soon as they fill in their address at checkout, instead of an estimate corrected afterward. Three situations still fall back to that method's own flat/zone fee:

  • GHN does not answer within 3 seconds.
  • GHN answers with an error.
  • GHN's system cannot resolve the shopper's ward to its own address code.

A GHN quote of exactly 0 is treated as meaningless and discarded — that does not mean the final fee itself can never be zero. If you set that method's own flat fee (the Fee field) to 0, a fallback still charges exactly 0 — the method dialog warns you when it sees this:

"This method's flat fee is 0. If the carrier cannot quote a fee, the order ships free."

Set that flat/zone fee to whatever you actually want to charge when GHN cannot answer in time; it is the real price for those moments, not a placeholder.

Free shipping above a threshold always wins regardless — once an order has already reached that amount, GHN is never asked for a price at all. And the first time a ward is ever quoted, the store has to look up GHN's own code for it first; if that lookup does not finish inside the 3-second budget, that one quote also falls back to the flat fee. Every later quote for the same ward reuses the code already resolved, so it almost always gets GHN's real price.

Addresses since the 2025 merger

GHN prices by the new ward names from the 2025 administrative merger — the same province/ward list the storefront's own checkout form uses, so most addresses need nothing extra from you. But there are two kinds of address GHN refuses, and neither one is the shop's fault:

A handful of wards GHN does not recognise yet. As of October 2026, these three are on the platform but not yet in GHN's own system:

  • Xã Đak Rong (Gia Lai)
  • Phường Kỳ Lừa (Lạng Sơn)
  • Xã Vụ Bổn (Đắk Lắk)

An order shipping to one of these three fails to book with GHN — there is currently no way to create a GHN waybill for these wards. The error is always in the language you administer the store in and names the ward and province of the order:

"{carrier} does not support the ward {ward}, {province} yet."

({carrier} is the carrier's name on the card; {ward} and {province} are replaced with the order's real address.) If the delivery address cannot be used and no particular ward can be named, the sentence is "{carrier} could not use this delivery address — check the order's ward." When the problem is the pickup address instead, it is "{carrier} could not use the pickup address — check the pickup ward in Apps → Shipping."

GHN can refuse a specific house number inside a ward it otherwise recognises fine. Measured on GHN's sandbox environment, in Phường Hải Châu, Đà Nẵng: GHN refuses "25 Bạch Đằng", "1 Bạch Đằng", "100 Bạch Đằng" but accepts "12 Bạch Đằng", "30 Bạch Đằng" — same ward, both times. This is how GHN's own address matching behaves, not something the shop controls; whether it also happens on the live environment is not confirmed. When it happens, the booking dialog reports:

"The carrier refused the request: ghn: phường/xã người nhận không tồn tại trong hệ thống"

Here only the "The carrier refused the request:" wrapper is Store Builder's own English text — everything after it, including the ghn: prefix, is GHN's own wording, verbatim, which is why this one sentence mixes English and Vietnamese. When you see it: check that the street name genuinely belongs to the ward selected on the order, try rewording the street name, and book again; if it still fails, contact GHN support. Do not drop the house number from the address — the courier still needs it to find the door.

Booking, printing and cancelling a GHN waybill from an order

Book a carrier shipment only appears on an order once GHN (or another carrier) is both connected and switched on — having the Token/Shop ID saved is not enough by itself, Enable this carrier also has to be on. Open the order and press Book a carrier shipment to open the dialog: its Carrier field is preselected to whichever carrier connected first, so it already reads Giao Hàng Nhanh (GHN) if GHN is the only (or first) one connected. Choose a Service (or leave it default) and press Book shipment — the waybill goes straight to GHN, with no review step in between. The weight it uses is the sum of every product's weight on the order (see The Shipping app for what happens when nothing on the order carries a weight); cash on delivery sent to GHN equals exactly what is still owed on the order.

Once booked, the shipment row shows two icon-only buttons side by side (no visible text, a tooltip on hover): Print label (a printer icon) opens GHN's own label straight away — a browser that blocks the pop-up reports "Your browser blocked the label window. Allow pop-ups for this site and try again." This button stays available on any waybill that is not Cancelled or Returned.

Cancel shipment (a cancel icon) calls GHN's own cancel endpoint directly — available on every status except Delivered and Cancelled; a waybill already Delivered loses this button entirely, because GHN considers the parcel done and will not reverse it.

The tracking link on a GHN waybill always points at donhang.ghn.vn, even for one booked in sandbox mode. Opening that link for a sandbox waybill can report "not found", because the live tracking site knows nothing about sandbox waybills — that is a known limit, not a bug in your order.

Troubleshooting

You see Why What to do
"The token or shop code is not correct…" on Test connection The Token is wrong, or it belongs to the other environment than the Sandbox switch is currently set to Paste the correct Token for whichever environment (sandbox or live) is selected
"This Shop ID does not belong to this account…" on Test connection The Token is right, but the Shop ID is not on that token's account (or belongs to the other environment) Check the Shop ID under GHN Khách hàng → Quản lý cửa hàng, paste the correct one, and test again
"{carrier} can't be disconnected yet. Shipments still in transit: N…" on Disconnect GHN still has waybills that are not delivered, cancelled or returned Switch Enable this carrier off instead of disconnecting; disconnect once those waybills are done
"…phường/xã người nhận không tồn tại trong hệ thống" when booking GHN refused this exact house number, even though the ward itself is valid Check the street belongs to the chosen ward, or reword the street name, and book again — do not drop the house number
"… does not support the ward …" That ward is not yet in GHN's own system (the three wards above) A GHN waybill cannot be booked for this ward yet; record the shipment manually instead
Checkout shows GHN's real fee, but the flat fee can still appear on the very first order to a new ward The store had not finished resolving that ward's GHN code within the 3-second budget Expected — later orders to the same ward will get GHN's real price
The tracking link reports "not found" The waybill was booked in sandbox mode; the tracking link always points at the live environment Working as designed; track a sandbox waybill from GHN's own sandbox site instead
The Print label window does not open The browser blocked the pop-up Allow pop-ups for this site and press it again

Updated 07/10/2026