Integration of 1C-Bitrix with UkrPoshta delivery service (Ukraine)

Integration of 1C-Bitrix with UkrPoshta delivery service (Ukraine) We often encounter stores that need to deliver goods to settlements where Nova Poshta branches are not available. UkrPoshta is the only state operator covering all of Ukraine, including villages and small towns. After restructurin

Our competencies:

Frequently Asked Questions

Integration of 1C-Bitrix with UkrPoshta delivery service (Ukraine)

We often encounter stores that need to deliver goods to settlements where Nova Poshta branches are not available. UkrPoshta is the only state operator covering all of Ukraine, including villages and small towns. After restructuring, the API became modern: REST with JWT authorization. However, developers often stumble on the mandatory sequential creation of objects (address → client → shipment) and on address string parsing. Let's walk through the implementation on Bitrix. Each stage requires careful handling, otherwise integration can drag on for weeks. We have accumulated experience with over 10 projects where UkrPoshta was the primary carrier, and we are ready to share the details.

How to authorize in the UkrPoshta API?

Authorization is done via a Bearer token in the header Authorization: Bearer <token>. To get the token, send a POST request to /api/2.0/client-token, passing the key from your personal account. The base API URL: https://www.ukrposhta.ua/ecom/0.0.1. The token has a limited validity period, so it needs to be refreshed periodically. In Bitrix, it is convenient to store it in the module settings and update via an agent. The token timeout is 30 minutes, so the agent should run at least every 25 minutes. Check that there are no restrictions on agent execution in your hosting settings.

Creating a shipment

UkrPoshta requires sequential creation of objects: address → client → shipment. Below is an example handler in PHP for the bitrix:sale.order.ajax component:

class UkrPoshtaHandler { public function createShipment(\Bitrix\Sale\Shipment $shipment): string { $order = $shipment->getOrder(); $props = $order->getPropertyCollection(); // Step 1: create recipient address $addr = $this->apiPost('/addresses', [ 'postcode' => $props->getItemByOrderPropertyCode('ZIP')?->getValue(), 'city' => $props->getItemByOrderPropertyCode('CITY')?->getValue(), 'street' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(), 'houseNumber' => '1', ]); $addressUuid = $addr['uuid']; // Step 2: create recipient $client = $this->apiPost('/clients', [ 'firstName' => $this->parseFirstName($props), 'lastName' => $this->parseLastName($props), 'phoneNumber' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(), 'type' => 'INDIVIDUAL', 'addressId' => $addressUuid, ]); $clientUuid = $client['uuid']; // Step 3: create shipment $response = $this->apiPost('/shipments', [ 'sender' => ['uuid' => $this->getOption('SENDER_UUID')], 'recipient' => ['uuid' => $clientUuid], 'deliveryType' => 'W2D', 'weight' => max((int)$shipment->getWeight(), 20), 'length' => (int)$this->getOption('DEFAULT_LENGTH', 20), 'width' => (int)$this->getOption('DEFAULT_WIDTH', 20), 'height' => (int)$this->getOption('DEFAULT_HEIGHT', 5), 'declaredPrice' => (int)round($order->getPrice()), 'description' => 'Goods', 'paidByRecipient' => false, ]); return $response['uuid'] ?? ''; } } 

paidByRecipient: false — the store pays for delivery. If true, the recipient pays upon receipt. Note: UkrPoshta API returns an error if the houseNumber field is missing. In a real project, you should take it from an order property, otherwise parsing may fail.

Delivery types

Code Description
W2W Warehouse to post office
W2D Warehouse to door
D2W Door to post office
D2D Door to door

The choice of type affects cost and delivery times. Based on experience, W2D is most often used for online stores — customers prefer home delivery.

How to implement shipment tracking?

After creating a shipment, save its UUID. Then set up an agent in Bitrix that calls GET /shipments/{uuid}/statuses every 3-4 hours. The received statuses can be logged or displayed in the order admin panel. Here is a simple implementation:

// Agent called every 3 hours public function trackShipments(): string { $shipments = \Bitrix\Sale\Shipment::getList([ 'filter' => ['!UKRPOSHTA_UUID' => null, '!=STATUS' => 'DELIVERED'] ]); foreach ($shipments as $shipment) { $statuses = $this->apiGet("/shipments/{$shipment['UKRPOSHTA_UUID']}/statuses"); // Update order status if (!empty($statuses)) { \Bitrix\Sale\Order::update($shipment['ORDER_ID'], [ 'UKRPOSHTA_STATUS' => end($statuses)['code'] ]); } } return 'trackShipments();'; } 

This approach allows seeing the current location of the parcel without manual updates.

Getting a label

// Print label — button in Bitrix order admin public function getLabel(string $shipmentUuid): string { $response = $this->apiGet("/shipments/{$shipmentUuid}/label"); return base64_decode($response['pdf_base64'] ?? ''); } 

The method returns a PDF file that can be saved or displayed to the user. In the admin area, it's convenient to add a "Print label" button directly in the shipment card.

What to know about international shipments?

For routes UA→BY, UA→PL and others: customs declaration CN22/CN23, weight limit up to 30 kg, mandatory HS code for goods. We recommend adding a user property UF_HS_CODE to products in the information block and automatically passing it to the declaration. Without this, UkrPoshta will reject the request. Also note: for international shipments, the country code must be specified in the recipient's address and the sender's country.

Address field specifics

UkrPoshta expects separate fields: street, house number, apartment. In Bitrix, the address is usually stored as a single string. You either need to add separate fields to the order form or implement address string parsing. The second approach gives about 85% accuracy, while the first is more reliable. In our projects, we use custom order properties "Street", "House", "Apartment" — this eliminates recognition errors. For example, when parsing, the house number is often confused with the apartment, especially in addresses like "Gagarin St., 10, apt. 5".

What is included in turnkey integration

  • Setting up the delivery module and obtaining tokens
  • Creating custom order properties for separate address fields
  • Implementing the shipment handler with UkrPoshta API calls
  • Generating and printing a waybill in PDF format
  • Setting up background tracking (agent with 3-4 hour interval)
  • Integrating customs declaration for international parcels
  • Preparing documentation and handing over access

This list covers all typical complexities. We guarantee stable data exchange and full support after implementation. If you need integration with UkrPoshta, contact us to assess your project. Get a consultation on stages and timelines to start without unnecessary delays.

Timelines

Stage Duration
Basic integration (shipment creation + label printing) 4–5 days
Adding tracking +1–2 days
International shipments (customs, CN22/CN23) +2 days

Timelines are given assuming all client accesses are ready. On average, the project takes one week. We work with Bitrix and have implemented over 10 integrations with Ukrainian postal services. Reach out — we'll help set up delivery via UkrPoshta in your store.