Using the Orders / OMS API

API OAuth Order Management OMS Orders CRUD Android iOS

Purpose of this guide

This guide covers how to create, retrieve, update, transition (confirm / processing / cancel / store POS pickup), and delete the orders under a business account using ReceiptRoller's Orders / OMS API. It is the entry point when you want to unify a store's sales channels — web orders, phone orders, marketplace integrations, and more.

Prerequisites

  • You have obtained an access token via the OAuth 2.0 authorization code flow
  • Your app's scopes include store.orders.read (read) / store.orders.write (create, update, delete, status transition)
  • You know the business account ID (UUID) (Listing business accounts, stores, and POS terminals)
  • Base URL: https://receiptroller.io

Endpoints

MethodPathPurposeRequired scope
GET/api/v1/ordersList orders (filter by status / channel / paymentStatus)store.orders.read
GET/api/v1/orders/{orderId}Detail of one orderstore.orders.read
POST/api/v1/ordersCreate a new orderstore.orders.write
PUT/api/v1/orders/{orderId}Update an order (customer, address, line items, amounts, etc.)store.orders.write
POST/api/v1/orders/{orderId}/confirmStatus transition: Pending → Confirmedstore.orders.write
POST/api/v1/orders/{orderId}/processStatus transition: Confirmed → Processingstore.orders.write
POST/api/v1/orders/{orderId}/cancelStatus transition: cancelstore.orders.write
POST/api/v1/orders/{orderId}/fulfill-via-posStatus transition: completed pickup at store POS (→ Delivered)store.orders.write
DELETE/api/v1/orders/{orderId}Delete an orderstore.orders.write

Order status values

StatusLabelDescription
PendingPendingOrder received, but not yet confirmed
ConfirmedConfirmedThe store confirmed the order
ProcessingProcessingPacking / preparing for shipment
ShippedShippedShipment complete (may be updated automatically via WMS integration)
DeliveredDeliveredDelivery to the customer complete (store POS pickup also transitions here)
CancelledCancelledOrder cancelled
RefundedRefundedRefund processing complete

1. Retrieve the order list

GET /api/v1/orders?organizationId={organizationId}&status=Pending
Authorization: Bearer {access_token}

Query parameters (optional)

  • status — filter by order status
  • channel — Web / POS / Phone / Manual / Marketplace
  • paymentStatus — Unpaid / Paid / Refunded / PartialRefund

The response is an array of order objects in orders. For the main fields of each object, see "Structure of the order object" below.

2. Retrieve the detail of one order

GET /api/v1/orders/{orderId}?organizationId={organizationId}
Authorization: Bearer {access_token}

3. Create a new order

POST /api/v1/orders?organizationId={organizationId}
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "orderNumber": "RR-2026-0002",
  "channel": "Phone",
  "customerName": "Hanako Sato",
  "customerEmail": "hanako@example.com",
  "customerPhone": "080-9876-5432",
  "shippingAddress": {
    "postalCode": "100-0001",
    "prefecture": "Tokyo",
    "city": "Chiyoda-ku",
    "line": "Chiyoda 1-1"
  },
  "items": [
    { "productId": "prd-002", "productName": "Iced tea", "sku": "TEA-ICE-001",
      "quantity": 3, "unitPrice": 380, "subtotal": 1140 }
  ],
  "paymentMethod": "BankTransfer",
  "paymentStatus": "Unpaid",
  "subtotalAmount": 1140,
  "taxAmount": 114,
  "shippingAmount": 500,
  "totalAmount": 1754,
  "linkedStoreId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "notes": "Phone order. Requests daytime delivery."
}

Points

  • Only customerName is required
  • Even if you include organizationId in the request body, it is ignored. The business account resolved from the token/query is always used
  • The initial status is always Pending. To advance the status, use the dedicated transition endpoints

4. Update an order

PUT /api/v1/orders/{orderId}?organizationId={organizationId}
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "customerName": "Hanako Sato",
  "customerPhone": "080-9876-5432",
  "shippingAddress": { "postalCode": "100-0001", "prefecture": "Tokyo",
                       "city": "Chiyoda-ku", "line": "Chiyoda 1-1-1 (address corrected)" },
  "items": [ ... ],
  "subtotalAmount": 1140, "taxAmount": 114, "shippingAmount": 500, "totalAmount": 1754
}

Points

  • Do not use this to change status. The rule is to update status via /confirm / /process / /cancel / /fulfill-via-pos (so that the operation type is recorded correctly in the audit log)
  • The linkedPosTransaction info attached by POS pickup cannot be updated via PUT either — only via the dedicated endpoint
  • Payment status (paymentStatus) can be updated
  • orderNumber and createdAt cannot be updated (protected on the server side)

5. Advance the status (confirm → processing → shipped, etc.)

Confirm (Pending → Confirmed)

POST /api/v1/orders/{orderId}/confirm?organizationId={organizationId}

Move to processing (Confirmed → Processing)

POST /api/v1/orders/{orderId}/process?organizationId={organizationId}

Cancel

POST /api/v1/orders/{orderId}/cancel?organizationId={organizationId}

The status transition endpoints return the complete, updated order object in the response.

* Transitions to shipped (Shipped) / delivered (Delivered) / refunded (Refunded) currently occur automatically via the WMS / payment system integration. If you want to trigger a transition directly from your app, let us know your use case in the community.

6. Pickup at the store POS (in-store handover of an online order)

This endpoint completes in a single operation the flow of: customer orders online → picks up at the store counter → pays at the register. It links the POS transaction and the OMS order to each other and transitions the order to Delivered + Paid at once.

POST /api/v1/orders/{orderId}/fulfill-via-pos?organizationId={organizationId}
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "posTerminalId": "term-001",
  "posTransactionId": "tx-9001"
}

Behavior

  • Records { terminalId, transactionId } in the OMS order's linkedPosTransaction
  • Records the order ID in the POS transaction's links.omsOrderId (reverse link)
  • Transitions the order status to Delivered
  • If the payment status is Unpaid, changes it to Paid and records paidAt (because it was paid at the register)
  • Adds a "FulfilledViaPos" entry to the timeline
  • The order-updated Webhook (order.updated) fires — the payload includes linked_pos_terminal_id and linked_pos_transaction_id

Idempotency

  • Calling again with the same posTransactionId for the same order ID has no side effects. Safe for retries / double taps

Error cases

  • Order / POS transaction not found → 404
  • The POS transaction is already linked to a different OMS order → 404 (prevents conflicts)
  • The POS transaction does not belong to this business account → 404 (cross-tenant defense)

Response example (part of the order object)

{
  "id": "ord-001",
  "status": "Delivered",
  "payment": { "method": "CreditCard", "status": "Paid", "paidAt": "2026-06-01T13:42:00Z" },
  "linkedStore": { "id": "f47ac10b-...", "name": "Shibuya store" },
  "linkedPosTransaction": {
    "terminalId": "term-001",
    "transactionId": "tx-9001"
  },
  ...
}

Usage scenario

  • Customer places a Pending order on the web → in the store's register app, POST /confirm → hand over the product → check out at the register → immediately after the POS transaction is recorded, POST /fulfill-via-pos from the register app
  • In the transaction list (Transactions API), both the POS row and the OMS row now hold links to each other, letting the UI control duplicate display

7. Delete an order

DELETE /api/v1/orders/{orderId}?organizationId={organizationId}
Authorization: Bearer {access_token}

The response is 204 No Content. Deleted orders disappear from list and search results.

Structure of the order object

{
  "id": "ord-001",
  "orderNumber": "RR-2026-0001",
  "channel": "Web",
  "status": "Pending",
  "customer": { "name": "...", "email": "...", "phone": "..." },
  "shippingAddress": { "postalCode": "...", "prefecture": "...", "city": "...", "line": "..." },
  "items": [ { "productId": "...", "productName": "...", "sku": "...",
               "quantity": 2, "unitPrice": 480, "subtotal": 960 } ],
  "itemCount": 2,
  "payment": { "method": "CreditCard", "status": "Paid", "paidAt": "..." },
  "amounts": { "subtotal": 960, "tax": 96, "shipping": 500, "discount": 0, "total": 1556 },
  "linkedStore": { "id": "...", "name": "..." },
  "linkedPosTransaction": null,        // if already picked up at store POS, { terminalId, transactionId }
  "notes": "...",
  "preOrder": { "isPreOrder": false, "targetShipDate": null },
  "createdAt": "...",
  "updatedAt": "..."
}

Structure of an item

{
  "productId": "prd-001",
  "productName": "Blend coffee M",
  "sku": "CFE-BLD-M",
  "quantity": 2,
  "unitPrice": 480,
  "subtotal": 960,
  "unit": "pc"
}

productId is the ID in the ReceiptRoller product master (retrievable via the Products API). For orders coming through a POS or an external e-commerce system, you can also send just productName + sku without a productId.

Typical flow (mobile app)

  1. Obtain an access token via OAuth → scopes include store.orders.read and store.orders.write
  2. Select a business account with GET /api/v1/me/organizations
  3. On the order dashboard screen, retrieve GET /api/v1/orders?status=Pending
  4. On the new-order screen, POST /api/v1/orders (first let the user pick products with GET /api/v1/products)
  5. "Confirm" button on the order detail screen → /confirm
  6. Packing staff "move to processing" → /process
  7. In the store's register app, "completed pickup at store" → specify the POS transaction ID and call /fulfill-via-pos
  8. Cancellation at the customer's request → /cancel

Error responses

StatusMeaningWhat to do
401 UnauthorizedAccess token invalid / expiredRe-obtain with the refresh token
403 ForbiddenMissing the required scope / not a member of the business accountCheck the scope and the selected business account
400 Bad RequestMissing required field (customerName / posTerminalId / posTransactionId) / empty bodyReview the request
404 Not FoundThe order ID does not exist in that business account / the POS transaction is not found in /fulfill-via-pos / already linked to another orderRe-fetch from the list; for a conflict, specify a different transaction

Related information

Published: 2026-06-01 Updated: 2026-07-05
このトピックについて
開発者API
機能の詳細を見る
Tags
API (22) OAuth (15) Android (10) iOS (9) Webhook (6) Troubleshooting (5) api (5) App registration (4) POS Integration (4) Reference (4)
Related articles