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 theamount 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
countryreturned on a Sandbox Payment comes from the Sandbox processor, and so does thebrandon 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 withgeneric_decline, the same code the rest of the100001–100099band publishes, and a hosted-page Payment ends withprocessor_error, the same code100101publishes. On either transport the code alone does not tell a refusal apart from a rule. 100102is 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 becomesREQUIRES_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 Googleauth_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, andRequest-Id. Do not record a secret key, Authorization header, PAN, CVC,
full request body, or provider response.