API reference

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:

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

  1. A successful payment with and without 3-D Secure, handled from the webhook as well as from the return page.
  2. Every decline you want to word differently for the customer.
  3. A payment that fails and is retried with a new Idempotency-Key.
  4. Capture (capture_method: manual), a partial capture and a cancel.
  5. 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.
  6. An installment payment, including the preview and the error for an unsupported count.
  7. Webhook signature verification, a retry (answer with 500 once) and a replay of an event.
  8. A request from an IP address that is not on your allowlist, to see the warning.