Appearance
Testing Payments
The sandbox checkout walks the same journey your customers see in production, but you choose how each payment ends.
The journey
Open the session_url returned when you created the session:
https://pay.spayon.io/sandbox/session/{session_id}Every page carries a SANDBOX MODE banner so it is never mistaken for a real payment.
- Pre-checkout — your product, price and payment options. Enter an email and continue
- Card entry — enter any card details
- Confirmation code — choose how the 3-D Secure step resolves
- Outcome — approve or decline the payment
- You are redirected to your
return_urlwithorderIdandsessionId, and the callback fires
Test cards
There are no special card numbers
Any card details are accepted. There is no Luhn check and no card is ever validated against a real network. You do not need a list of test cards — the outcome is chosen on the pages that follow, not by the number you type.
The only thing the card number affects is the brand recorded on the transaction:
| Card number starts with | Recorded brand |
|---|---|
4 | Visa |
| Anything else | Mastercard |
Example values that work:
| Field | Value |
|---|---|
| Card Number | 4111 1111 1111 1111 |
| Cardholder Name | JOHN DOE |
| Expiry | 12/29 |
| CVV | 123 |
The CVV is never transmitted, and the card number is not stored.
Forcing an outcome
Confirmation code step
| Choice | Result | Response Code |
|---|---|---|
| Code confirmed | Continues to the approve/decline step | — |
| Wrong code | Payment declined immediately | SANDBOX_OTP_FAILED |
| Code expired | Payment declined immediately | SANDBOX_OTP_TIMEOUT |
Outcome step
| Choice | Transaction status | Session status |
|---|---|---|
| Approve payment | DEPOSITED | paid |
| Decline payment | DECLINED | failed |
Every outcome fires the matching callback, so you can verify both your success and failure handling.
Expiry
To test the expiry path, create a session and simply leave it. When the session timeout elapses, the session is marked expired and the expiry callback fires — exactly as in production.
What your callback receives
On a declined payment the callback includes the reason:
json
{
"status": "failed",
"price": "1000.00",
"orderId": "your-order-id",
"currency": "AMD",
"sessionId": "16c4af36-bd41-4794-996e-930909aa2851",
"productName": "iPhone 16 Pro",
"declineReasons": [
{
"transactionId": 12,
"responseCode": "SANDBOX_OTP_FAILED",
"responseReasonEn": "OTP verification failed"
}
]
}On success, declineReasons is null and status is paid.
The X-Signature header is an HMAC-SHA256 of the raw body signed with your Sandbox Client Secret.
Checking status
Poll the session as you would in production, using your sandbox token:
http
GET https://api.spayon.io/api/sandbox/vendor/checkout-session/{session_id}
Authorization: Bearer YOUR_SANDBOX_TOKENReviewing your test activity
In the admin panel, Sessions and Transactions show your sandbox activity while sandbox mode is on — including the response code for each forced outcome, and whether the callback succeeded, is retrying, or failed.
Super vendors see all their child vendors together, with a Vendor column, and can filter to one child.