Build
Delivery and commission
Store riders or a Scanimart courier, what each costs, and what to do when a courier fails.
Every accepted delivery order is delivered one of two ways, chosen when it is accepted:
fulfilment_mode |
Who delivers | Who keeps the customer's delivery fee |
|---|---|---|
STORE_STAFF |
The store's own riders, using the Scanimart staff app | The store |
SCANIMART_COURIER |
A courier partner Scanimart books and pays for | Scanimart |
The store pays Scanimart a commission on each order, and the rate depends on the method. Never hard-code it — rates change by store and over time. Ask:
curl https://api.scanimart.com/v1/stores/1042/orders/ORDER-1A2B3C4D5E/delivery-options \
-H "Authorization: Bearer $SCANIMART_KEY"{
"object": "list",
"data": [
{
"mode": "STORE_STAFF",
"available": true,
"reason": null,
"commission_percent": "1.25",
"commission_amount": "3.71",
"eta_minutes": null
},
{
"mode": "SCANIMART_COURIER",
"available": true,
"reason": null,
"commission_percent": "5.00",
"commission_amount": "13.35",
"eta_minutes": 18
}
],
"has_more": false,
"next_cursor": null
}Show the cashier both options with their cost and the courier's pickup ETA, and send their choice as fulfilment_mode when accepting. An option with available: false carries a reason to show instead — for example cash-on-delivery orders are store-staff only, and the courier may not serve the store's area right now. Accepting with an unavailable method fails with fulfilment_unavailable.
On a courier order the commission is charged on the goods only, not the delivery fee, because Scanimart pays the courier out of that fee.
Following a courier order
Scanimart books the courier when picking starts in the Staff app. Your POS follows progress through these events:
| Event | Means | Do |
|---|---|---|
delivery.courier_booked |
A courier accepted the job. data.order.courier has the provider and a tracking link. |
Nothing yet |
delivery.courier_assigned |
A rider is on the way. courier.rider_name, rider_phone, vehicle. |
Print the rider's name on the packing slip |
delivery.rider_changed |
The courier swapped riders | Hand the bag to the new one |
order.out_for_delivery |
The rider collected it | — |
order.delivered |
Delivered | — a sale.completed follows |
delivery.failed |
No courier could be booked, or the courier gave up before pickup | Retry, or switch to store staff |
If a rider drops out before pickup, Scanimart books another automatically; you will see delivery.rider_changed or a fresh delivery.courier_booked.
When a courier fails
After delivery.failed, the order is still the store's. Two choices:
POST …/courier/retryasks Scanimart to try booking again — useful at a busy hour.POST …/delivery-methodwith{"fulfilment_mode": "STORE_STAFF"}hands it to the store's riders. Any booked courier is cancelled. Possible until the order is out for delivery.
If the order is cancelled, any courier is cancelled with it.
In the sandbox
Test orders can be accepted as courier orders. Moving one to OUT_FOR_DELIVERY or DELIVERED in the sandbox plays the courier's updates through the same path a real courier uses, so you see delivery.courier_assigned with a test rider, exactly as in live.
