Skip to main content
Sandbox requests create test objects and move no real money. Use your Sandbox secret key. The amounts below select a Payment outcome, so you can reach each one without special test data. Any other amount is answered by the Sandbox processor itself and is not guaranteed to succeed, so treat an unexpected failure on an ordinary amount as a Sandbox condition rather than a defect in your integration, and use a rule amount whenever you need a specific result. Create new test Payments and Refunds only in the supported payment currencies; Sandbox does not expand the accepted Payment or Refund currency set.

Choose the outcome with the amount

To reach a specific outcome, send the Payment amount below; outside this list the Sandbox processor answers on its own. A rule matches the amount integer in minor units in every currency, whatever that currency’s exponent, so send 100051 itself rather than a converted value. An outcome is decided when the Payment reaches its result, not when you create it. A Direct or hosted-page Payment that becomes REQUIRES_ACTION selects its outcome only after the payer completes the redirect, and an abandoned or expired attempt keeps the status it ended with. Examples that never reach a redirect and are terminal in the create response itself: 100102 on a Direct Payment, and a request the processor refuses definitively. A processor failure before execution can end a Direct Payment locally after eligible bounded retries, with processor_unavailable or processor_error. These technical failures are not issuer declines. If authentication or wallet execution may already have reached the provider, Flowlix reconciles the existing order; an unavailable read leaves it nonterminal. An uncertain hosted-page create can return a PENDING Payment because a checkout may already exist. Retrieve the existing Payment rather than creating a replacement while its result is unknown. The processor’s own page can show a success screen for a rule amount while the Payment ends FAILED: fulfil on the retrieved Payment status, never on what the payer saw. The last two digits of an amount between 100001 and 100099 are the processor response code. Today only 05, 14 and 51 carry a more specific public failure_code; every other code is a generic_decline, which is how the same answer is treated for a real Payment. Branch on failure_code, never on the amount you sent. 100103 is the one rule that does not decide the Payment: create it, retrieve it until it is terminal, and once it is SUCCEEDED, create a Refund of it. That Refund, and every later Refund of the same Payment, fails in the create response itself, so use a different Payment to test a successful Refund. Handle the failure with the Refund failure procedure. Each outcome produces the status, failure_code, failure_message, events and webhooks that the same answer produces in Live, so what you build against here is what you will see there. Handle a failed result with the failure codes and a rejected request with the request errors. The rules apply to Sandbox only and change nothing in Live.

What Sandbox does not reproduce

  • Payouts are not selected by amount. The rules above apply to Payments and their Refunds; a Sandbox Payout follows the processor’s own answer.
  • Card metadata is not decided by the amount. The country returned on a Sandbox Payment comes from the Sandbox processor, and so does the brand on a hosted-page Payment; neither need match the card that was used, so do not assert on them.
  • A refusal by the processor is not a rule. When the processor refuses the request outright, the Payment is created and ends FAILED, but the published code depends on the transport, not on the refusal: a Direct Payment ends with generic_decline, the same code the rest of the 100001–100099 band publishes, and a hosted-page Payment ends with processor_error, the same code 100101 publishes. On either transport the code alone does not tell a refusal apart from a rule.
  • 100102 is a Direct rule. A hosted-page Payment with that amount follows the processor’s own answer and is not declined by it.

Card data

The outcome comes from the amount, not from the card. Never send a real card number to Sandbox: use one of the synthetic examples below, with a future expiry. They are not account-specific test fixtures. For Hosted Payment Page, enter card data only in the hosted form. For Direct API, submit it only from your PCI-compliant Sandbox backend using payment_method_data.card. Supply the other required card fields as described in the Direct API guide. Never copy a card request body into logs, screenshots, issue trackers, or support messages.

3D Secure in Sandbox

A Direct Sandbox Payment usually becomes REQUIRES_ACTION with a next_action.redirect_url, and the Sandbox authentication page completes without a challenge screen. Treat the redirect as part of the flow: follow the latest next_action.redirect_url, then retrieve the Payment and fulfil only on SUCCEEDED, never on return_url alone. To exercise a failed authentication, send 100100. A completed authentication page is not proof of payment, and the absence of a challenge screen is not proof that authentication was skipped. For each different scenario, create a new Payment with a new Idempotency-Key.

Wallet input and response checks

Apple Pay and Google Pay are Experimental: their support and this guidance are still being refined and are not final. Direct processing accepts decrypted input when the account and upstream wallet route are provisioned. The card scenarios above do not provide usable wallet credentials or prove wallet authorization. Use the wallet input reference for local request-construction checks. Include the required Google auth_method and the complete payer-browser object for PAN_ONLY. Do not send real wallet credentials to probe syntax or availability. Before launch, test response parsing with payment_method.card, a known method without card metadata, a null method, and an unfamiliar method string. A missing payment_method field is invalid. Test webhook handling with grouped Payment snapshots, including a present null payment_method for an unknown method. Retrying an Event ID must preserve its original content and must not repeat fulfilment. These local parsing checks do not establish issuer authorization. A successful wallet payment test additionally needs a provisioned account and a valid wallet credential supplied through the approved upstream integration. See Payment response changes and Payment event snapshots.

Verification checklist

1

Successful Payment

Complete one HPP or Direct Payment with an amount outside 100001–100103 and retrieve it until it is terminal. Confirm your order is fulfilled only after SUCCEEDED; if the attempt fails, create a new Payment and try again.
2

Terminal decline

Send 100051, then 100054. Confirm that your checkout branches on failure_code, handles both a specific reason and generic_decline, shows neutral customer copy, and creates a new Payment for another attempt.
3

3D Secure

Complete one Direct Payment through the authentication page, then send 100100 for a failed authentication. Confirm that both use the returned Payment status, not the presence or absence of a challenge screen, to decide fulfilment.
4

Idempotency

Retry with the same key and an equivalent effective request identity, then change a non-card field such as merchant_reference while retaining the key. Confirm replay and idempotency_key_reused handling without recording card data.
5

Refunds

On a Payment created with an ordinary amount that reached SUCCEEDED, create a partial Refund and retrieve the parent Payment until that Refund is SUCCEEDED or FAILED. Only after SUCCEEDED, retrieve the Payment again, read the latest amount_refundable, and create a remaining Refund when the business still intends to return that amount. Then create a separate Payment with 100103, let it reach SUCCEEDED, and confirm that a Refund of it fails: do not automatically issue another one, and follow the Refund failure procedure.
6

Payouts

Submit one test Payout, retrieve it by ID, and locate it in the paginated Payout list. Keep PENDING and PROCESSING nonterminal; track SUCCEEDED or FAILED through retrieval and payout events. For FAILED, handle failure_code and failure_message without an automatic retry. A repeated creation can return its original response, so use GET for the latest state. See the Payout guide.
7

Request failures

Exercise invalid authentication, malformed JSON, invalid fields, idempotency conflicts, and a safe transient retry. Preserve Request-Id without recording sensitive request data.
8

Webhooks

Create a Sandbox endpoint and subscribe to the Payment and Refund events you handle. Verify a real delivery, persist it before acknowledging, and confirm that repeating the same Event ID does not repeat fulfilment. Locally test altered payloads, an incorrect signing secret, and stale timestamps; these must fail signature verification. See Webhooks.

Keep test evidence safe

Record operation, HTTP status, object status, machine-readable error code, and Request-Id. Do not record a secret key, Authorization header, PAN, CVC, full request body, or provider response.