Skip to main content

Order

Base path: /api/data/order

POST /api/data/order

Create a new order. Subtotal, total, and discount amounts are computed server-side. If a discountCode is provided, the discount is validated and applied automatically.

Auth: Session cookie required Tenant: Scoped via x-tenant-id header

Request Body

FieldTypeRequiredDescription
orderNumberstringYesUnique order number
itemsarrayYesOrder line items (min 1)
currencystringNoISO 4217 currency code, 3 chars (default USD)
customerobjectYesCustomer info
customerIdstringNoAssociated customer record ID
customerRoleIdsstring[]NoCustomer's role IDs for discount eligibility
discountCodestringNoDiscount code to apply
shippingAddressobjectNoShipping address
statusenumNoInitial status override
shippingStatusenumNoInitial shipping status override
shipmentIdstringNoAssociated shipment ID
trackingNumberstringNoTracking number
notesstringNoOrder notes

Item object:

FieldTypeRequiredDescription
productIdstringYesProduct ID
namestringYesProduct name
skustringYesProduct SKU
quantitynumberYesQuantity (positive integer)
unitPriceCentsnumberYesUnit price in cents (non-negative integer)
currencystringNoCurrency code (default USD)

Customer object:

FieldTypeRequiredDescription
namestringYesCustomer name
emailstringNoCustomer email
discordIdstringNoCustomer Discord ID

Status values: PENDING_PAYMENT, PAID, FULFILLING, SHIPPED, COMPLETE, CANCELLED, REFUNDED

Shipping status values: PENDING, LABEL_CREATED, SHIPPED, DELIVERED, FAILED

Response (201)

Returns the created order record.

Errors

StatusCondition
400Validation error, DiscountError, or operation failure

GET /api/data/order/:id

Retrieve an order by ID.

Auth: Session cookie required Tenant: Scoped via x-tenant-id header

Response (200)

Returns the order record.

Errors

StatusCondition
400Operation error
404Order not found

PATCH /api/data/order/:id

Update an order by ID. All fields are optional.

Auth: Session cookie required Tenant: Scoped via x-tenant-id header

Request Body

FieldTypeRequiredDescription
statusenumNoUpdated order status
itemsarrayNoUpdated line items
subtotalCentsnumberNoUpdated subtotal
totalCentsnumberNoUpdated total
discountIdstringNoUpdated discount ID
discountCodestringNoUpdated discount code
discountAmountCentsnumberNoUpdated discount amount
taxAmountCentsnumberNoUpdated sales tax amount in cents
currencystringNoUpdated currency
customerobjectNoUpdated customer info
customerIdstringNoUpdated customer record ID
customerRoleIdsstring[]NoUpdated role IDs
shippingAddressobjectNoUpdated shipping address
shippingStatusenumNoUpdated shipping status
shipmentIdstringNoUpdated shipment ID
trackingNumberstringNoUpdated tracking number
notesstringNoUpdated notes

Response (200)

Returns the updated order record.

Errors

StatusCondition
400Validation error or operation failure

DELETE /api/data/order/:id

Remove an order by ID.

Auth: Session cookie required Tenant: Scoped via x-tenant-id header

Response (204)

No content.

Errors

StatusCondition
400Operation error

GET /api/data/order/open

Returns a paginated list of open orders for the authenticated admin's tenant.

Auth: Session cookie required + admin.access permission
Tenant: Derived from authenticated session; fails closed if missing

Query Parameters

ParameterTypeRequiredDescription
statusstringNoFilter to one open status: PENDING_PAYMENT, PAID, FULFILLING, SHIPPED
searchstringNoSubstring search on orderNumber
createdFromISO datetimeNoFilter orders created on or after this timestamp
createdToISO datetimeNoFilter orders created on or before this timestamp
pagenumberNoPage number (default: 1)
pageSizenumberNoRecords per page (default: 50, max: 200)

Response (200)

{
"items": [
{
"id": "string",
"orderNumber": "string",
"status": "PENDING_PAYMENT | PAID | FULFILLING | SHIPPED",
"shippingStatus": "PENDING | LABEL_CREATED | SHIPPED | DELIVERED | FAILED",
"totalCents": 1000,
"currency": "USD",
"customerName": "string",
"createdAt": "ISO date",
"updatedAt": "ISO date"
}
],
"page": 1,
"pageSize": 50,
"total": 42
}

Errors

StatusCondition
400Invalid query parameters
403Missing admin access or tenant context

GET /api/data/order/open/summary

Returns per-status open-order counts for the authenticated admin's tenant. Used by the dashboard summary cards.

Auth: Session cookie required + admin.access permission
Tenant: Derived from authenticated session; fails closed if missing

Response (200)

{
"totalOpen": 42,
"byStatus": {
"PENDING_PAYMENT": 10,
"PAID": 15,
"FULFILLING": 12,
"SHIPPED": 5
}
}

Errors

StatusCondition
403Missing admin access or tenant context

POST /api/orders/:id/invoice-link

Generates a public, time-limited pay-by-invoice link for an existing order. Merchant pastes the returned url into an email or message; the customer opens it in a browser to pay.

Auth: Session cookie required + admin.access permission
Tenant: Derived from authenticated session; fails closed if missing

Request Body

FieldTypeRequiredDescription
expiresInSecondsnumberNoToken validity window in seconds. Default: 604800 (7 days)

Response (200)

{
"url": "https://app.example.com/orders/invoice/<token>",
"token": "<base64url-hmac-token>",
"expiresAt": "2025-05-02T00:00:00.000Z"
}

Errors

StatusCondition
400Validation error
403Missing admin access or tenant context
404Order not found
503INVOICE_LINK_SIGNING_SECRET not configured

GET /orders/invoice/:token

Public (no authentication required). Verifies the HMAC-signed token, fetches the order, and renders an HTML invoice page with order summary and processor-backed payment buttons.

Auth: None — token is the credential
Tenant: Resolved from the signed token payload

Response (200)

Returns an HTML page containing:

  • Order number, customer name
  • Line items with unit price and subtotal
  • Discount row (when applicable)
  • Payment buttons for each processor-backed method the tenant has enabled (excludes VENMO_P2P, CASHAPP_P2P, ZELLE, CHIME, PAYPAL_MANUAL, BTC_MANUAL)

Errors

StatusCondition
404Token is invalid, expired, or tampered — returned for all failures to avoid leaking whether an order exists