If you sell to Ukraine, you will meet Nova Poshta. It is the country's dominant private carrier, and Ukrainian buyers do not think in street addresses — they think in branch numbers. A customer will tell you «branch 25 in Lviv», not a postal address, and they expect a dropdown that knows what that means.
That expectation is the whole integration problem in one sentence. Below: what the API gives you, where the key comes from, and the four traps that cost money after everything already «works».
What the API does: five jobs
| Job | What it returns |
|---|---|
| Settlement lookup | cities and towns, searchable as the buyer types |
| Branch directory | branches and parcel lockers for a chosen settlement |
| Rate quote | delivery price for weight, dimensions and route |
| Waybill | an electronic consignment note — the shipment's identity |
| Tracking | current parcel status by waybill number |
The first three shape checkout. The last two are back-office: they turn a paid order into a real parcel and tell you where it is.
Where the API key comes from
The key is free. It lives in the carrier's business cabinet, under developer settings — new.novaposhta.ua/dashboard/settings/developers. You need a business account, not a personal one; a personal account has no such section.
One thing worth knowing before you start: the key is tied to the counterparty — the legal entity that ships. Waybills created with it are issued on that entity's behalf, and the sender's city and branch are part of every request. So «connect the API» is not only a technical step; it also decides whose name is on the parcel.
Four traps the documentation does not warn about
These are the ones that surface after launch, when everything appears to work.
1. Cash on delivery charged on a paid order. The carrier can collect money from the recipient on handover. If that option is a plain on/off switch in your integration, it goes onto every shipment — including orders already paid by card. The customer pays twice and finds out at the counter.
The fix is to make the setting a *permission*, not a trigger: cash on delivery applies only when the order's payment status is «unpaid». Not «anything except paid» — an order marked «refunded» would then collect the full amount for goods you just refunded.
2. Double-charged delivery. The waybill has a «who pays for shipping» field. If it says «recipient» while your checkout also charges a delivery fee, the buyer pays twice: once to you online, once to the carrier on pickup. Nothing errors out; the two settings simply contradict each other.
3. Declared value set to the order total. Declared value is the insurance base, and the carrier charges a percentage of it. Put the full order total there and you are insuring your own delivery fee. Insure the goods: total minus shipping.
The reverse is also a trap. Understating declared value makes shipping cheaper, but if the parcel is lost the carrier reimburses exactly what was declared.
4. Waybills created twice. Creating a waybill is an irreversible external effect — it consumes a number and, on a live account, is billable. If your integration fires on an order-updated event without a claim, a retry or a double save produces a second parcel for the same order.
Path 1: build it yourself
Reasonable if you have a developer and unusual requirements. Budget for more than the happy path:
- Directory sync. Settlements and branches change. Nobody queries them live per keystroke — they are mirrored locally and refreshed on a schedule.
- Both name forms. Ukrainian buyers type a city in Ukrainian, but older data and some users still use Russian spellings. Search that ignores this looks broken to half your customers.
- Parcel lockers are not branches. They have weight and dimension limits, and offering one for an oversized item produces an order that cannot be fulfilled.
- Idempotency. See trap 4. This belongs in the first version, not «later».
Path 2: use a module
The alternative is a ready integration. In CommerCentr the Nova Poshta plugin ships the checkout side free: settlement autocomplete against a local mirror, branch and locker picker with filters, live rate quotes, and a nightly directory refresh.
The paid tier covers the back office: waybill creation and tracking, batch label printing (100×100 mm, several orders at once), volumetric weight in rate calculations, and parcel-locker fit filtering — lockers that physically cannot take the item disappear from the list.
That split is deliberate and worth stating plainly: choosing a branch is what a *store* needs to sell, so it is free. Printing forty labels without leaving the admin is what an *operation* needs, and that is what the paid tier is for.
If your store runs on OpenCart
Most Ukrainian OpenCart shops carry some Nova Poshta module already, and the usual complaints are the same three: the branch directory goes stale, waybills have to be typed into the carrier's cabinet by hand, and every platform upgrade breaks the integration again.
Worth checking on your current setup, whatever platform you are on: does the directory refresh by itself, does a waybill get created from the order card, and does cash on delivery respect payment status. If the answer to any of those is no, the integration is costing you time or money right now.
Cash on delivery and fiscal duties: a risk map, not advice
One point that goes beyond shipping. When the carrier collects money from the buyer on your behalf, that is a payment — and payments have fiscal consequences that vary by jurisdiction and by how your business is registered.
This article does not tell you what your obligations are. It flags that cash on delivery is not merely a shipping option: it changes who receives the money first, when the sale is recognised, and what document the customer is entitled to. Settle that with your accountant before switching it on, not after the first audit.
The technical side stays simple either way: the setting permits the mechanism, the order's payment status decides whether it fires.
Summary
The Nova Poshta API covers five jobs: find the settlement, list branches, quote the rate, create the waybill, track the parcel. The first three decide whether checkout feels native to a Ukrainian buyer; the last two decide how much manual work your team does per order.
Whichever path you take, the four traps are the same, and all four are quiet — nothing crashes, money just leaks. Check them explicitly: cash on delivery gated by payment status, one payer for delivery, declared value without the shipping fee, and a claim that stops duplicate waybills.
In CommerCentr the checkout side is free because a store cannot sell without it; the operational side is the paid tier. Look at returns and refunds as well — two of the traps above show up there again, from the money side.
