1C-Bitrix Integration with Yandex Delivery Service
Yandex Delivery is available as an independent B2B service for online stores. Main scenarios: express delivery within the city (1–3 hours), same-day or next-day courier delivery, delivery to pickup points. Integration with 1C-Bitrix is done via Delivery API v2.
API Structure
Authorization: OAuth token from Yandex Passport in the Authorization: Bearer <token> header. Base URL: https://b2b.taxi.yandex.net/b2b/cargo/integration/v2.
Main operations:
-
POST /check-price— preliminary cost estimate -
POST /claims— claim creation -
GET /claims/info— claim status -
POST /claims/accept— claim confirmation (without this step, no courier is assigned)
Cost Calculation
class YandexDeliveryHandler extends \Bitrix\Sale\Delivery\Services\Base
{
protected function calculateConcrete(
\Bitrix\Sale\Shipment $shipment
): \Bitrix\Sale\Delivery\CalculationResult {
$result = new \Bitrix\Sale\Delivery\CalculationResult();
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$address = $props->getItemByOrderPropertyCode('ADDRESS')?->getValue();
if (!$address) {
$result->addError(new \Bitrix\Main\Error('Delivery address not specified'));
return $result;
}
$payload = [
'items' => $this->buildItems($shipment),
'route_points' => [
['coordinates' => $this->getOption('FROM_COORDS'), 'type' => 'source', 'visit_order' => 1],
['address' => ['fullname' => $address], 'type' => 'destination', 'visit_order' => 2],
],
];
$response = $this->apiPost('/check-price', $payload);
if (!empty($response['price'])) {
$result->setDeliveryPrice((float)$response['price']);
}
return $result;
}
}
Note: check-price returns an estimated cost. The actual price is fixed when the claim is created. If the discrepancy exceeds 20%, it is recommended to display "price from".
Two-Step Claim Creation
Yandex Delivery requires explicit confirmation after creation:
public function createAndAcceptClaim(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$claim = $this->apiPost('/claims?request_id=' . uniqid(), [
'items' => $this->buildItems($shipment),
'route_points' => $this->buildRoutePoints($shipment),
'comment' => 'Order #' . $order->getId(),
'callback_properties' => ['callback_url' => $this->getOption('WEBHOOK_URL')],
]);
$claimId = $claim['id'];
// Without this call, no courier will be assigned
$this->apiPost('/claims/accept?claim_id=' . $claimId, [
'version' => $claim['version'],
]);
return $claimId;
}
request_id is an idempotency key: a repeated request with the same value returns the existing claim.
Status Webhooks
Yandex Delivery supports push notifications to callback_url. Lifecycle statuses:
| Status | Meaning |
|---|---|
new |
Claim created |
accepted |
Confirmed |
performer_found |
Courier found |
pickuped |
Cargo picked up from warehouse |
delivery_arrived |
Arrived at recipient |
delivered |
Delivered |
returning |
Return in progress |
cancelled |
Cancelled |
Case Study: Express Delivery in Moscow
A cosmetics store needed to display "deliver in 2 hours" for orders placed before 15:00. Two delivery methods were implemented: standard (next day) and express (2–3 hours, +350 RUB surcharge). Express is available for orders placed before 15:00 MSK with a minimum order value of 1,500 RUB. The check is implemented in the handler's isCompatible() method. When a cancelled status arrives via webhook, the manager is notified and the customer is offered the nearest available time slot.
Timelines
| Scope | Timeline |
|---|---|
| Calculation + claim creation + confirmation | 3–4 days |
| + Status webhooks | +1 day |
| + Express/standard with time conditions | +1–2 days |
| + Customer-facing tracking interface | +2 days |







