Skip to main content

Record Sales Order Payment

POST 

/api/sales-orders/:salesOrderId/payments

Record a manual payment against a sales order and recalculate the order's payment_status.

Required scope: orders:write

Grant this scope to your token under Settings → Developer → Personal Access Tokens.

Request body:

  • payment_type_id (integer, required) — must exist in payment_types.
  • amount (numeric, required, < 100,000,000) — positive records a payment; negative records a refund (creates a Refund sales credit and a matching positive payment against it); an amount exceeding the order balance creates an Overpayment sales credit for the excess.
  • payment_date (date, optional) — defaults to today (Y-m-d) when omitted.
  • external_reference (string, optional, max 255) — e.g. a cheque or transaction number.
  • currency_id (integer, optional) — defaults to the sales order's currency when omitted.

Duplicate handling: payments are unique on (payment_type_id, external_reference). Re-submitting an identical payment for the same order is idempotent (the existing payment is returned, no duplicate created). Reusing the same type+reference for a different payment (different owner/amount/date) returns 422 with an external_reference error — it no longer 500s.

Validation: returns 422 if the order is already fully paid (positive amount), or if a refund exceeds the amount already paid.

Authentication: Requires Bearer token.

Requires permission: sales_orders.manage_payments

Request

Responses

OK

Response Headers
    Content-Type