The line
Every payment holds exactly one status at a time and only ever moves forward. declined, returned, voided and refunded are final: nothing moves a payment out of them.
Statuses
| Status | What it means |
|---|---|
| pending_authorization | Created; the risk checks are running. You will rarely see it, because they finish inside the create request. |
| authorized | The risk checks passed. The debit is about to be sent to the bank. |
| submitted | The debit was sent to the payer's bank. It can still be voided. |
| settled | The bank settled the debit and the money is on the ledger. Held until release_after if your agreement holds payments. |
| released | Counted in your available balance; it goes out in your next payout. |
| paid_out | Included in a payout that settled. |
| declined | Stopped by the risk checks. It was never sent to the bank. decline_reason is a fixed code and decline_message a sentence you can show the payer. |
| returned | The payer's bank sent the debit back. Its amount comes off your next payout. |
| voided | You cancelled it before the bank settled the debit. |
| refunded | Refunded in full. Partial refunds leave the status as it was and raise refunded_cents. |
Read every change a payment went through, with its time, from GET /. Each move also sends a signed event.
Checked before any debit
A payment taken on a website or by phone (WEB, TEL) first needs the payer's authorization: the words from POST /, shown before they agree, and the SHA-256 of exactly those words sent with the payment. Then the risk checks run inside the create request, before anything is sent to the payer's bank:
- your per-payment, daily and monthly limits;
- velocity: 3 payments per payer per hour, 5 per payer per day, $5,000 per payer per day, and 30 per merchant per minute;
- the payer's available balance, wherever a live balance can be read;
- your merchant account's return rates.
You can let one payer past the soft checks, such as the velocity limits or a weak name match, with POST /. It never lifts your own limits, the unauthorized-return pause, a balance known to be short, or an unauthorized return by that payer.
While your return rates are at the critical level, a payment above $200 waits for SMP's review before any debit: it is answered 201 and stays pending_authorization until SMP approves it (payment.authorized follows) or declines it (payment.declined).
A payment the checks stop comes back with status declined, a fixed decline_reason code and a decline_message you can show the payer; the checks' own reasons, such as the payer's balance or history, are never sent. A declined payment is recorded so you can show it, but it is never sent to the bank and never paid. A payment that passes comes back submitted: the debit is on its way to the payer's bank.
Declined before any debit (balance below the amount)
The response · 201
HTTP 201
Cache-Control: no-store
{
"data": {
"id": "482e84e1-2393-4048-bde9-465edf0a38d1",
"object": "payment",
"status": "declined",
"amount_cents": 8400,
"fee_cents": 109,
"net_cents": 8291,
"refunded_cents": 0,
"currency": "USD",
"entry_code": "WEB",
"payer_id": "500d25bc-a844-4e3c-a460-04e971508a0b",
"bank_account_id": "33746dac-4666-4b2a-9c31-6d3ce13afdc5",
"statement_descriptor": "NORTHWIND",
"external_order_id": "order_10483",
"metadata": null,
"risk_score": 0,
"decline_reason": "insufficient_funds",
"decline_message": "The bank account does not have enough available to cover this payment.",
"bank_reference": null,
"payout_id": null,
"return_id": null,
"override_id": null,
"site_id": null,
"release_after": null,
"created_at": "2026-10-28T00:22:35.538Z",
"submitted_at": null,
"settled_at": null,
"released_at": null,
"paid_out_at": null
}
}
Void or refund
Until the bank settles the debit you can void the payment with POST /; after that the void answers 409 too_late_to_void. Once it has settled you refund it instead, in full or in part, with POST /. Partial refunds raise refunded_cents and leave the status alone; the payment becomes refunded when the whole amount has been refunded. A refund larger than what remains answers 422 refund_exceeds_payment.
Refund part of a payment
curl -X POST https://sandbox.socialmatterspay.com/v1/payments/3c8029c9-00de-481f-aff2-4e80839dea08/refund \
-H 'Idempotency-Key: refund_order_10482_1' \
-H 'Authorization: Bearer sk_sandbox_…' \
-H 'Content-Type: application/json' \
-d '{
"amount_cents": 1200,
"reason": "One item out of stock"
}'
The response · 201
HTTP 201
Cache-Control: no-store
{
"data": {
"id": "aa7af452-4b99-49a1-9c61-630bccadbb36",
"object": "refund",
"payment_id": "3c8029c9-00de-481f-aff2-4e80839dea08",
"amount_cents": 1200,
"reason": "One item out of stock",
"status": "submitted",
"failure_reason": null,
"created_at": "2026-10-28T00:23:37.591Z",
"settled_at": null
}
}
What the payer's statement says
The payer's bank statement shows SMS* followed by your statement descriptor: up to 12 characters of letters, digits, spaces and . & -. Set a default when you apply, or send statement_descriptor on a payment.
