Viettel Post Shipping
This guide connects Odoo to Viettel Post's partner API. It assumes Vietnam Delivery Connectors
is installed, which happens automatically with this app.
Installation
- Go to Apps, remove the default Apps filter, search for Viettel Post Shipping and click
Install.
Getting your credentials
Viettel Post issues partner accounts through its sales team rather than through self-service.
- Contact Viettel Post on 0862 235 888 or at b2b@viettelpost.com.vn and ask for API integration.
- They create an account on the Partner system and give you a username - usually a phone number -
and a password. If you already have a Viettel Post account, ask them to sync it to the Partner
system instead of creating a second one.
Configuration
- Go to Inventory > Configuration > Delivery Methods and create a method with Provider set to
Viettel Post.
- On the Vietnam Shipping tab, fill in Viettel Post Username and Password.
- Leave Test Environment on to talk to partnerdev.viettelpost.vn.
- Click Test the connection. This logs in, which is the only call that actually proves the
credentials.
There is no token to paste and none to rotate. Viettel Post authenticates with a session token that
expires; Odoo fetches it when needed, keeps it until shortly before it lapses and renews it without
anyone noticing. If Viettel Post returns an expiry Odoo cannot read, a conservative lifetime is
assumed rather than treating the token as permanent.
The username is the phone number on the account, not the email you sign in to their website
with. An email is accepted by the login form and rejected by the API, with the same "Username or
password is not valid" as a wrong password - so if the credentials look right and still fail, try
the phone number.
A refused sign-in is not retried for five minutes. Every call signs in when there is no session, so
a wrong password would otherwise mean one sign-in attempt per quote: Viettel Post answers that with
"too many attempts, try again after 1 minute" and can lock the account outright, which is a worse
problem than the wrong password. During those five minutes calls fail immediately, naming the
reason. Saving the username or password clears it at once.
If they cannot price your routes
A quote can come back as "Viettel Post returned no price for this route". Two different things look
identical from outside: they genuinely do not serve the route, or your contract has no service and
price list covering it. Their own answer is an empty list of services either way - and on the
non-conversational endpoint, "Price does not apply to this itinerary". A brand-new sandbox account
has no price list at all, so expect this until their sales team attaches one.
Nothing is ever quoted at zero. A service Viettel Post prices at nothing is treated as no quote
rather than as free shipping, because the alternative is offering a customer a delivery you are not
being paid for.
Options worth setting
- Pickup Warehouse ID - the warehouse registered on your Viettel Post account that parcels are
collected from. Test the connection lists the ones you have. Set it: Viettel Post prices from
the old district numbers, and a warehouse addressed with a ward created on 01/07/2025 has no place
in that catalogue at all, so without it your own address may be unpriceable even when the
customer's is fine.
- Let Viettel Post Read the Address - on by default, and worth leaving on. Viettel Post runs the
written Vietnamese address through its own language model and identifies the administrative units
itself, so a parcel books from the address as the customer wrote it. Synchronise provinces and
wards still imports the 2025 two-level catalogue for the cases where an exact identifier is wanted.
- Service Code - the Viettel Post service to book, for example VCN for standard express.
Leave it empty and the cheapest service Viettel Post offers for the route is chosen.
- Shipping Fee Paid By, Recipient May Inspect - the defaults for every parcel, changed per
delivery in its Shipping block. Viettel Post's ORDER_PAYMENT is worked out from the fee
payer and the cash to collect: nothing, the goods, the shipping, or both. The inspection rule is
written at the front of the courier note, as Viettel Post has no field for it.
- Parcel Contents - goods or documents.
Webhooks
Viettel Post reports parcel journeys over its webhook only; there is no per-parcel polling endpoint
on the partner API. The webhook is therefore not optional - without it, a transfer keeps the status
it had when it was booked.
- On the delivery method, click Generate a new secret and copy the Webhook URL.
- Log in to the Viettel Post partner portal on the development environment, open Account
configuration, and register the URL together with the secret.
- Use Check connection there to confirm Viettel Post can reach your server.
Two things about Viettel Post's callbacks are worth knowing, and both are handled: it warns that it
may send the same journey twice, and Odoo absorbs the repeat without a duplicate timeline entry; and
it expects a reply in under a second, so events are recorded and answered rather than processed
slowly.
Only one webhook endpoint can be configured per account. Under a delegation arrangement, journeys
go to the delegating account's endpoint, so the delegated account does not configure one at all.
Daily use
Click Send to Carrier on the delivery. The transfer name goes to Viettel Post as its ORDER_NUMBER with
CHECK_UNIQUE turned on, which is its own duplicate guard: re-sending the same reference returns
the parcel that already exists.
Viettel Post reports the collection fee and its VAT per parcel, so what it charges for handling cash
is visible per delivery rather than as one figure at the end of the month.
When a delivery fails, the reason code Viettel Post returns is translated on the timeline: "wrong
size", "recipient disputes the COD amount", "recipient could not be reached", rather than a bare
number.
Reconciling COD
Viettel Post's partner API has no settlement report. The statement is therefore built from the
delivery callbacks - what was delivered, what Odoo asked to be collected, and the fee Viettel Post
reported - and matching that against the bank credit is what the statement is for. Fetch from
Carrier says as much rather than implying the figures came from a report Viettel Post publishes.
Troubleshooting
"Sai tài khoản" on Test connection
The username or password is wrong, or the account has not been synced to the Partner system. The
Partner account is not the same as an ordinary Viettel Post customer account.
The address is cut short
Viettel Post caps its address fields at 150 bytes, and Vietnamese characters take up to three bytes
each. Odoo truncates on bytes rather than characters so the address stays valid, but a very long
street line will still lose its end. Keep the street line short and let the ward and province carry
the rest.
The timeline never moves
The webhook is not registered, or the secret does not match. This carrier has no polling fallback.