CommerCentr
EN
Sign in

Ukrposhta for an online store: connecting delivery

Ukrposhta for an online store: connecting delivery

Ukrposhta for an online store is the cheapest delivery across Ukraine and almost the only way to reach a customer in a village where no other carrier has a branch. The price of that is a longer transit time and an address system your checkout has to understand. Below: what to configure, where order forms usually break, and how to verify that yours works.

Why Ukrposhta is not "just another carrier in the list"

From a store's point of view most carriers are simple: there is a list of branches and the customer picks theirs. Ukrposhta works differently — it starts from an address, not a branch number. A single post office serves dozens of settlements, and a customer usually knows their postcode or the name of their village rather than a branch number.

The practical consequence: if you simply drop a "choose a branch" select into checkout, a rural customer will not find theirs. They will see the district centre, wonder whether they are supposed to travel there, and leave to "check". That is where most orders on this route die, and that is what the module has to solve.

The Address Classifier: the source everything depends on

Ukrposhta maintains an official address directory — the Address Classifier. It is an export of the country's entire address structure: regions, districts, communities, settlements, streets, postcodes and the offices that serve them. It changes over time: villages merge, postcodes shift, branches close.

Two rules follow, and they are worth accepting up front:

  • Do not type addresses in by hand. A list assembled once will be stale within months, and you will learn about it from failed hand-offs.
  • Do not query the API on every character. If checkout calls the carrier on each keystroke, you have tied your order flow to someone else's uptime.

Official documentation and directory access live on the carrier's site: ukrposhta.ua.

The key architectural decision: local database versus live API

There are two ways to connect a carrier, and the difference only becomes visible when something goes wrong.

Two approaches to address data in checkout
Live API callLocal database + sync
Type-ahead speeddepends on the networkinstant, from your own data
Carrier is downcheckout stallsthe order still completes
API limitsspent on every characterspent only on syncing
Data freshnessalways currentas of the last sync

The Ukrposhta module follows the second pattern: the directory lands in your database, syncing runs on a schedule, and checkout reads local data. The downside is stated plainly — between syncs the data lags slightly. For an address directory that is acceptable: villages do not appear daily.

Nova Poshta and Meest use the same model, so checkout behaves identically whichever carrier the customer picks. All three are in shipping modules.

What to configure, step by step

Order matters here — each step depends on the previous one.

  • 1. Contract and carrier account. First the contract with Ukrposhta and access to their portal. Without it there is no key, and without a key the module syncs nothing.
  • 2. API key. Issued in the portal. This is the same Ukrposhta API the module uses to pull the directory. The key belongs in store settings, not in code.
  • 3. First sync. The directory is exported into your database. This is the longest step; subsequent updates are incremental.
  • 4. Schedule. Put syncing on cron. Once a day is a reasonable baseline for an address directory.
  • 5. Verify checkout. Place a test order to a village, not to a regional capital. If the address resolves, the module works.

Where this usually breaks

Three common failures, and none of them are about code.

The key ended up in the repository. An API key is access to your carrier account. It belongs in settings or in.env, neither of which goes into git. If it has already appeared in commits, reissue it rather than hoping nobody noticed.

Syncing never made it to cron. The first import was run by hand, it worked, and everyone moved on. Six months later customers start reporting that their branch is missing. The module is fine — nobody was feeding it.

Testing on the capital. A regional centre always resolves, even from a half-loaded directory. Your test order should go to a settlement whose spelling you are not sure of yourself.

Who gains most from Ukrposhta

Honestly, about who actually needs this:

  • If your customers are outside the cities. Here Ukrposhta has no competitor: where no other carrier has a branch, the post office almost always does.
  • If you sell inexpensive goods. When delivery is comparable to the price of the item, the carrier decides whether the order happens at all.
  • If you ship abroad. International parcels are a separate scenario with few alternatives in this price bracket.

And where it will not help: if your customer is urban and expects a parcel tomorrow, Ukrposhta will not meet that expectation. Keep several carriers and let the buyer choose — that is cheaper than arguing with their habits.

Where to start

The cheapest way to check is not to read reviews but to put the free build on a test domain: the Ukrposhta module is already inside, along with Nova Poshta and Meest. Run one test order to a village and see whether the address resolves. If it does, delivery is settled and you can go back to your products.