Miracle Docs

Test Cards

Use these test card numbers in sandbox to simulate different payment scenarios. All test cards only work with test API keys (sk_test_ / pk_test_).

For all test cards: use any future expiry date (e.g., 12/30) and any 3-digit CVC (e.g., 123).


Basic test cards

The sandbox test adapter determines the outcome based on the last 4 digits of the card number. Use any Luhn-valid card number — only the suffix matters.

ScenarioCard NumberExpected Result
Successful payment4242 4242 4242 0000Payment succeeds (APPROVED)
Successful payment (variant)4242 4242 4242 0026Payment succeeds (APPROVED)
3DS required4242 4242 4242 0018Redirects to 3DS challenge page
Decline — insufficient funds4242 4242 4242 0034Payment fails (INSUFFICIENT_FUNDS)
Decline — do not honor4242 4242 4242 0042Payment fails (DO_NOT_HONOR)
Pending (async)4242 4242 4242 0059Payment enters async processing
Gateway timeout4242 4242 4242 0091Retryable provider error (GATEWAY_TIMEOUT)

Magic card rules

The test adapter determines the outcome based on the last 4 digits of the card number. Use any Luhn-valid PAN — the prefix does not matter, only the suffix.

Last 4 DigitsOutcomeDescription
0000SuccessPayment approved immediately
00183DS RequiredReturns paymentAction.type = 'redirect' with sandbox 3DS challenge URL
0026Success (variant)Payment approved immediately (alternate success card)
0034Decline — Insufficient FundsPayment fails with error code INSUFFICIENT_FUNDS
0042Decline — Do Not HonorPayment fails with error code DO_NOT_HONOR
0059PendingPayment enters async processing state, resolves via callback
0091Error — Gateway TimeoutReturns a retryable GATEWAY_TIMEOUT error

Payment lifecycle per scenario

Each scenario produces a different sequence of status transitions. Use these to test your webhook handling and UI state management.

Successful payment:

created --> processing --> succeeded

Declined payment:

created --> processing --> failed

3DS required (success):

created --> processing --> pending_user_action --> processing --> succeeded

When a payment enters pending_user_action, the API response includes a paymentAction with type: 'redirect' and a sandbox 3DS challenge URL. After the cardholder completes the challenge, call POST /v1/payments/{id}/complete-action with redirectResult to resume processing.

3DS required (failed):

created --> processing --> pending_user_action --> failed

Pending (async):

created --> processing --> pending --> succeeded

The pending state resolves automatically via a test callback after a short delay.


3DS test scenarios

Use the card suffix 0018 to trigger a 3DS redirect. The payment enters pending_user_action status and the response includes a paymentAction with type: 'redirect' pointing to the sandbox 3DS challenge page.

After the cardholder completes (or abandons) the challenge, call POST /v1/payments/{id}/complete-action with a redirectResult value. The test adapter maps redirectResult to a realistic 3DS outcome:

redirectResult valueOutcomeDescription
successPayment succeeds3DS challenge authenticated. Liability shift = yes.
failurePayment fails3DS challenge failed (not_authenticated). Error: AUTHENTICATION_REQUIRED.
rejectedPayment fails3DS authentication explicitly rejected by issuer. Error: AUTHENTICATION_REQUIRED.
attemptedPayment succeeds3DS challenge attempted but not fully authenticated. Liability shift = no.
frictionlessPayment succeeds3DS performed silently — no challenge shown. Liability shift = yes.
unavailablePayment succeeds3DS service unavailable. Proceeds without 3DS.
not_enrolledPayment succeedsCard not enrolled in 3DS. Proceeds without 3DS.

The sandbox 3DS challenge page is hosted locally at http://localhost:3002/3ds-challenge during development. It presents buttons for each redirectResult value so you can simulate different 3DS outcomes.


Refund test scenarios

Refunds in sandbox follow the same flow as live. Create a payment with a success card, then refund it:

# 1. Create a successful payment (card ending 0000)
# 2. Refund it
curl -X POST https://api.miracle.com/v1/payments/pay_abc123/refunds \
  -H "Authorization: Bearer sk_test_your_secret_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: test-refund-001" \
  -d '{
    "reason": "Testing refund flow"
  }'

Refund status transitions in sandbox:

pending --> processing --> succeeded

You will receive refund.created and refund.succeeded webhook events, identical to live.


Magic amounts

Magic amounts are not currently active. Only magic card suffixes control test outcomes. The rules below describe the planned magic amount behavior.

In addition to card numbers, the test adapter will also check the last two digits of the amount (in minor units) for special behavior:

Amount endingOutcomeDescription
66DeclineAmount-based decline trigger
773DS requiredAmount-based 3DS trigger

For example, an amount of 1066 (10.66 USD) will trigger a decline regardless of the card number used.

When both a magic card rule and a magic amount rule apply, the card rule will take precedence.


Important notes

  • Test cards only work with test API keys (sk_test_). Using them with a live key will result in a rejected transaction.
  • Never use real card numbers in sandbox. The sandbox is not PCI-scoped for real card data. Use the test card numbers on this page.
  • Test cards are rejected in live mode. When you switch to live keys, you must use real card numbers.

On this page