Before you start
You need curl, an HTTPS address that can receive a POST for step 4, and a sandbox key from step 1. Every response below is the one the sandbox returned when these exact requests ran; IDs and times will differ on yours, and the secrets are placeholders.
fee_cents on a payment is SMP's fee, from the fee rules in force for your account (GET /); in these examples it is worked out from example prices, not SMP's. The payer is debited exactly amount_cents; the payment pays you net_cents.
Nine steps
Get a sandbox key
Apply free at
https://. When you finish the first page (your business, and the one website or app you will use the API on), the page shows your sandbox key once, with a copy button: store it now, it is not shown again. The rest of the application can wait until you want to go live; Going live has the steps.onboard. socialmatterspay. com/ apply/ Create the payer
A payer is the person paying. There is one payer per email for your merchant account, so creating one for an email you already used returns the same payer with
200instead of201.Create a payer
curl -X POST https://sandbox.socialmatterspay.com/v1/payers \ -H 'Authorization: Bearer sk_sandbox_…' \ -H 'Content-Type: application/json' \ -d '{ "email": "ana.lopez@example.com", "name": "Ana Lopez" }'The response · 201
HTTP 201 Cache-Control: no-store { "data": { "id": "6427de75-801c-4ac6-95fa-870665d10af3", "object": "payer", "email": "ana.lopez@example.com", "name": "Ana Lopez", "phone": null, "created_at": "2026-10-28T00:22:35.474Z" } }Reference: Create the payer for an email, or return the existing one
Link a sandbox bank account
In the sandbox you can link a test bank account without a bank sign-in.
available_balance_centssets the balance the risk checks will see, so you can test a decline by setting it below the amount. Live accounts are linked through Plaid's bank sign-in instead (POST/and POSTv1/ bank-accounts/ link-token /).v1/ bank-accounts/ exchange 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 } }Reference: Sandbox only — link Plaid's documented test checking account without Plaid keys
Subscribe to events
Subscribe an HTTPS endpoint before you pay, so the payment's events reach it. The response carries the signing secret once; you need it to verify every delivery.
Subscribe to events
curl -X POST https://sandbox.socialmatterspay.com/v1/webhooks \ -H 'Authorization: Bearer sk_sandbox_…' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://northwind.example/smp/webhooks", "events": [ "payment.authorized", "payment.settled", "payment.released", "payment.declined", "payment.returned", "payout.initiated", "payout.settled", "fee.assessed" ] }'The response · 201
HTTP 201 Cache-Control: no-store { "data": { "id": "a4602568-d7c4-46ee-9f8b-b7d99c853837", "object": "webhook_subscription", "url": "https://northwind.example/smp/webhooks", "events": [ "payment.authorized", "payment.settled", … 6 more ], "active": true, "site_id": null, "secret": "whsec_…", "created_at": "2026-10-28T00:22:34.449Z" } }Reference: Subscribe an HTTPS URL to events
Show the payer the authorization
Before a payer agrees to a debit taken on a website, show them the authorization: the exact words this call returns, in readable type, next to the button they press. They name your business, the amount and the last four digits of the account. Keep
text_sha256: the payment sends it to prove which words were shown.The words to show the payer
curl -X POST https://sandbox.socialmatterspay.com/v1/payments/authorization-text \ -H 'Authorization: Bearer sk_sandbox_…' \ -H 'Content-Type: application/json' \ -d '{ "bank_account_id": "1357923a-53e2-4aa9-a547-a20155759d6c", "amount_cents": 8400, "entry_code": "WEB" }'The response · 200
HTTP 200 Cache-Control: no-store { "data": { "object": "payment_authorization_text", "text": "By completing this payment, you authorize Northwind Supply to initiate a one-time electronic debit of $84.00 from your bank account ending in 9606. You may revoke this authorization at any time by contacting Northwind Supply, with the understanding that it may take up to 3 business days to process.", "text_sha256": "85916f0096d185117093d29466e05b4a3a9baca8e4fc5b4bcfd467f691f035dc", "merchant_name": "Northwind Supply", "amount_cents": 8400, "amount_description": "$84.00", "entry_code": "WEB", "frequency": "single", "bank_account": { "id": "1357923a-53e2-4aa9-a547-a20155759d6c", "bank_name": "Plaid Checking (sandbox)", "last_four": "9606" }, "ach_company": null } }Reference: The exact authorization words to show the payer before a debit
Create the payment
Send the bank account, the amount in cents, and an
Idempotency-Key(your order number works well). For a payment taken on a website (entry_codeWEB) also send the payer's IP address and browser from the checkout, andauthorization_text_sha256from step 5; without it the payment is refused with422 authorization_requiredbefore anything is stored. The risk checks run before the bank is called: this payment passed them, so it came backsubmitted.Create a payment
curl -X POST https://sandbox.socialmatterspay.com/v1/payments \ -H 'Idempotency-Key: order_10482' \ -H 'Authorization: Bearer sk_sandbox_…' \ -H 'Content-Type: application/json' \ -d '{ "bank_account_id": "1357923a-53e2-4aa9-a547-a20155759d6c", "amount_cents": 8400, "payer_id": "6427de75-801c-4ac6-95fa-870665d10af3", "entry_code": "WEB", "external_order_id": "order_10482", "payer_ip": "203.0.113.7", "payer_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6) AppleWebKit/605.1.15 Safari/605.1.15", "metadata": { "cart_id": "c_7731" }, "authorization_text_sha256": "85916f0096d185117093d29466e05b4a3a9baca8e4fc5b4bcfd467f691f035dc" }'The response · 201
HTTP 201 Cache-Control: no-store { "data": { "id": "3c8029c9-00de-481f-aff2-4e80839dea08", "object": "payment", "status": "submitted", "amount_cents": 8400, "fee_cents": 109, "net_cents": 8291, "refunded_cents": 0, "currency": "USD", "entry_code": "WEB", "payer_id": "6427de75-801c-4ac6-95fa-870665d10af3", "bank_account_id": "1357923a-53e2-4aa9-a547-a20155759d6c", "statement_descriptor": "NORTHWIND", "external_order_id": "order_10482", "metadata": { "cart_id": "c_7731" }, "risk_score": 65, "decline_reason": null, "decline_message": null, "bank_reference": "sbt_98eecba8-0048-4a1d-83c0-385f4ac6b04a", "payout_id": null, "return_id": null, "override_id": null, "site_id": null, "release_after": null, "created_at": "2026-10-28T00:22:35.514Z", "submitted_at": "2026-10-28T00:22:35.514Z", "settled_at": null, "released_at": null, "paid_out_at": null } }Move the sandbox clock
The sandbox bank settles a debit 60 seconds after it was submitted. Move the sandbox clock instead of waiting; anything due runs immediately.
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 } } }Reference: Move this merchant's sandbox clock forward, then run settlement and the return scan
Read the payment
The payment settled and was released at once, under this merchant's agreement. When an agreement holds a payment after it settles, it stays
settledandrelease_aftersays when it will be released.Get a payment
curl https://sandbox.socialmatterspay.com/v1/payments/3c8029c9-00de-481f-aff2-4e80839dea08 \ -H 'Authorization: Bearer sk_sandbox_…'The response · 200
HTTP 200 Cache-Control: no-store { "data": { "id": "3c8029c9-00de-481f-aff2-4e80839dea08", "object": "payment", "status": "released", "amount_cents": 8400, "fee_cents": 109, "net_cents": 8291, "refunded_cents": 0, "currency": "USD", "entry_code": "WEB", "payer_id": "6427de75-801c-4ac6-95fa-870665d10af3", "bank_account_id": "1357923a-53e2-4aa9-a547-a20155759d6c", "statement_descriptor": "NORTHWIND", "external_order_id": "order_10482", "metadata": { "cart_id": "c_7731" }, "risk_score": 65, "decline_reason": null, "decline_message": null, "bank_reference": "sbt_98eecba8-0048-4a1d-83c0-385f4ac6b04a", "payout_id": null, "return_id": null, "override_id": null, "site_id": null, "release_after": "2026-10-28T00:23:35.518Z", "created_at": "2026-10-28T00:22:35.514Z", "submitted_at": "2026-10-28T00:22:35.514Z", "settled_at": "2026-10-28T00:23:35.518Z", "released_at": "2026-10-28T00:23:36.559Z", "paid_out_at": null } }Reference: Get a payment
Receive the signed event
Your endpoint receives
payment.settled, signed with the secret from step 4. Verify the signature before you trust the body; Signed webhooks has tested code for Node, PHP and Python. The example below was signed with the placeholder secretwhsec_…shown in step 4.The delivery · payment.settled
POST /smp/webhooks Content-Type: application/json User-Agent: SocialMatterPayments-Webhook/1.0 X-SMP-Event: payment.settled X-SMP-Delivery-ID: 27a244be-357b-440f-941a-abc7bf5f9fee X-SMP-Timestamp: 1793146956 X-SMP-Signature: 5d445074ffbd99d1df1f0ab4d4056746c1e8c79b1e436ce799eccd89027cdaed { "id": "27a244be-357b-440f-941a-abc7bf5f9fee", "event": "payment.settled", "created_at": "2026-10-28T00:23:36.559Z", "data": { "payment_id": "3c8029c9-00de-481f-aff2-4e80839dea08", "amount_cents": 8400, "fee_cents": 109, "net_cents": 8291, "settled_at": "2026-10-28T00:23:35.518Z", "release_after": "2026-10-28T00:23:35.518Z", "external_order_id": "order_10482" } }
Next
- Make a return happen on purpose: amounts ending in
.01come backR01after they settle. See the sandbox. - Pay out what was released: POST
/.v1/ payouts/ trigger - Read Idempotency before you go live; every money-moving call needs a key.
