Testing

Test your API integration with custom data.

In this version, test your integration using your own custom data instead of the default dummy data provided in earlier versions.

Use the X-Scenario-Key header to simulate different test scenarios in the sandbox environment. Check out the sections below to see supported scenario keys.

Cards

To test card transactions, pass a scenario key in this format:
scenario:<value>&issuer:<value>

  • scenario defines the authentication flow you want to test.
  • issuer defines the processor response to simulate.

🚧

Default Card Testing

If you omit the X-Scenario-Key header, the card transaction defaults to a noauth flow.

curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/charges' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:<value>&issuer:<value>' \
--data '{}
'

Supported Card Scenarios

ScenarioMeaning
auth_pinMock PIN authentication. Prompts the customer to enter their PIN and OTP.
auth_pin_3dsMock a failover from PIN to 3DS. The customer first enters their PIN, then gets redirected to the 3DS flow.
auth_3dsMock a 3DS authentication. Returns a redirect URL to send the customer to their bank for charge authorization.
auth_avsMock the noauth (AVS) flow. Prompts the customer to enter their billing address to complete the payment.

Mocking different Issuer responses

You can simulate different issuer responses for each authentication model. These represent actual responses from providers after payment processing. Use these to test failure, success, and edge cases.

We recommend that you test as much as you can to build high reliability for your application. Here are the available issuer response values:

  • already_reversed
  • approved
  • blocked_first_use
  • cannot_complete_violation_of_law
  • cannot_verify_pin
  • do_not_honor
  • error
  • exceeds_approval_amount_limit
  • exceeds_withdrawal_limit
  • expired_card
  • file_temporarily_not_available
  • incorrect_pin
  • insufficient_funds
  • invalid_account_number
  • invalid_amount
  • invalid_cvv
  • invalid_merchant
  • invalid_restricted_service_code
  • invalid_transaction
  • issuer_unavailable
  • lost_card_pick_up
  • negative_cvv_result
  • no_action_taken
  • no_checking_account
  • no_reason_to_decline
  • no_savings_account
  • no_such_issuer
  • partial_approval
  • pick_up_card_fraud
  • pick_up_card_no_fraud
  • pin_data_required
  • pin_entry_tries_exceeded
  • refer_to_issuer
  • refer_to_issuer_special_condition
  • reenter_transaction
  • security_violation
  • stolen_card_pick_up
  • suspected_fraud
  • system_error
  • transaction_does_not_fulfill_aml_req
  • transaction_not_permitted_card
  • transaction_not_permitted_terminal
  • unable_to_locate_record_in_file
  • unable_to_route_transaction
  • unsolicited_reversal

Example

You can mock a successful 3D Secure (3DS) transaction by specifying the scenario:auth_3ds&issuer:approved key:

// Successful 3DS transaction
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/charges' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:auth_3ds&issuer:approved' \
--data '{}
'

Mock a failed transaction due to an incorrect PIN:

// Incorrect pin transaction
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/charges' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:auth_pin&issuer:incorrect_pin' \
--data '{}
'

Mock a declined transaction due to insufficient funds during Address Verification System (AVS) checks:

// Insufficient funds AVS transaction
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/charges' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:auth_avs&issuer:insufficient_funds' \
--data '{}
'

Mobile money

Test Mobile Money transactions using one of two flows:

  1. The default flow prompts the customer to authorize payment via a notification on their mobile device.
  2. The redirect flow sends the customer to an authorization page.

Scenario 1 is the default flow for mobile money on the sandbox environment. To trigger this scenario, you don't need to pass the X-Scenario-Key header in your request.

To simulate the redirect flow, pass scenario:auth_redirect in the header.

// Redirect auth for Mobile Money transactions
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/charges' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:auth_redirect' \
--data '{}
'

Transfers

Test transfer transactions the same way as card transactions: define a scenario using the X-Scenario-Key header.

Available transfer scenarios:

  • successful
  • account_resolved_failed
  • amount_below_limit_error
  • amount_exceed_limit_error
  • blocked_bank
  • currency_amount_below_limit
  • currency_amount_exceed_limit
  • day_limit_error
  • day_transfer_limit_exceeded
  • disabled_transfer
  • duplicate_reference
  • file_too_large
  • insufficient_balance
  • invalid_amount
  • invalid_amount_validation
  • invalid_bulk_data
  • invalid_currency
  • invalid_payouts
  • invalid_reference
  • invalid_reference_length
  • invalid_wallet_currency
  • month_limit_error
  • month_transfer_limit_exceeded
  • no_account_found
  • payout_creation_error
  • unavailable_transfer_option

Example

You can mock a successful transfer request using the scenario:successful key:

// Successful transfer
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/transfers' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:successful' \
--data '{}
'

Mock a failed transfer due to an invalid currency:

// Invalid Currency
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/transfers' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:invalid_currency' \
--data '{}
'

Mock a failed transfer caused by insufficient balance:

// Insufficient balance
curl --request POST \
--url 'https://api.flutterwave.cloud/developersandbox/transfers' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Scenario-Key: scenario:insufficient_balance' \
--data '{}
'

❗️

Default Transfer Testing

If you do not pass the X-Scenario-Key header, the transfer remains in a pending state and no webhook is sent for the test.