Developing a Delivery Tracking Module for 1C-Bitrix
Customer places order and waits for package. If they must visit the shipping service website, copy tracking number and search for status each time — poor experience. Delivery tracking module solves this: status updates automatically, user sees it in personal account and receives status change notifications.
Data Sources
Tracking number appears in order after transfer to delivery service. In Bitrix it's stored in TRACKING_NUMBER field of b_sale_order_delivery table or in custom order property, depending on delivery configuration. Shipping modules (DPD, CDEK, Boxberry, Russian Post) store tracking numbers differently — must be considered during implementation.
Module Architecture
local/modules/vendor.tracking/
├── lib/
│ ├── Provider/ # Adapters for shipping APIs
│ │ ├── CdekProvider.php
│ │ ├── DpdProvider.php
│ │ └── RussianPostProvider.php
│ ├── TrackingService.php # Orchestrator
│ └── StatusMapper.php # Status normalization
├── install/
│ └── db/install.sql
└── cron/
└── update_statuses.php
Table b_tracking_status — status history for each order:
| Field | Type | Purpose |
|---|---|---|
| ID | int auto_increment | — |
| ORDER_ID | int | Order ID |
| TRACKING_NUMBER | varchar(100) | Tracking number |
| PROVIDER | varchar(50) | Shipping service code |
| STATUS_CODE | varchar(50) | Status code from provider |
| STATUS_TEXT | text | Human-readable status |
| LOCATION | varchar(255) | Current location |
| EVENT_TIME | datetime | Event time |
| NOTIFIED | tinyint(1) | Whether notification sent |
| CREATED_AT | datetime | When recorded in DB |
Shipping API Integration
Each provider implements interface:
interface DeliveryProviderInterface
{
public function getStatuses(string $trackingNumber): array;
public function getProviderCode(): string;
}
CDEK uses REST API v2. Get token via POST /v2/oauth/token, statuses via GET /v2/orders?cdek_number={number}. Response contains statuses array with code, name, date_time, city fields.
Russian Post provides SOAP service https://tracking.russianpost.ru/rtm34. getOperationHistory method returns XML with shipment operations. Parsing via SoapClient or direct XML parsing with SimpleXMLElement.
DPD — REST API, tracking via GET /api/tracing/order/{trackingNumber}.
Status Normalization
Each provider has own status codes. StatusMapper brings them to unified set:
| Internal Status | Description |
|---|---|
| CREATED | Order created with delivery service |
| IN_TRANSIT | In transit |
| AT_PICKUP | Arrived at pickup point |
| DELIVERED | Delivered |
| RETURNED | Return |
| FAILED | Delivery error |
Allows unified tracking interface regardless of shipping service.
Automatic Status Updates
Cron task runs every 30 minutes:
*/30 * * * * php /var/www/site/local/modules/vendor.tracking/cron/update_statuses.php
Script selects orders in active delivery statuses (DELIVERY, DELIVERING), gets current statuses from provider for each, compares with last recorded in b_tracking_status. If status changed — writes new record and sets NOTIFIED = 0 flag.
Separate agent or next cron run traverses records with NOTIFIED = 0 and sends notifications.
Customer Notifications
On status change customer receives:
-
Email — via mail event
TRACKING_STATUS_CHANGED. Template contains: current status, tracking number, order page link, "Track on shipping service website" button. - Push notification (if web push implemented) — short status change message.
Personal Account Widget
Order page in personal account shows delivery timeline — all events chronologically with status icons. Data taken from b_tracking_status by ORDER_ID without API provider call — fast and independent of external service availability.
Development Timeline
| Scope | Components | Duration |
|---|---|---|
| Basic | 1 provider, cron update, status table, display in account | 5–7 days |
| Standard | + 3 providers, status normalization, email notifications, timeline | 10–14 days |
| Extended | + 5+ providers, push notifications, tracking map, delivery analytics | 16–22 days |







