Using the Orders / OMS API
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
| Method | Path | Purpose | Required scope |
|---|---|---|---|
| GET | /api/v1/orders | List orders (filter by status / channel / paymentStatus) | store.orders.read |
| GET | /api/v1/orders/{orderId} | Detail of one order | store.orders.read |
| POST | /api/v1/orders | Create a new order | store.orders.write |
| PUT | /api/v1/orders/{orderId} | Update an order (customer, address, line items, amounts, etc.) | store.orders.write |
| POST | /api/v1/orders/{orderId}/confirm | Status transition: Pending → Confirmed | store.orders.write |
| POST | /api/v1/orders/{orderId}/process | Status transition: Confirmed → Processing | store.orders.write |
| POST | /api/v1/orders/{orderId}/cancel | Status transition: cancel | store.orders.write |
| POST | /api/v1/orders/{orderId}/fulfill-via-pos | Status transition: completed pickup at store POS (→ Delivered) | store.orders.write |
| DELETE | /api/v1/orders/{orderId} | Delete an order | store.orders.write |
Order status values
| Status | Label | Description |
|---|---|---|
Pending | Pending | Order received, but not yet confirmed |
Confirmed | Confirmed | The store confirmed the order |
Processing | Processing | Packing / preparing for shipment |
Shipped | Shipped | Shipment complete (may be updated automatically via WMS integration) |
Delivered | Delivered | Delivery to the customer complete (store POS pickup also transitions here) |
Cancelled | Cancelled | Order cancelled |
Refunded | Refunded | Refund 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 statuschannel— Web / POS / Phone / Manual / MarketplacepaymentStatus— 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
customerNameis required - Even if you include
organizationIdin 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
linkedPosTransactioninfo attached by POS pickup cannot be updated via PUT either — only via the dedicated endpoint - Payment status (
paymentStatus) can be updated orderNumberandcreatedAtcannot 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'slinkedPosTransaction - 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 toPaidand recordspaidAt(because it was paid at the register) - Adds a "FulfilledViaPos" entry to the timeline
- The order-updated Webhook (
order.updated) fires — the payload includeslinked_pos_terminal_idandlinked_pos_transaction_id
Idempotency
- Calling again with the same
posTransactionIdfor 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
Pendingorder 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-posfrom 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)
- Obtain an access token via OAuth → scopes include
store.orders.readandstore.orders.write - Select a business account with
GET /api/v1/me/organizations - On the order dashboard screen, retrieve
GET /api/v1/orders?status=Pending - On the new-order screen,
POST /api/v1/orders(first let the user pick products withGET /api/v1/products) - "Confirm" button on the order detail screen →
/confirm - Packing staff "move to processing" →
/process - In the store's register app, "completed pickup at store" → specify the POS transaction ID and call
/fulfill-via-pos - Cancellation at the customer's request →
/cancel
Error responses
| Status | Meaning | What to do |
|---|---|---|
| 401 Unauthorized | Access token invalid / expired | Re-obtain with the refresh token |
| 403 Forbidden | Missing the required scope / not a member of the business account | Check the scope and the selected business account |
| 400 Bad Request | Missing required field (customerName / posTerminalId / posTransactionId) / empty body | Review the request |
| 404 Not Found | The order ID does not exist in that business account / the POS transaction is not found in /fulfill-via-pos / already linked to another order | Re-fetch from the list; for a conflict, specify a different transaction |
Related information
-
Using the Store Information APIA guide to the REST API for fetching and updating a store's basic information (store name, store type, contact details, and address). Lets you implement a store information editing screen from token-authenticated clients such as staff apps.
-
PosTransactionDto specification — field reference for transaction dataA complete field reference for PosTransactionDto, the canonical model for the transaction data ReceiptRoller handles. For each category — identifiers, dates, amounts, line items, payments, staff, status, and CRM linkage — it summarizes the field names, types, meanings, and how each POS vendor populates them. A reference for developers and external-system integrators. Also referenced from the Smaregi and Square mapping articles.
-
Purchase and receipt data integrationExplains the structure of the purchase and receipt data ReceiptRoller handles, how to retrieve it, related scopes, Webhooks, and common use cases.
-
Using the Business Hours APIA guide to ReceiptRoller's Business Hours API (/api/v1/stores/{storeId}/business-hours). Covers retrieving and updating per-day business hours, registering special business days (temporary closures and hour changes), configuring a store's workable hours (the upper bound for shift creation), and determining whether the store is currently open.
-
Representative API examplesIntroduces, as curl commands, examples of calling the representative ReceiptRoller API endpoints (retrieving receipts, listing stores, creating products, registering Webhooks).