Ring up a manual (counter) order
- Credentials, one of
- Station token
- OAuth access token
- Scopes
orders:write- Subscription
- Needs an active plan. Otherwise
403 subscription_locked. - Idempotency
- Send an
Idempotency-Keyheader. A retry with the same key does the work once.
Access: OAuth scope orders:write; write-gated by the subscription.
AuthorizationBearer <token>It may call only the operations whose x-stations lists its kind, on its own store, and acts through the access of the owner or admin who paired it. Unpairing it, or that person leaving the business, ends it (401 station_revoked).
storeId*stringA store the person can reach. Any other id answers 404, never 403.
Idempotency-Key*stringRequired on every write. Minted on the device when the person taps, reused on every retry. A write without one, or with one that does not match the pattern, is refused with 422 validation_error. Scoped to the token's subject, remembered 24 hours. A replay returns the first 2xx response with Idempotent-Replay: true; a request still running answers 409 in_flight; the same key with a different method, path or body answers 409 idempotency_key_reused; non-2xx results are not remembered. If the key store cannot be read nothing is processed and the answer is 503 idempotency_unavailable: retry with the same key.
^[A-Za-z0-9_-]{8,128}$application/json- body
Passed through to the service, which validates (422 on failure).
lines*array<>customerId?stringcustomerName?stringcustomerEmail?stringcustomerPhone?stringnote?stringshippingAddress?markPaid?booleanTake payment now (cash, card machine, EFT received).
paymentMethod?stringCreated
application/json- response
data*curl -X POST 'https://api.shopeazy.co/v1/merchant/stores/<storeId>/orders' \ -H 'Authorization: Bearer <access_token>' \ -H 'Idempotency-Key: <unique_key>' \ -H 'Content-Type: application/json' \ -d '{ "lines": [ { "itemId": "string", "quantity": 1 } ]}'{ "data": { "id": "string", "number": "string", "channel": "online", "customerName": "string", "soldByName": "string", "total": { "amount": 0, "currency": "ZAR" }, "status": "open", "paymentStatus": "unpaid", "fulfillmentStatus": "unfulfilled", "placedAt": 0, "lineCount": 0, "kinds": [ "physical" ], "currency": "string", "customerEmail": "string", "customerPhone": "string", "lines": [ { "id": "string", "kind": "physical", "requiresShipping": true, "title": "string", "variantTitle": "string", "customisations": [ { "groupName": "string", "choiceName": "string", "price": { "amount": 0, "currency": "ZAR" } } ], "quantity": 0, "unitPrice": { "amount": 0, "currency": "ZAR" }, "lineTotal": { "amount": 0, "currency": "ZAR" }, "fulfilled": true, "imageUrl": "string" } ], "subtotal": { "amount": 0, "currency": "ZAR" }, "shipping": { "amount": 0, "currency": "ZAR" }, "discount": { "amount": 0, "currency": "ZAR" }, "paid": { "amount": 0, "currency": "ZAR" }, "refunded": { "amount": 0, "currency": "ZAR" }, "kept": { "amount": 0, "currency": "ZAR" }, "refundable": { "amount": 0, "currency": "ZAR" }, "pendingRefunds": [ { "amount": { "amount": 0, "currency": "ZAR" }, "providerName": "string" } ], "eft": { "reference": "string", "overdue": true, "overdueAt": 0, "bankName": "string", "account": "string" }, "customerNote": "string", "giftNote": "string", "notes": [ { "at": 0, "message": "string", "author": "string" } ], "timeline": [ { "at": 0, "type": "created", "message": "string", "author": "string" } ], "fulfilment": { "method": "delivery", "serviceName": "string", "lockerName": "string", "address": "string", "provider": "string", "serviceCode": "string", "locker": { "id": "string", "name": "string", "provider": "string", "courier": "string", "address": "string", "hours": "string" }, "fellBack": true }, "shippingAddress": "string", "shippingAddressParts": { "addressLine": "string", "localArea": "string", "city": "string", "province": "string", "postalCode": "string" }, "shippingAddressMissing": [ "string" ], "needsCourier": true, "shipment": { "provider": "string", "trackingReference": "string", "state": "pending", "estimate": "string" } }}List or search orders GET
Access: OAuth scope `orders:read`; not write-gated. Paged: `{ items, nextCursor }`, `limit` (default 30, at most 100) and an opaque `cursor`.
Do one thing to several orders at once POST
Up to 200 orders. Every order is re-read and decided again (an order that cannot take the action, one already in that state, one that is gone, a sold-out item) and then goes through the same service call, audit entry and customer emails as its single-order operation. One failing never stops the rest; orders run a few at a time. The answer is one `{ id, ok, error? }` per id (`BulkResult`), always 200. A retry is safe: each order is decided again from a fresh read, so one already done is left alone (`ok: false`, `validation_error`, for example `already cancelled`) and nothing happens twice; the same `Idempotency-Key` replays the first answer. The scope is `orders:write`; `cancel` calls off a booked courier collection per order, as `cancelOrder` does. The refund-bearing paths stay with `refundOrder` (`orders:refund`). Access: OAuth scope `orders:write`; write-gated by the subscription.