Returns
After a debit settles, the payer's bank can still send it back with a return code: the account had too little money, was closed, or the payer says they did not authorize it. When the bank reports a return, SMP books it:
- the payment's status becomes
returnedand apayment.returnedevent is sent; - a return object records the code, its category (
nsf,adminorunauthorized) and the amount; - the return fee in force for your account is assessed and a
fee.assessedevent is sent;payment.returnedcarries it asreturn_fee_cents; - the amount and the fee come off your next payout. Your
merchant_balance_centscan go below zero for a while;available_centsnever does.
If SMP has turned Bounce Protection on for your account (an optional add-on, priced per account), a payment it covers that comes back R01 or R09 is paid back to you from SMP's reserve, up to the per-payment cap: payment.returned says covered: true and how much in covered_cents, and only the rest comes off your payout. The return fee is still charged. An unauthorized return is never covered.
Get a return
The response · 200
HTTP 200
Cache-Control: no-store
{
"data": {
"id": "cf78dfa0-3095-4c6b-aab7-e7fd7a67d3c0",
"object": "return",
"payment_id": "b17067cf-5562-4448-a039-3149a0ccd6cc",
"amount_cents": 4200,
"return_code": "R01",
"return_reason": "Insufficient Funds",
"category": "nsf",
"netted": false,
"netted_from_payout_id": null,
"evidence_url": null,
"covered": false,
"covered_cents": 0,
"external_order_id": "order_10485",
"returned_at": "2026-10-28T00:24:38.640Z",
"created_at": "2026-10-28T00:27:38.650Z"
}
}
Fees and your statement
Every fee amount on this page comes from example prices, not SMP's.
SMP's fee on a payment is its fee_cents. It comes out of what settles: the payer is debited exactly amount_cents and the payment pays you net_cents. A declined or voided payment never settles, so its fee is never charged.
A fee charged outside a payment, such as the return fee, is a fee assessment. GET / lists them, each with the rule that priced it and the payout that netted it; GET / shows the rules in force for your account. A rule that is not active is never charged.
Fees charged outside a payment
The response · 200
HTTP 200
Cache-Control: no-store
{
"data": [
{
"id": "fa:return:ret_sbt_e9fa3956-1381-4f03-9a17-50e7ff8ed218",
"object": "fee_assessment",
"code": "return",
"amount_cents": 1200,
"base_amount_cents": 4200,
"rule": {
"source": "schedule",
"basis": "fixed",
"bps": null,
"fixed_cents": 1200,
"min_cents": null,
"max_cents": null
},
"payment_id": "b17067cf-5562-4448-a039-3149a0ccd6cc",
"return_id": "cf78dfa0-3095-4c6b-aab7-e7fd7a67d3c0",
"refund_id": null,
"period": null,
"netted": false,
"netted_from_payout_id": null,
"assessed_at": "2026-10-28T00:27:38.650Z"
},
{
"id": "fa:payout.instant:7b6d615c-b239-44a0-b13d-fc2507da24ab",
"object": "fee_assessment",
"code": "payout.instant",
"amount_cents": 110,
"base_amount_cents": 10964,
"rule": {
"source": "schedule",
"basis": "bps",
"bps": 100,
"fixed_cents": null,
"min_cents": 25,
"max_cents": null
},
"payment_id": null,
"return_id": null,
"refund_id": null,
"period": null,
"netted": true,
"netted_from_payout_id": "7b6d615c-b239-44a0-b13d-fc2507da24ab",
"assessed_at": "2026-10-28T00:24:38.631Z"
},
… 4 more
],
"pagination": {
"total": 6,
"limit": 25,
"offset": 0,
"has_more": false
}
}
GET / gives one month line by line: each settled payment with its fee, each refund, payout, return and assessed fee, and the balance after each.
This month's statement
The response · 200
HTTP 200
Cache-Control: no-store
{
"data": {
"object": "statement",
"month": "2026-10",
"period_start": "2026-10-01T00:00:00.000Z",
"period_end": "2026-11-01T00:00:00.000Z",
"opening_balance_cents": 0,
"closing_balance_cents": -5400,
"fees": {
"per_payment_cents": 176,
"assessed": [
{
"code": "bank_verification",
"count": 2,
"cents": 200
},
{
"code": "merchant.batch",
"count": 1,
"cents": 40
},
… 3 more
],
"assessed_cents": 1570
},
"bounce_protection": {
"fees_cents": 0,
"covers_cents": 0
},
"lines": [
{
"at": "2026-10-28T00:22:35.486Z",
"type": "fee_assessed",
"description": "Fee bank_verification: 100 cents",
"credit_cents": 0,
"debit_cents": 100,
"balance_after_cents": -100,
"payment_id": null,
"payout_id": null,
"return_id": null,
"refund_id": null,
"fee_assessment_id": "fa:bank_verification:1357923a-53e2-4aa9-a547-a20155759d6c",
"fee_collection_id": null,
"invoice_id": null,
"fee_code": "bank_verification"
},
{
"at": "2026-10-28T00:22:35.532Z",
"type": "fee_assessed",
"description": "Fee bank_verification: 100 cents",
"credit_cents": 0,
"debit_cents": 100,
"balance_after_cents": -200,
"payment_id": null,
"payout_id": null,
"return_id": null,
"refund_id": null,
"fee_assessment_id": "fa:bank_verification:33746dac-4666-4b2a-9c31-6d3ce13afdc5",
"fee_collection_id": null,
"invoice_id": null,
"fee_code": "bank_verification"
},
… 9 more
],
"fee_collections": []
}
}
What payouts can't cover
Fees and returns come off your payouts first. What they can't cover, such as a balance gone negative after returns, is debited from your payout account on your payout day, under an authorization you accept once: GET / gives the exact words and PUT / records your signer's acceptance. GET / lists those debits. A debit returned for insufficient or uncollected funds is tried again for the same amount, at most twice. Any other return ends the authorization, and an unauthorized one also suspends the merchant account.
Debits from your own account
The response · 200
HTTP 200
Cache-Control: no-store
{
"data": [
{
"id": "fc_d7dfee96-ee3a-4a4b-96f5-bb17919f1b76",
"object": "fee_collection",
"status": "submitted",
"amount_cents": 3198,
"entry_code": "CCD",
"same_day": true,
"attempt_kind": "initial",
"reinitiates_collection_id": null,
"return_code": null,
"failure_reason": null,
"created_at": "2026-11-03T15:00:00.778Z",
"submitted_at": "2026-11-03T15:00:00.778Z",
"settled_at": null,
"returned_at": null
}
],
"pagination": {
"total": 1,
"limit": 25,
"offset": 0,
"has_more": false
}
}
Evidence for unauthorized returns
When a payer says a debit was not authorized, the return gets an evidence packet: the return, the payment, the authorization the payer agreed to (its exact words, time, IP address and browser), and the bank account's details. Fetch it with GET /. Returns in other categories have none and answer 404.
An unauthorized return's evidence packet
The response · 200
HTTP 200
Cache-Control: private, no-store
{
"return": {
"id": "e1c07144-04d7-4196-9b40-4d528eb48f74",
"code": "R10",
"reason": "Customer Advises Not Authorized",
"returned_at": "2026-10-28T00:23:38.732Z"
},
"payment": {
"id": "3078ebdd-da4d-492a-9050-f2bcc55a14ea",
"amount_cents": 3300,
"entry_code": "WEB",
"statement_descriptor": "LAKESIDE",
"external_order_id": "order_20311",
"created_at": "2026-10-28T00:22:37.714Z",
"settled_at": "2026-10-28T00:23:37.717Z"
},
"authorization": {
"authorization_text": "By completing this payment, you authorize Lakeside Outfitters to initiate a one-time electronic debit of $33.00 from your bank account ending in 9606. You may revoke this authorization at any time by contacting Lakeside Outfitters, with the understanding that it may take up to 3 business days to process.",
"ip_address": "203.0.113.7",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6) AppleWebKit/605.1.15 Safari/605.1.15",
"consent_timestamp": "2026-10-28T00:22:37.714Z",
"entry_code": "WEB",
"frequency": "one_time",
"expires_at": "2028-10-27T12:22:37.714Z"
},
"bank_account": {
"last_four": "9606",
"owner_name": "Riley Ng",
"link_method": "sandbox",
"identity_match_score": null,
"verified_at": "2026-10-28T00:22:37.706Z"
}
}
Return rates
SMP measures your return rates every day on Nacha's 60-day method: the returns of the last 60 days against the debits sent to the bank in them, for unauthorized returns, administrative returns (R02, R03, R04) and all returns. GET / shows yours.
- Unauthorized returns at 0.3% of your debits suspend your merchant account at once: new payments and payouts are refused with
403 forbidden, while refunds and voids still work. - At the critical level your per-payment and daily limits are halved, and every payment above $200 waits for SMP's review.
- At Nacha's own limits (0.5% unauthorized, 3% administrative, 15% of all debits) your account is suspended.
With fewer than 20 debits in the 60 days, one return is a large share, so the number of returns sets a step instead: one return sends a warning email, two halve your limits, three pause new payments. Each step lifts on its own as returns age past 60 days. An unauthorized return still suspends the account at any volume.
Return codes
| Code | Meaning | Category | What to do |
|---|---|---|---|
R01 | Insufficient Funds | nsf | Ask the customer to pay again with a new payment once the funds are there; SMP does not re-present a returned debit |
R02 | Account Closed | admin | Request new bank account from customer |
R03 | No Account/Unable to Locate | admin | Verify account number with customer |
R04 | Invalid Account Number | admin | Re-link bank account via Plaid |
R05 | Unauthorized Debit (Corporate) | unauthorized | Evidence packet — verify authorization was obtained |
R07 | Authorization Revoked | unauthorized | Do not re-debit. Evidence packet if disputed. |
R08 | Payment Stopped | admin | Contact customer to resolve |
R09 | Uncollected Funds | nsf | Ask the customer to pay again with a new payment once the deposit has cleared; SMP does not re-present a returned debit |
R10 | Customer Advises Not Authorized | unauthorized | Evidence packet — identity match and the authorization record with its exact words |
R11 | Customer Advises Entry Not in Accordance with the Terms of the Authorization | unauthorized | Evidence packet — show the debit matched the authorization; do not re-debit without a corrected authorization |
R16 | Account Frozen | admin | Request alternative payment method |
R20 | Non-Transaction Account | admin | Request checking account instead |
R29 | Corporate Customer Not Authorized | unauthorized | Evidence packet. Verify authorization with corporate customer. |
R51 | Item Related to RCK Entry is Ineligible | unauthorized | Do not re-present |
Payouts
A payout sends your released balance to the bank account on your merchant account, net of returns and fees not yet netted. Payouts run on the schedule SMP sets for your account: every Fed business day, weekly or every two weeks on a weekday (Tuesday unless set otherwise), monthly on the 1st, or only when you ask. A payout day on a weekend or a Fed holiday goes out on the next Fed business day; GET / shows yours. An early payout now ("Pay me now"), with POST / and an Idempotency-Key, is off until SMP turns it on for your account, and it carries the early payout fee in your fee schedule. On the only-when-you-ask schedule, a payout you ask for carries no fee. Each payout lists how many payments it includes and how much it netted for returns and for fees, and sends payout.initiated, then payout.settled or payout.failed.
Pay out the available balance now
The response · 201
HTTP 201
Cache-Control: no-store
{
"data": {
"id": "7b6d615c-b239-44a0-b13d-fc2507da24ab",
"object": "payout",
"status": "submitted",
"amount_cents": 10964,
"fee_cents": 110,
"net_cents": 10854,
"returns_netted_cents": 0,
"fees_netted_cents": 370,
"fees_included": 5,
"method": "ach_credit",
"trigger": "manual",
"payments_included": 2,
"returns_included": 0,
"period_start": "2026-10-28T00:22:34.395Z",
"period_end": "2026-10-28T00:24:38.631Z",
"initiated_at": "2026-10-28T00:24:38.631Z",
"settled_at": null,
"failed_reason": null
}
}
Holds
Every day SMP reconciles its ledger with the bank's, to the cent. Any difference puts payouts on hold until it is resolved; while a hold is on, a payout answers 422 payout_held and payout_hold on your balance says why.
SMP staff can also keep part of your balance back as a reserve, or delay when your payments are released. Neither is ever set automatically: each is recorded with who set it and why, and your balance shows what a reserve holds in reserve_held_cents.
Balance after the return
The response · 200
HTTP 200
Cache-Control: no-store
{
"data": {
"object": "balance",
"available_cents": 0,
"merchant_balance_cents": -5400,
"held_cents": 0,
"reserve_held_cents": 0,
"pending_cents": 0,
"unnetted_return_cents": 4200,
"unnetted_fee_cents": 1200,
"pending_payout_cents": 0,
"payout_hold": {
"active": false
},
"currency": "USD",
"as_of": "2026-10-28T00:22:36.681Z"
}
}
