Ask the provider whether the order is paid, and settle it if so
- Credentials, one of
- Store key and Order access token
- Store key and Shopper session
- Store key and Shopper ID token
- Scopes
checkout:write
For the success page. The provider's callback to the platform is the primary settlement path; this is the second, independent one. Idempotent and safe to poll: an already-paid order returns at once. The status always comes from the provider; nothing a caller sends can mark an order paid. Takes no body.
It returns the order, so it has the same access rule as GET /v1/store/orders/{id}: X-Order-Token or the shopper who placed it.
Old path, deprecated, sunset 1 Feb 2027: POST /v1/orders/{id}/confirm.
AuthorizationBearer <sez_pub_... (publishable) or sez_sk_... (secret)>A per-store key from the console. Publishable keys are browser-safe; secret keys are server-only.
Scope: checkout:write
X-Order-Token<token>The accessToken from POST /v1/store/orders. Reads back that one order for 30 days.
id*stringThe order id returned at placement.
Whether it is paid, and the order as it stands now.
application/json- response
data*curl -X POST 'https://api.shopeazy.co/v1/store/orders/<id>/confirm' \ -H 'Authorization: Bearer sez_pub_...' \ -H 'X-Order-Token: <order_access_token>'{ "data": { "paid": true, "order": { "id": "string", "number": "string", "status": "open", "paymentStatus": "unpaid", "fulfillmentStatus": "unfulfilled", "currency": "string", "totals": { "subtotal": { "amount": 0, "currency": "ZAR" }, "discount": { "amount": 0, "currency": "ZAR" }, "shipping": { "amount": 0, "currency": "ZAR" }, "tax": { "amount": 0, "currency": "ZAR" }, "total": { "amount": 0, "currency": "ZAR" }, "paid": { "amount": 0, "currency": "ZAR" }, "balanceDue": { "amount": 0, "currency": "ZAR" } }, "customer": { "name": "string", "email": "string", "phone": "string" }, "lines": [ { "itemId": "string", "title": "string", "variantTitle": "string", "quantity": 0, "unitPrice": { "amount": 0, "currency": "ZAR" }, "customisations": [ { "groupId": "string", "groupName": "string", "choiceId": "string", "choiceName": "string", "price": { "amount": 0, "currency": "ZAR" } } ], "fulfillmentStatus": "unfulfilled", "attendees": [ { "name": "string", "answers": [ { "fieldId": "string", "value": "string" } ] } ], "departure": { "at": 0, "meetingPointId": "string", "note": "string", "participants": [ { "name": "string", "answers": [ { "fieldId": "string", "value": "string" } ] } ] }, "booking": { "at": 0, "durationMins": 0 } } ], "createdAt": 0, "paidAt": 0, "fulfilment": "delivery", "shippingAddress": { "addressLine": "string", "localArea": "string", "city": "string", "province": "string", "postalCode": "string", "country": "string" }, "delivery": { "provider": "string", "serviceCode": "string", "serviceName": "string", "price": { "amount": 0, "currency": "ZAR" }, "locker": { "id": "string", "name": "string", "provider": "string", "courier": "string", "address": "string" } }, "discountCode": "string", "giftNote": "string", "note": "string", "payment": { "method": "card", "bank": { "bankName": "string", "accountHolder": "string", "accountNumber": "string", "accountType": "string", "branchCode": "string", "instructions": "string" }, "reference": "string", "overdueAt": 0 } } }}Open a hosted checkout for the order's balance POST
Goes through whichever provider the merchant activated (Yoco, iKhokha or Peach). Send the shopper to the returned `url`. Return URLs must be absolute and `https` (`http://localhost` is allowed for development). Peach renders its form inside your own page, so pass `checkoutPageUrl` when the store is on Peach. The checkout is opened with your site's origin (from `checkoutPageUrl`, else `successUrl`); for Peach that domain must be on the merchant's allowlist. Settlement is the platform's job: iKhokha and Peach call back to this API, Yoco to ShopEazy's own webhook. Use `POST /v1/store/orders/{id}/confirm` on your success page. Old path, deprecated, sunset 1 Feb 2027: `POST /v1/orders/{id}/pay`.
File a contact-form enquiry and tell the merchant POST
Recorded in the store **before** anything is sent; the merchant notification and email are best-effort and never fail the call, so do not retry a `201`. The recipient, subject and body are composed server-side from structured fields; there is deliberately no "send an email" endpoint. A `name` and at least one of `phone` or `email` are required. Strings are trimmed and capped (name 120, phone 40, email 200, service 120, notes 2000 characters). Old path, deprecated, sunset 1 Feb 2027: `POST /v1/booking-requests`.