Skip to main content

Payments

POST /v1/payments records money a customer paid you and issues the receipt in one call. There is no draft step: an issued payment is never cancelled, and money going back to the customer is a credit note.

Required fields​

Every request sends customerId, branchId, paymentMethodId and amount. amount is above 0 with at most two decimals.

branchId is the branch that received the money. The payment method posts to the treasury set for that branch, or to the method's default treasury when the branch has none. If that treasury serves only another branch, the payment would be recorded there, so it is refused with 422 payment_method_not_in_branch.

date is optional and defaults to today in Saudi time. A past date is accepted unless the merchant has closed that accounting period (422 period_locked), or it is before an invoice the payment settles (400 invalid_parameter on date).

notes takes up to 500 characters and referenceId up to 100.

Allocations​

allocations says which invoices the payment settles, up to 100 of them:

{
"customerId": "3f1c2a6e-8b4d-4e2a-9c1f-5d7e8a9b0c12",
"branchId": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
"paymentMethodId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"amount": 150,
"allocations": [{ "invoiceId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e", "amount": 115 }]
}
RuleError
The allocations add up to no more than amount400 invalid_parameter on allocations
An invoice appears once400 invalid_parameter on allocations[i].invoiceId
The invoice exists, is an issued sales invoice of this customer, and is in a branch your key may use422 invoice_not_payable on allocations[i].invoiceId
The payment's date is not before the invoice's400 invalid_parameter on date
The amount is no more than the invoice still owes422 allocation_exceeds_due on allocations[i].amount

Whatever the allocations leave, or the whole amount when you send none, stays as the customer's credit. The reply shows it as unallocatedAmount. After the call, the invoice's amountPaid and amountDue in GET /v1/sales-invoices/{id} include the allocation.

A key limited to some branches settles only invoices of those branches

A key limited to some branches can allocate a payment only to invoices issued in those branches. An invoice from any other branch answers 422 invoice_not_payable, exactly like an invoice id that does not exist, so the key learns nothing about it.

To settle an invoice of another branch, record the payment with a key that may use that branch.

Other refusals​

ErrorWhen
422 referenced_resource_not_foundthe customer, the branch or the payment method does not exist, or the payment method is disabled; param names the field
422 customer_inactivethe customer is disabled
422 payment_method_not_in_branchthe payment method's treasury serves another branch
409 invoice_busy on allocations[i].invoiceIdanother request on that invoice held it for more than 30 seconds; send the request again
409 invoice_busy with no paramother payments were being recorded for more than 30 seconds; send the request again
409 reference_id_takenanother payment already has this referenceId; existingId names it when your key may read it
422 payment_not_recordeda business rule with no code of its own refused the payment; the message names the rule

A refused payment records nothing.

Reading payments​

GET /v1/payments lists every issued payment in the key's branches, whichever channel recorded it. createdVia says which. Filter with customerId, branchId, invoiceId, referenceId, dateFrom and dateTo; invoiceId returns the payments with an allocation to that invoice.

The list includes a payment taken with a sale (POST /v1/sales-invoices with payment) to a company customer. A sale to a person paid at issue keeps the money on the invoice: its amountPaid shows it, and no payment is created.

A payment recorded on the dashboard can carry a settlement discount: debt the merchant forgave on top of the money. The reply shows it as discount, and its allocations can add up to amount plus discount. unallocatedAmount is amount plus discount, less the allocations. A payment recorded through the API always has a discount of 0.

A payment recorded with no branch has branchId: null, and only a key with every branch sees it.