Testing Card Payments
In your demo environment, create a test payment with the following data:
1. Payer information
Use any placeholder data you'd like for the required payer information like first name, last name etc.
2. Card information
Use one of the demo cards:
Brand | Number | Expiration date | CVV |
---|---|---|---|
Visa | 4111 1111 1111 1111 | 03/30 | 737 |
Mastercard | 5454 5454 5454 5454 | 03/30 | 737 |
Amex | 3700 0000 0000 002 | 03/30 | 7373 |
3. Cardholder's name (Magic Values)
Use one of the magic values for the cardholder's name depending on the scenario you want to test:
Successful Payment
Cardholder's First Name | Cardholder's Last Name | Payment Flow | Callbacks you will receive |
---|---|---|---|
MAGICVALUE | APPROVED |
|
|
Unsuccessful Payment
Use one of the following magic values to simulate a card being declined due to either being expired, having no sufficient funds, or being suspected of fraud:
Cardholder's First Name | Cardholder's Last Name | Payment Flow | Callbacks you will receive |
---|---|---|---|
MAGICVALUE | CARD EXPIRED |
|
|
MAGICVALUE | NOT ENOUGH BALANCE |
|
|
MAGICVALUE | FRAUD |
|
|
4. Check the results
You will receive callbacks according to the magic value you chose (see Payment Status Notifications for details).
The failed callbacks will contain information according to the scenario you picked in the reason, reason_code, and client_reason parameters.

The status failed can only occur for card or direct debit payments. It occurs when there’s an issue to capture the funds. The notification will contain the reason for the failure.
For any new failed charge attempt, Flywire will send a new failed payment status notification. If the retry succeeds, Flywire will send a processed notification. If the payer retries with a different payment method, the information in the payment_method object will change.

Type of the event (status change).
Possible types:
initiated guaranteed delivered cancelled |
For payments. For details of the meaning of each status see Payment Status Notifications - Payment Statuses |
processed failed |
For charges of payments. For details of the meaning of each status see Payment Status Notifications - Payment Statuses |

The time when the event (status change) occurred.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The resource that has generated the notification.
Possible values:
-
payments
-
charges
data object

The payment reference.

The payment reference is an ID generated by Flywire to identify a payment.
Format:
Either: ABC123456789
3-letter portal/recipient ID 9 numbers
Or: 1AB12CD452ABC1D
number 8 alphanums number 5-alphanum portal/recipient ID
With the payment reference, the payment can be tracked through the different stages of the payment process.
The payment reference is also important in other situations, for example:
-
When a payer is using bank transfer as payment method, they usually must provide the payment reference when sending the funds.
-
The payment reference helps Flywire to identify the payment if you or your payer needs support.

The payment amount in the payer currency.
The amount is specified in the smallest unit of the currency, called subunits. For example, in USD, the subunit is cents, and 100 cents equal 1 USD. So, an amount of 12025 (cents) is equivalent to 120.25 USD.
Note that the subunit-to-unit ratio varies by currency, it is not always 100. See Currencies for the subunits of each currency.

The payer currency.
Format:
Three-letter ISO 4217 currency code, for example EUR.


The payment amount in the billing currency.

The billing currency is the currency in which the recipient of the payment is billing their payer. The billing currency depends on the
The amount is specified in the smallest unit of the currency, called subunits. For example, in USD, the subunit is cents, and 100 cents equal 1 USD. So, an amount of 12025 (cents) is equivalent to 120.25 USD.
Note that the subunit-to-unit ratio varies by currency, it is not always 100. See Currencies for the subunits of each currency.

The billing currency.
Format:
Three-letter ISO 4217 currency code, for example EUR.

The billing currency is the currency in which the recipient of the payment is billing their payer. The billing currency depends on the

The current status of the payment.

A payment can have the following statuses and notifications:
Status | Notification | Description | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
The payment status initiated is the status for all new payments in Flywire. No funds have been received by Flywire at the initiated stage. ![]() In everyday usage, a "payment" usually refers to the entire process of making a payment through Flywire. But the term "payment" has a specific meaning in Flywire:
|
||||||||||||||||||||||||
![]() |
Only for Pre-Authorization Payments. ![]() A Pre-Authorization Payment temporary reserves the payment amount on a debit or credit card. The purpose of a pre-authorization is to verify that the cardholder has sufficient credit available to cover a transaction and to temporarily set aside that amount until you capture the funds. Pre-Authorization Payments are only available for same-currency payments, not for FX payments. Example for a Pre-Authorization Payment:
The payment has been authorized and is now in the holding period. ![]() How long funds can be reserved depends on the card issuer and other circumstances. At the moment, Flywire can reserve the funds for 7 days. If you are not capturing the funds within the holding period, blocked amount is released back to the cardholder's credit. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. When you cancel a Pre-Authorization Payment the blocked amount immediately returns back to the cardholder's credit. |
|||||||||||||||||||||||||
|
![]() |
The payment status goes from initiated to processed when Flywire has the confirmation that the funds have been received or captured via one of these ways:
For 529 Payments, you have to put a payment into the processed status yourself. After a payment is processed by you, you should notify your payer that their payment was processed to avoid duplicate payments.
|
||||||||||||||||||||||||
|
![]() |
The status changes to guaranteed when funds are received by Flywire and all the necessary validations for that payment method and corridor are successful (since Flywire performs a security check on every payment once the funds have been received). At this point, you are guaranteed that Flywire will send you the funds. |
||||||||||||||||||||||||
|
![]() |
The status changes from guaranteed to delivered when Flywire sent you the funds in your daily batch disbursement. Payments are updated to delivered at a set time each day. The status delivered is the end stage, the status of a delivered payment can't change. |
||||||||||||||||||||||||
|
![]() |
The status failed can only occur for card or direct debit payments. It occurs when there’s an issue to capture the funds. The notification will contain the reason for the failure. |
||||||||||||||||||||||||
|
![]() |
The payment status ![]()
|
||||||||||||||||||||||||
|
![]() |
This status has different meaning depending on the context: ![]() This reversed type means a refund for the payment has been finished. It can either be a partial or a full refund. If there are multiple partial refunds for a payment, you will receive a notification for each new finished refund. Keep in mind that there can only be one refund at a time for a payment. This status tells you that a refund has successfully been completed for the payment.
![]() This reversed type is only relevant for direct debits payments. The status occurs when you (the client) received the funds from Flywire but Flywire did not receive the funds from your payer's bank account. From a technical side this means:
|

The time and date the payment will expire automatically if no funds were received.
For card payments:
For API integration:
Card payments do not expire. If the charge has been unsuccessful, no other attempts of charging the card will be made. You need to create a new payment to try a new charge attempt.
For other integrations:
Card payments expire usually within 2 business days, when there was no attempted payment or the attempts to capture the funds were unsuccessful.
For Pre-Authorization Payments:
The expiration date is not the holding period length of a Pre-Authorization Payment. For Pre-Authorization Payments, you can disregard this parameter.

How long funds can be reserved depends on the card issuer and other circumstances. At the moment, Flywire can reserve the funds for 7 days. If you are not capturing the funds within the holding period, blocked amount is released back to the cardholder's credit.

A payment expires automatically after a while if no funds are received by Flywire:
-
Bank transfer payments expire usually within 5-8 business days, when no funds have been received by Flywire.
-
Direct debit payments expire usually within 2 business days, when the attempts to capture the funds were unsuccessful.
-
For API integration:
Card payments do not expire. If the charge has been unsuccessful, no other attempts of charging the card will be made. You need to create a new payment to try a new charge attempt.
For other integrations:
Card payments expire usually within 2 business days, when there was no attempted payment or the attempts to capture the funds were unsuccessful.

The unique identifier you provided for the payment to help you match the callback to the payment.
For API integrations:
You provided this identifier via the external_reference parameter.
For all other integrations:
You provided this identifier via the callback_id parameter.

The ISO2 code of the payer country (the country the money was sent from).
payment_method object

The payment method type.
Possible values:
bank_transfer |
Payment is done via bank transfer. |
online |
Payment is done via an alternative payment method (APM), through a third-party provider. |
card |
Payment is done via credit or debit card. You'll get additional information about the type of card in the parameter card_classification (either credit or debit). |
direct_debit |
Payment is done via direct debit. |
529_payments |
Payment is done via a 529 provider. |

Only for card payments.
The brand of the card (for example, Visa or Mastercard).

Only for card payments.
Credit or debit card.
Possible values:
-
credit
-
debit

Only for card payments.
The card expiration date in the format MM/YYYY.

The last four digits of the card number or bank account number.

The reason why the charge failed that you can share with your payers. You can display this reason to your payer to help them figuring out what went wrong and possibly solve the problem.
There are different reasons depending on what the issue is.

Issue | Reason returned by the API |
---|---|
Configuration or connectivity issues | Your transaction has not been successful, please try again. If the error persists select a different payment method or contact our customer support team. |
Issues related with bank or card details, like invalid data or refused by the bank | Your transaction has been declined by your bank. Please try inserting correct, valid card/bank account details to complete the payment or contact your bank to resolve the issue. |
Not enough balance or over amount limit | Your transaction has been declined by your bank. Please try increasing the available balance of your account, use a different card/bank account or contact your bank for further assistance. |

Flywire error code for the error message why charging the payment failed.

The reason why the payment failed for you as an internal information.

The plan ID.
A plan ID is the unique identifier for a Flywire installment plan.
Format:
Either: IPABC18EADF349BE
IP3-letter portal/recipient ID11 characters
Or: IPABC1D18EADF349BE
IP5-alphanum portal/recipient ID11 characters
fields object
These are the fields of the recipient (also called "

Fields of a recipient (also called a portal) are fields that are specific to that recipient. Depending on how you use Flywire, you might know them under the names dynamic fields, custom fields, or student fields.
Fields are defined when the recipient (also called portal) is set up by Flywire. They are additional fields that the payer has to fill out when they make their payment (additional to the standard payer fields that are the same for all recipients).
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please contact the Solutions team if you require payer information to be returned.

The payer's first name.

The payer's last name.

The payer's middle name.

The payer's first line of address.

The payer's second line of address.

The payer's city.

The payer's zip code.

The ISO2 code of the payer country (the country the money was sent from).

The payer's state.

The payer's phone number.

The payer's email address.
{
"event_type": "failed",
"event_date": "2022-02-21T11:15:34Z",
"event_resource": "charges",
"data": {
"payment_id": "MGT670199181",
"amount_from": "420",
"currency_from": "USD",
"amount_to": "420",
"currency_to": "USD",
"status": "failed",
"expiration_date": "2022-02-23T11:12:19Z",
"external_reference": "Callback ID 1234",
"country": "US",
"payment_method": {
"type": "card",
"brand": "visa",
"card_classification": "credit",
"card_expiration": "01/2035",
"last_four_digits": "5555"
},
"reason": "Your transaction has been declined by your bank. Please try increasing the available balance of your account, use a different card/bank account or contact your bank for further assistance.",
"reason_code": "012",
"client_reason": "Not enough balance",
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"student_id": "ID123456",
"student_last_name": "Smith"
},
"payer": {
"first_name": "Peter",
"last_name": "Payer",
"middle_name": null,
"address1": "789 Calle Mayor",
"address2": null,
"city": "Madrid",
"country": "ES",
"state": null,
"zip": "28013",
"phone": "0034912345678",
"email": "[email protected]"
},
}
}