Developers

Guides

Markdown

Working with orders

Order and payment statuses, customer data, and keeping your data in sync between webhooks and the API.

What an order contains

With the orders:read scope you receive the full order, except the customer's identity:

FieldExampleNotes
id"ord_8Kd2"Stable string ID. Use it as the key in your database
number10482The number the merchant and the customer see
status"processing"Order status, as in the next table
payment_status"paid"unpaid, paid or refunded
currency"SAR"
totals{"subtotal":"180.00","discount":"0.00","shipping":"25.00","total":"205.00"}String amounts with two decimal places
itemsProduct, name at the time of the order, kind, quantity and price
order_url"https://store.example/orders"The customer's orders page, the same link as the order email. It is not a link to this one order and does not sign the customer in. null when the store has no https domain
created_at updated_at paid_at refunded_atUTC

An order never includes the payment method, gateway or card details. A full example is in List orders.

Order statuses

statusMeaning
pendingCreated and not yet in progress; usually not paid yet
processingIn progress: paid and awaiting delivery or shipping
completedCompleted and delivered
cancelledCancelled by the merchant, or the payment window expired
returnedRefunded in any way, or marked returned by the merchant

status and payment_status answer different questions. A pending order is unpaid, a processing order is paid, and any refund makes the order returned with payment_status: refunded. To answer "has the customer paid?", read payment_status, not status.

Customer data

With the customers:read scope, the order also includes:

JSON
"customer": {
  "id": "c_2041",
  "name": "Sara Alotaibi",
  "phone": "+966512345678",
  "email": "[email protected]"
},
"shipping_address": {
  "name": "Sara Alotaibi",
  "phone": "+966512345678",
  "country": "SA",
  "city": "Riyadh",
  "district": "Al Malqa",
  "street": "…",
  "postal_code": "13521",
  "short_address_code": "RAAA1234",
  "building_number": "2101",
  "secondary_number": "8899",
  "notes": null
}
  • The phone number is always in E.164 format. Saudi numbers written as 05…, 5…, 9665… or 009665… arrive as +9665…. A number that cannot be validated arrives as null, never as raw text.
  • customer.id is null for a guest order without an account.
  • Every address field is a trimmed string or null; shipping_address itself is null when the order has no address.
  • Without the scope, both keys are absent. Do not assume they exist.

Keeping in sync

Webhooks arrive within seconds but do not guarantee ordering, and the same webhook can arrive twice. The reliable pattern:

  1. Subscribe to order.created, order.paid, order.status.updated and order.refunded.
  2. When a webhook arrives, compare its resource.version with the last one you applied for that order: if it is lower, ignore it. Order events carry a strictly increasing version; the order object's own resource_version is always 0.
  3. Once an hour, fetch what changed with updated_after to catch any webhook you missed:
cURL
curl "https://larm.sa/stores/$STORE_ID/v1/orders?updated_after=2026-10-15T08:00:00Z&limit=100" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

List filters: status, payment_status, created_after, created_before and updated_after, plus limit and cursor. Any other filter returns 400 INVALID_FILTER. Results are sorted by creation time, newest first.

Payments

With the payments:read scope you read payment outcomes: each payment has exactly id, order_id, status and created_at, where status is succeeded or failed. In-progress attempts are not returned, and payments carry no gateway, amount, currency or card details. For the order and its payment status, orders:read is enough; a later refund appears on the order as payment_status: refunded and the order.refunded webhook.

Not available

  • There is no endpoint to list customers. Customer data arrives only with their order or cart.
  • Orders and their statuses cannot be modified through the API.
  • Shipping and tracking data are not available yet.

    ↑↓ moveEnter openEsc close