Test Cards
Use this card to simulate a successful payment:
| Field | Value |
|---|---|
| Number | 4111 1111 1111 1111 |
| Expiry | Any future date (e.g. 12/30) |
| CVC | Any 3 digits (e.g. 123) |
Card brand detection
Section titled “Card brand detection”The widget detects the card brand from the card number prefix:
| Brand | Number prefix |
|---|---|
| Visa | 4 |
| Mastercard | 51–55 |
| American Express | 34, 37 |
| Discover | 6011, 65 |
| Diners Club | 36, 38 |
| JCB | 35 |
BECS direct debit test accounts
Section titled “BECS direct debit test accounts”For Australian bank account (BECS) payments:
| Field | Value |
|---|---|
| BSB | 062-000 |
| Account number | Any number |
| Account name | Any name |
A bank account saved with those details has no direct debit mandate, so its debits can’t be collected. For a bank account a plan can debit, save the fixture token instead. It saves a sandbox bank account with an accepted mandate:
curl -X POST https://api.elasticpay.co/api/v1/payment_methods \ -H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "type": "au_becs_debit", "customer_reference": "cus_xxx", "payment_method_data": { "token_metadata": { "type": "fixture", "token": "tok_sandbox_au_becs_debit" } } }'Its debits settle two business days after they’re sent, counted on your account’s calendar (its time zone and country’s public holidays), unless a test helper fails them. Three more tokens save a bank account that fails every debit the same way, as the declining cards do:
| Token | Every debit |
|---|---|
tok_sandbox_au_becs_debit_dishonour_insufficient_funds |
is dishonoured for insufficient funds when it would settle; the account stays usable |
tok_sandbox_au_becs_debit_dishonour_account_closed |
is dishonoured as account closed; the account is stopped |
tok_sandbox_au_becs_debit_late_return |
settles, then is returned late seven business days later |
All four tokens are refused on a live account, as the card fixture tokens are.
Bank debit outcomes
Section titled “Bank debit outcomes”These sandbox-only test helpers fail one bank debit, as the bank would. The outcome lands at the customer’s test clock time, or now:
| Endpoint | For a debit that is | code |
|---|---|---|
POST /api/v1/test_helpers/payment_intents/{id}/dishonour |
sent to the bank and not yet settled (processing) |
insufficient_funds, account_closed, payment_stopped, invalid_bsb, no_account, refer_to_customer, customer_deceased, ddr_cancelled_at_bank, technically_invalid |
POST /api/v1/test_helpers/payment_intents/{id}/late_return |
settled (succeeded) |
late_return, late_return_insufficient_funds, dd_claim, recall |
curl -X POST https://api.elasticpay.co/api/v1/test_helpers/payment_intents/pi_xxx/late_return \ -H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "code": "late_return" }'The response is the failed payment intent. Each outcome is handled as a real return:
insufficient_funds,refer_to_customer,late_returnandlate_return_insufficient_fundsleave the bank account usable, so a plan collects the amount again under its failure behaviour.invalid_bsb,account_closed,no_accountandtechnically_invalidstop the bank account. This suspends the plans that use it until the customer adds a new payment method.payment_stopped,ddr_cancelled_at_bank,customer_deceased,dd_claimandrecallare about the customer: they stop the bank account and suspend every plan of the customer for your review, and no email is sent to the customer. Only/resumeends it.
A debit in the wrong state is refused with 409
(payment_intent_not_dishonourable or payment_intent_not_returnable), and
a live account with 403 (sandbox_only).
Forcing payment outcomes
Section titled “Forcing payment outcomes”To force a specific outcome regardless of card details, set
_sandbox_outcome in the payment intent’s metadata:
curl -X POST https://api.elasticpay.co/api/v1/payment_intents \ -H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "amount": 1999, "currency": "AUD", "metadata": {"_sandbox_outcome": "decline"} }'| Value | Result |
|---|---|
succeed |
Payment succeeds (the default without an override) |
decline |
Payment fails with insufficient_funds |
requires_action |
Simulates a 3D Secure challenge |
timeout |
Payment fails with gateway_timeout |
This works for any payment method and takes priority over card-number-based
outcomes. Refunds have a parallel override — set
"_sandbox_refund_outcome": "fail" in the refund request’s metadata to make
the refund fail (refunds succeed by default).
Fixture tokens — server-side testing without the widget
Section titled “Fixture tokens — server-side testing without the widget”For CI pipelines, server-side tests, and agents, you can skip the widget
entirely: pass a fixture token as token_metadata.token when creating a
payment method (sandbox keys only).
curl -X POST https://api.elasticpay.co/api/v1/payment_methods \ -H "Authorization: Bearer pk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "type": "card", "payment_method_data": { "token_metadata": { "type": "fixture", "token": "tok_sandbox_visa_succeed", "data": "" } } }'| Token | Brand | last4 | Outcome when charged |
|---|---|---|---|
tok_sandbox_visa_succeed |
Visa | 4242 | Succeeds |
tok_sandbox_visa_decline_insufficient_funds |
Visa | 0002 | Declines — insufficient funds |
tok_sandbox_visa_decline_card_lost |
Visa | 9987 | Declines — card lost |
tok_sandbox_visa_decline_expired_card |
Visa | 0069 | Declines — expired card |
tok_sandbox_visa_3ds_required |
Visa | 3155 | Requires 3D Secure authentication |
tok_sandbox_visa_timeout |
Visa | 0119 | Fails — gateway timeout |
tok_sandbox_mastercard_succeed |
Mastercard | 4444 | Succeeds |
tok_sandbox_mastercard_decline_insufficient_funds |
Mastercard | 9995 | Declines — insufficient funds |
tok_sandbox_mastercard_decline_account_closed |
Mastercard | 0014 | Declines — account closed |
tok_sandbox_amex_succeed |
Amex | 8431 | Succeeds |
The outcome travels with the saved payment method: every later charge against it resolves to that outcome, regardless of amount. That makes the declining tokens the right tool for testing recurring-billing failure handling — save a declining card, attach a payment plan, and advance a test clock to watch the dunning flow run.
Decline codes and plan retries
Section titled “Decline codes and plan retries”Each declining fixture answers with the card scheme’s response code and merchant advice code that a real issuer would send for that decline. When a payment plan’s payment declines, those codes decide whether the plan may collect it again:
| Token | Response code | Merchant advice code | On a payment plan |
|---|---|---|---|
tok_sandbox_visa_decline_insufficient_funds |
51 |
2 (issuer can’t approve at this time) |
Retryable: the plan’s failure behaviour runs |
tok_sandbox_visa_decline_card_lost |
41 |
1 (issuer will never approve) |
Never retried: the card is stopped |
tok_sandbox_visa_decline_expired_card |
54 |
3 (new card details needed) |
The saved card is stopped and isn’t retried; updated card details are required before another attempt |
tok_sandbox_mastercard_decline_insufficient_funds |
51 |
02 (try again later) |
Retryable, at the first collection time at least 72 hours after the decline |
tok_sandbox_mastercard_decline_account_closed |
79 |
03 (do not try again) |
Never retried: the card is stopped |
A decline that stops the card (the card-lost, expired-card and account-closed fixtures) runs no failure behaviour, and later scheduled payments aren’t sent to the card. If the customer has another usable saved card, the plan switches to it. Otherwise the customer is emailed a link to add a new one, and plans set up with that card as their payment method are suspended.
The decline override and amounts ending in 01 carry no codes. A live
decline without a merchant advice code isn’t retried, and neither are these on
a plan: no failure behaviour runs, but the card isn’t stopped. It stays the
plan’s card for its next payment, and no recovery email is sent.
One-off payments don’t use these codes; see Exercising failure for what a declined one-off payment does.
Amount-based outcomes
Section titled “Amount-based outcomes”When no metadata override or fixture outcome applies, the last two digits of the amount in cents select the outcome:
| Amount ends in | Outcome |
|---|---|
01 |
Declines — insufficient funds |
02 |
Requires 3D Secure authentication |
99 |
Fails — gateway timeout |
| anything else | Succeeds |
For refunds, an amount ending in 03 fails; anything else succeeds.
Prefer _sandbox_outcome metadata or fixture tokens — they leave amounts
free to carry realistic values, so a $19.99 subscription in a test stays
$19.99. Watch for accidental triggers: a test amount of 1001 cents
declines by design.
Outcome precedence
Section titled “Outcome precedence”_sandbox_outcomein the payment intent’s metadata (per-charge override)- The saved payment method’s fixture outcome
- Amount-based fallback
- Default: succeed
All test transactions use mocked PSP responses. Webhook events still fire normally in sandbox mode, giving you a realistic integration test environment.