Sandbox and test cards
A sandbox installation behaves like live, but every bank, 3-D Secure page and fraud service is simulated and no real money moves. Keys start with sk_sandbox_, objects have livemode: false, and the merchant panel shows a sandbox banner. Sandbox and live are separate installations with separate keys, webhooks and data.
Differences you should know about:
- Registered-website, callback-URL and billing-details checks only warn in sandbox (see Developers → Logs) where live refuses. Fix every warning before going live.
- Time-based behaviour (end-of-day cut-offs, settlement dates, deferred refunds) follows a simulated clock that your sandbox operator may move, so a refund or payout can resolve faster or slower than the calendar suggests.
Test card data
Use any of the numbers below with expiry 12/2030, CVC 123 (Amex: 1234) and any cardholder name. Any other card number that passes the Luhn check approves; a number that fails it is declined as invalid_card. Never use real card numbers in sandbox.
Cards that approve
| Number | Card |
|---|---|
4109090000000011 |
Visa credit, domestic |
5109090000000018 |
Mastercard credit, domestic |
4109100000000018 |
Visa prepaid, domestic |
4355080000000013 |
Visa credit, domestic, program Axess (installments) |
5400610000000019 |
Mastercard credit, domestic, program Axess (installments) |
4766100000000012 |
Visa credit, domestic, program Bonus (installments) |
4894500000000018 |
Visa credit, domestic, program World (installments) |
4543600000000011 |
Visa credit, domestic, program Maximum (installments) |
4355090000000012 |
Visa debit, domestic (single payment only) |
9792010000000010 |
Troy debit, domestic (single payment only) |
4111111111111111 |
Visa credit, foreign |
5555555555554444 |
Mastercard credit, foreign |
Cards that decline
The decline scenario is built into the number; the response is a 402 card_error with the decline_code shown.
| Number | decline_code |
|---|---|
4109090000000508 |
do_not_honor |
4109090000000516 |
insufficient_funds |
4109090000000524 |
lost_card |
4109090000000532 |
stolen_card |
4109090000000540 |
expired_card |
4109090000000557 |
incorrect_cvc |
4109090000000565 |
invalid_card |
4109090000000573 |
transaction_not_allowed |
4109090000000581 |
card_not_supported |
4109090000000599 |
fraudulent |
4109090000000607 |
installment_not_supported |
4109090000000615 |
limit_exceeded |
4109090000000623 |
restricted_card |
4109090000000649 |
issuer_unavailable (temporary; retry may succeed on a real issuer) |
4109090000000656 |
processing_error (temporary) |
3-D Secure scenarios
| Number | What happens |
|---|---|
4109090000000631 |
The customer's authentication fails: decline_code: authentication_failed. |
4109090000000664 |
The card requires 3-D Secure. Payments that would skip it are declined (transaction_not_allowed); with 3-D Secure the payment succeeds. |
4109090000000672 |
The challenge is abandoned: the customer never returns and the payment stays requires_action. |
Any other approving card goes through 3-D Secure when the platform decides it is needed, and the simulated bank page completes it automatically.
Slow or uncertain bank answers
| Number | What happens |
|---|---|
4109090000000706 |
Technical error at the bank (processing_error). |
4109090000000714 |
The bank times out, then the platform finds the payment approved. The payment is processing first and ends succeeded. |
4109090000000722 |
The bank times out, then the platform finds nothing. The payment is processing first and ends as a failure. |
Rely on webhooks for these two: the first answer is not the final one.
Magic amounts
The last two digits of the minor-unit amount charged select a scenario, whichever card you use. With a customer-paid installment surcharge the amount that counts is amount_charged, not amount. Amounts that end in 00 to 39 are neutral, for example 100000.
| Last two digits | Result |
|---|---|
41 |
Fraud screening: review (fraud_status: review). |
42 |
Fraud screening: reject (fraud_error, fraudulent). |
50 |
do_not_honor |
51 |
insufficient_funds |
52 |
lost_card |
53 |
stolen_card |
54 |
expired_card |
55 |
incorrect_cvc |
56 |
invalid_card |
57 |
transaction_not_allowed |
58 |
card_not_supported |
59 |
fraudulent |
60 |
installment_not_supported |
61 |
limit_exceeded |
62 |
restricted_card |
63 |
3-D Secure authentication fails (authentication_failed) |
64 |
issuer_unavailable |
65 |
processing_error |
66 |
The card requires 3-D Secure (non-secure attempt declined) |
67 |
The 3-D Secure challenge is abandoned |
A card scenario (the numbers above) wins over an amount ending. For example, card 4109090000000508 declines with do_not_honor whatever the amount, while an approving card with an amount of 12551 (125.51 TRY) declines with insufficient_funds.
Things to try before you go live
- A successful payment with and without 3-D Secure, handled from the webhook as well as from the return page.
- Every decline you want to word differently for the customer.
- A payment that fails and is retried with a new
Idempotency-Key. - Capture (
capture_method: manual), a partial capture and a cancel. - A full refund on the day of the sale (void), a partial refund the same day, and a refund on a later day. See the refunds guide.
- An installment payment, including the preview and the error for an unsupported count.
- Webhook signature verification, a retry (answer with
500once) and a replay of an event. - A request from an IP address that is not on your allowlist, to see the warning.