Order synchronisation
Online and platform orders flow into POS so the business sees every sale in one place and stock is deducted once.
Submitting
POST /api/v1/businesses/{id}/orders (orders:write)
{
"externalRef": "RD-ORD-20261105-0042",
"customer": { "externalId": "buyer-77", "name": "Lerato M", "phone": "+27 82 …" },
"lines": [
{ "externalVariantId": "menu-981", "quantity": 2, "modifierIds": [] },
{ "variantId": "cm…", "quantity": 1, "unitPrice": "18.00" }
],
"payment": { "method": "OTHER", "amount": "148.00", "provider": "rekadijo", "reference": "PAY-8812" },
"fulfilment": "delivery",
"note": "Gate code 1234"
}
- Idempotent on
externalRef(per application). Resubmitting returns the same order with"replayed": true— retry freely. - Lines name a variant by your
externalVariantId(from product sync) or by POSvariantId.unitPricerecords what the customer was actually charged on your platform; omit it to use the POS price. discount(optional,{ "kind": "FIXED" | "PERCENT", "value": "10.00" }) records an order-level discount such as a platform promotion; it is spread across lines before VAT.- Send only what belongs to the business's sale. Delivery fees and tips collected for a driver or the platform are not part of the seller's order.
- With
paymentthe order is completed: stock is deducted (ONLINE_ORDERmovements), cost of sales and VAT are posted, and the payment is recorded against "Other payments clearing" (money your platform collected and will settle to the business).payment.amountmust equal the order total POS computes, or the request is rejected — so totals can never silently disagree. - Without
paymentthe order isOPEN: stock is reserved (shown asreserved, removed fromavailable) but not deducted, and nothing is posted to the books.
Updating
PATCH /api/v1/businesses/{id}/orders/{orderId}
action |
Body | Effect |
|---|---|---|
pay |
payment |
Completes an OPEN order: releases the reservation, deducts stock, posts the books |
cancel |
reason |
Voids an unpaid order and releases its reservation. A paid order is refunded instead (POST …/sales/{id}/refunds) |
fulfil |
fulfilmentStatus |
received → accepted → preparing → ready → out_for_delivery → delivered / collected |
Kitchen and counter staff see these in POS. Changes emit order.updated (and order.cancelled).
GET …/orders/{orderId} accepts a POS id or ext:<externalRef>.
Quotation-first platforms (RekaDijo)
Do not push a quotation as an order. Push when the buyer accepts and the order exists on your side: unpaid → reserve; paid → complete. Your payment and settlement logic stays where it is; POS records the outcome.
Keeping channels distinct
Orders from an application have channel: "PLATFORM"; orders from a business API key are ONLINE; register sales are POS. Reports and the Control Centre split by channel, so online and in-store sales are never confused.