A test bank inside the platform
The sandbox runs the same code as the live API with one difference: the bank is a test bank inside the platform, so nothing reaches a real bank. Use keys that start sk_sandbox_ on https://; yours comes from the first page of the free application (Going live). The calls on this page exist only there and answer 404 on the live API.
The test bank keeps its own clock per merchant: it settles a debit 60 seconds after it was submitted and reports a return 120 seconds after settlement. These are sandbox timings only.
Test bank accounts
Link a test account for any payer email with POST /. available_balance_cents sets the balance the risk checks read, so a balance below the amount produces a decline.
Link a sandbox test bank account
curl -X POST https://sandbox.socialmatterspay.com/v1/bank-accounts/sandbox-link \
-H 'Authorization: Bearer sk_sandbox_…' \
-H 'Content-Type: application/json' \
-d '{
"payer_email": "ana.lopez@example.com",
"payer_name": "Ana Lopez",
"available_balance_cents": 250000
}'
The response · 201
HTTP 201
Cache-Control: no-store
{
"data": {
"id": "1357923a-53e2-4aa9-a547-a20155759d6c",
"object": "bank_account",
"payer_id": "6427de75-801c-4ac6-95fa-870665d10af3",
"account_type": "checking",
"bank_name": "Plaid Checking (sandbox)",
"last_four": "9606",
"owner_name": "Ana Lopez",
"link_method": "sandbox",
"status": "verified",
"identity_match_score": null,
"signal_score": null,
"verified_at": "2026-10-28T00:22:35.485Z",
"disconnected_at": null,
"is_tokenized": false,
"item_health": "ok",
"consent_expires_at": null,
"disconnect_at": null,
"debit_block": null,
"owner_changed_from": null,
"created_at": "2026-10-28T00:22:35.485Z",
"available_balance_cents": 250000
}
}
Move the clock
POST / moves your sandbox clock forward by up to 7,776,000 seconds (90 days) and runs everything that falls due: settlements, releases, returns and payouts.
Move the sandbox clock 61 seconds
curl -X POST https://sandbox.socialmatterspay.com/v1/sandbox/advance \
-H 'Authorization: Bearer sk_sandbox_…' \
-H 'Content-Type: application/json' \
-d '{
"seconds": 61
}'
The response · 200
HTTP 200
Cache-Control: no-store
{
"data": {
"object": "sandbox_clock",
"offset_seconds": 61,
"now": "2026-10-28T00:23:36.567Z",
"returns_processed": 0,
"balances": {
"settlement_cents": 8400,
"merchant_balance_cents": 8051,
"fee_revenue_cents": 349,
"held_cents": 0,
"pending_cents": 0,
"reserve_held_cents": 0,
"payable_cents": 8051
}
}
}
Pay an invoice
Send money to an invoice's account as its customer would with POST /. An ACH credit lands after the settle delay, so move the clock and then read the invoice; an instant payment lands at once. See Invoices.
Other things a bank does
A payer's bank correcting an account with a notice of change (POST /), your bank sending a payout back (POST /), and your bank returning a debit of what your payouts didn't cover (POST /). Each is booked on the next scan or clock move, with the fee your schedule sets for it.
Make a return happen
Two ways. Pay an amount whose cents match the table below and the test bank returns it with that code after it settles. Or return any settled debit now with POST /; the return is booked on the next clock move.
| Amount ends in | Returned with | Meaning |
|---|---|---|
….01 | R01 | Insufficient Funds |
….02 | R02 | Account Closed |
….03 | R03 | No Account/Unable to Locate |
….05 | R05 | Unauthorized Debit (Corporate) |
….07 | R07 | Authorization Revoked |
….08 | R08 | Payment Stopped |
….09 | R09 | Uncollected Funds |
….10 | R10 | Customer Advises Not Authorized |
….29 | R29 | Corporate Customer Not Authorized |
Make the payer's bank return a debit
curl -X POST https://sandbox.socialmatterspay.com/v1/sandbox/return \
-H 'Authorization: Bearer sk_sandbox_…' \
-H 'Content-Type: application/json' \
-d '{
"payment_id": "b17067cf-5562-4448-a039-3149a0ccd6cc",
"code": "R01"
}'
The response · 202
HTTP 202
Cache-Control: no-store
{
"data": {
"object": "sandbox_bank_return",
"payment_id": "b17067cf-5562-4448-a039-3149a0ccd6cc",
"return_code": "R01",
"returned_at": "2026-10-28T00:24:38.640Z",
"booked": false
}
}
