Guide
Orders
An order moves through buyer, seller, and — for deliveries — rider hands before it's done. Every endpoint on this page requires authentication, and lives under either https://api.swiftgoma.com/api/v1/cart or https://api.swiftgoma.com/api/v1/orders.
Cart → checkout
A buyer has one cart per shop, capped at 50 line items. Checkout turns one shop's cart into an order and starts payment — it doesn't touch any of the buyer's other carts.
- 1
Build the cart
POST /cart/items to add, PUT /cart/items/:itemId to change quantity, DELETE /cart/items/:itemId to remove. - 2
Check out
POST /orders/checkout with the shopId, fulfillment method, and mobile money payment details. The order is created asAWAITING_PAYMENT.
Idempotency-Key header on checkout — a retried request with the same key returns the original order instead of charging the buyer twice.Order status lifecycle
Status only ever moves forward through this graph — there's no going back a step.
| Status | Can move to |
|---|---|
| AWAITING_PAYMENT | PENDING_SELLER_REVIEW, FAILED, CANCELLED |
| PENDING_SELLER_REVIEW | ACCEPTED, REJECTED, CANCELLED, EXPIRED |
| ACCEPTED | PREPARING, READY_FOR_PICKUP, RIDER_ASSIGNED, CANCELLED |
| PREPARING | READY_FOR_PICKUP, RIDER_ASSIGNED, CANCELLED |
| READY_FOR_PICKUP | COMPLETED, CANCELLED |
| RIDER_ASSIGNED | PICKED_UP, CANCELLED, ACCEPTED |
| PICKED_UP | ON_THE_WAY, FAILED |
| ON_THE_WAY | DELIVERED, FAILED |
| DELIVERED | COMPLETED |
| COMPLETED / REJECTED / CANCELLED / EXPIRED / FAILED | — terminal |
PICKUP vs DELIVERY diverge after ACCEPTED
fulfillmentMethod.Who does what
| Role | Moves the order through |
|---|---|
| Buyer | checkout · cancel · confirm receipt |
| Seller | accept · reject · mark ready · complete pickup · assign rider |
| Rider | picked up · on the way · complete delivery · failed delivery |
QR-code handoffs
Both handoff points — a buyer collecting a pickup order, or a rider delivering one — are confirmed the same way: the buyer shows a QR code, the other party scans it.
- 1
Buyer generates the code
GET /:id/qr-code returns a single-useqrToken. - 2
Seller or rider scans it
POST /scan resolves the token to the order — this is what a scanning app calls right after reading the code. - 3
Confirm the handoff
The seller calls POST /:id/complete-pickup, or the rider calls POST /:id/complete-delivery, passing the sameqrToken.
In-delivery chat
Buyer and rider can message each other through GET /:id/messages, POST /:id/messages (up to 1000 characters, capped at 20 per minute), and POST /:id/messages/read— but only while the order is actively out for delivery.
The thread isn't open the whole time
RIDER_ASSIGNED, PICKED_UP, or ON_THE_WAY. Before a rider is assigned, or after delivery, POST /:id/messages is rejected.Cancellation & refunds
A buyer can cancel their own order via POST /:id/cancel while it's still in an early-enough status — AWAITING_PAYMENT, PENDING_SELLER_REVIEW, ACCEPTED, PREPARING, READY_FOR_PICKUP, or RIDER_ASSIGNED. Once a rider has picked up the order, it can no longer be cancelled that way.
Staff have three refund-related endpoints, under the Order Moderation group:
| Endpoint | Role | Notes |
|---|---|---|
| POST /admin/:id/cancel | ADMIN, SUPPORT | Cancels on the buyer's behalf, e.g. for a support case. |
| POST /admin/:id/refund/request-approval → confirm | ADMIN | OTP-gated — emails a code, then requires it to complete the refund. |
| POST /admin/:id/refund | ADMIN | Issues the refund directly, without the OTP step. |
Timeouts to plan around
| Window | Duration |
|---|---|
| Seller must accept or reject a new order | 120 minutes, then it expires |
| Rider must act on an assigned order | 240 minutes |
| Buyer confirms receipt after delivery | Auto-completes after 48 hours if they don't |