Payment Status Notifications
Payment status notifications are callbacks for payment events, such as a payment status change. They enable you to track a payment while it makes its way through the payment workflow. Whenever a status change event occurs, for example when the payment status changes from
Initiated to
Processed, you'll get a notification to the URL you provided.
Why should I use callbacks?
Using callbacks has several benefits:
-
Callbacks can be used to facilitate reconciliation of Flywire payments to accounting systems, ERPs, etc.
-
Callbacks provide real-time updates for payment statuses, no manual checks in Dashboard needed.
-
Callbacks are especially useful for direct debit payments where the payment capture will take a few working days and may be subject to future failure.
-
You can use callbacks to trigger processes that start after the payment is completed.
When should I use callbacks?
If you have access to Flywire Dashboard, callbacks are optional (but recommended) since you have the option to manually track the payment progress there. If you don't have access to Flywire Dashboard, it is highly recommended to use callbacks enable you to track the payment progress.
If you are using the
Flywire API, callbacks are essential to ensure you get reliable updates about the payment in real-time. Without callbacks, your system would have to poll the API for updates, which is resource-intensive and can lead to performance bottlenecks or rate-limiting.
How do I get started?
-
For your production environment: See How to set up Payment Status Notifications.
-
For testing notifications: See Flywire API Sandbox
Payment Statuses
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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
|
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 amount that is being held on the card has been adjusted. |
|
|
|
|
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:
|
|
|
|
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 Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
|
|
|
|
The status failed can only occur for card |
|
|
|
The payment status |
|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
Payment Status Notifications
-
Initiated -
Authorized -
Adjusted -
Processed -
Guaranteed -
Delivered -
Failed -
Cancelled -
Reversed
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:
-
A payment is considered created when a payment reference is assigned to it, not any earlier stage in the process.
What is 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.
-
-
When the payment reference is assigned, two things happen:
-
The FX rate is locked in for FX payments (FX = "foreign exchange", a payment where one currency has to be converted to a different currency).
-
The payment starts its journey in status initiated, and its progress traceable via the payment reference. If you are using Flywire Dashboard, you can view the payment on your dashboard.
-
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "initiated",
"event_date": "2021-05-20T11:24:45Z",
"event_resource": "payments",
"data": {
"payment_id": "PTU146221637",
"amount_from": "4225",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "initiated",
"expiration_date": "2021-05-31T11:24:45Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card"
},
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
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:
A guest checks into a hotel for a three-night stay, and you place a pre-authorization on their credit card for the estimated cost of the stay.
Check-In: You pre-authorizes $600 on the guest's credit card ($150 per night plus $150 deposit). This reduces the guest's available credit by $600 but is not yet charged.
During the Stay: The guest orders room service for $50.
Check-Out: The final bill is $500 ($450 for room charges plus $50 for room service). You capture $500 from the pre-authorization. The remaining $100 from the original hold is returned to the guest's available credit.
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. The period starts from the day the Pre-Authorization Payment is created.
If you want to hold funds for longer, you can extend the holding period.
If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment.
The blocked amount returns back to the cardholder's credit:
-
if you don't capture the funds within the holding period
-
if you cancel a Pre-Authorization Payment (immediately after cancelling)
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
fields object
These are the fields of the recipient (also called "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "authorized",
"event_date": "2024-03-20T11:33:02Z",
"event_resource": "charges",
"data": {
"payment_id": "PTU146221637",
"amount_from": "4800",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "authorized",
"expiration_date": "2024-03-28T11:33:02Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card"
},
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
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:
A guest checks into a hotel for a three-night stay, and you place a pre-authorization on their credit card for the estimated cost of the stay.
Check-In: You pre-authorizes $600 on the guest's credit card ($150 per night plus $150 deposit). This reduces the guest's available credit by $600 but is not yet charged.
During the Stay: The guest orders room service for $50.
Check-Out: The final bill is $500 ($450 for room charges plus $50 for room service). You capture $500 from the pre-authorization. The remaining $100 from the original hold is returned to the guest's available credit.
The amount that is being held on the card has been adjusted.
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
The resource that has generated the notification.
Possible values:
-
payments
-
charges
dataobject
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
fields object
These are the fields of the recipient (also called "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "adjusted",
"event_date": "2024-03-20T11:33:02Z",
"event_resource": "charges",
"data": {
"payment_id": "PTU146221637",
"amount_from": "4800",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "adjusted",
"expiration_date": "2024-03-28T11:33:02Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card"
},
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
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:
-
Bank transfer: funds have been received in a Flywire bank account.
-
Card payments: funds have been captured in payer’s card.
-
Direct debit: instructions to capture the funds are in progress and correct.
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
Only for card payments.
The brand of the card. For example, Visa or Mastercard (MC).
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 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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "processed",
"event_date": "2021-05-20T11:25:02Z",
"event_resource": "charges",
"data": {
"payment_id": "TQQ146221637",
"amount_from": "4225",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "processed",
"expiration_date": "2021-05-31T11:24:45Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card",
"brand": "visa",
"card_classification": "credit",
"card_expiration": "08/2025",
"last_four_digits": "3878"
},
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
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.
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
Only for card payments.
The brand of the card. For example, Visa or Mastercard (MC).
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 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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "guaranteed",
"event_date": "2021-05-20T11:25:05Z",
"event_resource": "payments",
"data": {
"payment_id": "PTU146221637",
"amount_from": "4225",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "guaranteed",
"expiration_date": "2021-05-31T11:24:45Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card",
"brand": "visa",
"card_classification": "credit",
"card_expiration": "08/2025",
"last_four_digits": "3878"
},
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
The status changes from guaranteed to delivered when Flywiresent 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.
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
Only for card payments.
The brand of the card. For example, Visa or Mastercard (MC).
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.
payouts array
The portal code for this portal (also called recipient).
The portal code identifies the portal. The portal code has been assigned by Flywire when the portal has been set up.
Format:
Either: 3 letters (ABC)
Or: 5 alphanumeric characters, always starting with a letter (ABC1D)
The payout currency in ISO 4217 format.
The payout currency is the currency
The amount of this disbursement in your payout currency.
Only payments that are in status delivered have a disbursement ID.
The disbursement ID identifies a disbursement.
Format:
Either: ABC2025-12-17
3-letter portal/recipient ID disbursement date YYYY-MM-DD
Or: ABC1D2025-12-17
5-alphanum portal/recipient ID disbursement date YYYY-MM-DD
A disbursement is a bundle of payments that Flywire transfers into
Note if you are using refunds:
Disbursements can also contain refunds if you are using the refund collection method netting.
Netting refers to a method used to simplify transactions. By offsetting the value of multiple payments between you and Flywire into a single net amount, it reduces the number of individual transactions.
Simplified example: You have to pay Flywire $200 because you have to refund money to your payers. At the same time, Flywire has to pay you $500 because you have new payments incoming. Instead of exchanging $200 and $500 separately, netting combines these amounts and you'll receive only $300 from Flywire while Flywire takes no money from you.
Essentials about using netting as a refund collection method
-
Refunds will only be processed when Flywire has received enough funds from new payments to offset them against the pending refunds.
-
This means if the original recipient doesn't have a constant stream of new incoming payments, it can take a while before refunds are processed.
-
This refund collection method is not available by default, you need to set it up together with Flywire. Please contact the Solutions team if you want to use this method.
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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "delivered",
"event_date": "2021-05-20T11:48:02Z",
"event_resource": "payments",
"data": {
"payment_id": "TQQ146221637",
"amount_from": "4225",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "delivered",
"expiration_date": "2021-05-31T11:24:45Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card",
"brand": "visa",
"card_classification": "credit",
"card_expiration": "08/2025",
"last_four_digits": "3878"
},
"payouts": [
{
"portal_code": "TQQ",
"currency": "GBP",
"amount": "28300",
"disbursement_id": "SANDBOX-TQQ2024-04-18-1713458596"
}
],
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
The status failed can only occur for card
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
Only for card payments.
The brand of the card. For example, Visa or Mastercard (MC).
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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
The payment status
Cancelled means that the payment will not be processed. If Flywire already received the funds, Flywire will return the funds to the payer.
| Who cancelled? | Scenario | cancellation_reason in the payment status notification |
|---|---|---|
|
You |
You cancelled a payment via the API. A payment can only be cancelled when it is in status See Cancelling a payment |
cancelled_by_user |
| The payer |
Payers can cancel a payment in two different ways: For API integrations:
For Pay-By-Link and Checkout integrations:
Payer contacts Flywire:
|
cancelled_by_user |
| Flywire |
There can be different reasons why Flywire cancels a payment: |
|
|
Verification not passed The payment didn’t pass Flywire validations. If funds were captured, an automatic refund will be created and funds will be returned directly to the source of funds. |
rejected | |
|
Duplicate payment The payer created 2 payments by mistake, and Flywire closed one of them after identifying the duplicate issue. |
duplicated | |
|
You or the payer contacted Flywire to cancel the payment. |
cancelled_by_user | |
| Automatic cancellation - Payment expired |
When a payment expires it will automatically be cancelled. Expiring means the payment reached the expiration date without Flywire receiving the funds. A payment expires automatically after a while if no funds are received by Flywire:
The exact time within a payment expires depends on your individual settings that have been defined between you and Flywire.
|
expired |
| Direct debit payment failed |
When a direct debit payment fails while a payment is in status processed or guaranteed it will be cancelled. Note that if the direct debit payment is in status delivered and fails, it goes to status reversed instead. A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc. |
unpaid |
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
The ISO2 code of the payer country (the country the money was sent from).
The reason for the cancellation.
| Who cancelled? | Scenario | cancellation_reason in the payment status notification |
|---|---|---|
|
You |
You cancelled a payment via the API. A payment can only be cancelled when it is in status See Cancelling a payment |
cancelled_by_user |
| The payer |
Payers can cancel a payment in two different ways: For API integrations:
For Pay-By-Link and Checkout integrations:
Payer contacts Flywire:
|
cancelled_by_user |
| Flywire |
There can be different reasons why Flywire cancels a payment: |
|
|
Verification not passed The payment didn’t pass Flywire validations. If funds were captured, an automatic refund will be created and funds will be returned directly to the source of funds. |
rejected | |
|
Duplicate payment The payer created 2 payments by mistake, and Flywire closed one of them after identifying the duplicate issue. |
duplicated | |
|
You or the payer contacted Flywire to cancel the payment. |
cancelled_by_user | |
| Automatic cancellation - Payment expired |
When a payment expires it will automatically be cancelled. Expiring means the payment reached the expiration date without Flywire receiving the funds. A payment expires automatically after a while if no funds are received by Flywire:
The exact time within a payment expires depends on your individual settings that have been defined between you and Flywire.
|
expired |
| Direct debit payment failed |
When a direct debit payment fails while a payment is in status processed or guaranteed it will be cancelled. Note that if the direct debit payment is in status delivered and fails, it goes to status reversed instead. A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc. |
unpaid |
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.
|
|
direct_debit |
Payment is done via direct debit. |
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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "cancelled",
"event_date": "2021-05-20T11:33:02Z",
"event_resource": "payments",
"data": {
"payment_id": "PTU146221637",
"amount_from": "4225",
"currency_from": "EUR",
"amount_to": "5000",
"currency_to": "USD",
"status": "cancelled",
"expiration_date": "2021-05-31T11:24:45Z",
"external_reference": "a-reference",
"country": "ES",
"cancellation_reason": "cancelled_by_user",
"payment_method": {
"type": "card"
},
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
There are two types of reversed callbacks:
- Reversed type refund
- Reversed type unpaid
When a payment is in status
Delivered and returns a reversed callback, it means a refund for the payment has 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.
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
The type of the payment reversal.
Possible values:
-
refund
More info
When a payment is in status
Delivered and returns a reversed callback, it means a refund for the payment has 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.
-
unpaid
More info
Only 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 direct debit payment went into the delivered status (which means you received the funds from Flywire).
-
Then the direct debit payment fails and remains unpaid (which means Flywire did not receive the funds).
What does it mean when a direct debit payment is unpaid?
A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc.
-
Then Flywire will start a recovery process and the payment status will change from delivered to reversed.
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed.
-
The entity ID depends on the type of reversed callback.
The refund ID.
The refund ID is a unique reference generated by Flywire to identify a refund. It is generated for each refund after a refund
Format:
Either:RABC1AB23CD4
R 3-letter portal/recipient ID 8 hexadecimals
Or: R1ABC1D1AB23CD4
R number 5-alphanum portal/recipient ID 8 hexadecimals
The refund ID identifies a single refund within a refund bundle. The single refund starts with an R and the refund bundle it is part of starts with a BUDR.
Refunds
A refund is a way to return funds back to your payer via Flywire. You can define if you want to return the full amount (full refund) or just part of the amount (partial refund) of the original payment.
Refund Essentials: What You Should Know
-
A payment needs to be in status
Delivered before you can create a refund for it (see Payment Statuses for details about payment statuses). -
Each refund is connected to one payment, it is not possible to create one "shared" refund for multiple payments.
-
A payment can only have one active refund at a time. When the refund is done (in status finished) you can create a new refund for the payment.
-
The refunded amount, whether it's one full refund or several partial refunds added together, can't be more than the initial payment amount.
-
Refunds and bundles are recipient-specific. The settings for refunds (how the money will be collected, the cut-off time for refund bundles, and if approvals are needed for a bundle) depend on the recipient of the original payment.
-
A refund is always part of a refund bundle, even if the bundle only contains one refund. This means even if you only create one single refund, there will automatically be a refund bundle created for it.
Refund bundles
Flywire processes refunds collectively in refund bundles to streamline the reconciliation process. Bundling refunds means Flywire only needs to collect money from the original payment recipient once, reducing the number of transactions needed for refunds.
The refund bundle cycle
-
Creating a refund for recipient A automatically generates a refund bundle for recipient A.
-
Each recipient has a set cut-off time for their refund bundles. All refunds created for the recipient will be added to the bundle until the cut-off time is reached.
More details about the cut-off time
The cut-off time controls when Flywire starts to process pending refunds. Since Flywire processes refunds in bundles and not as single refunds, there is a time span where you can add more refunds to a bundle before it gets processed. For example, if the cut-off time is 1 day, you can add more refunds to the refund bundle for 1 day until Flywire starts processing it or - if your refund bundles need approval - until the bundle can be approved and then processed.
The cut-off time is set individually for each recipient. Please contact the Solutions team if you want to set or change the cut-off time for a recipient.
You can also specify a timezone when setting up the cut-off time for a recipient with Flywire. -
When the cut-off time for recipient A is reached, Flywire either processes the bundle or requires your approval first, based on the recipient's settings.
More details about approvals
All refund bundles must be approved before processing, but there is a difference between how they get approved. It depends on the settings for the recipient of the original payment which type of approval is needed:
Type of approval approval_type (setting for the recipient) Manual approval
Manual approvals create an extra step in processing refunds. Flywire waits for your approval before processing a refund bundle (see Approving a refund bundle).
manual Automatic approval
Flywire processes refund bundles automatically after the cut-off time.
automatic To add or change the settings for refund approvals of a recipient please contact the Solutions team.
For details about how to approve a refund bundle see see Approving a refund bundle.
-
Creating a refund for recipient A now creates a new bundle (no matter if the previous bundle is being processed or waiting for approval) and the cycle starts again.
Refund Bundle Essentials: What You Should Know
-
A refund bundle has a bundle ID that enables you to identify it and retrieve all refunds in this bundle.
-
Refunds and bundles are recipient-specific. The settings for refunds (how the money will be collected, the cut-off time for refund bundles, and if approvals are needed for a bundle) depend on the recipient of the original payment.
-
A refund is always part of a refund bundle, even if the bundle only contains one refund. This means even if you only create one single refund, there will automatically be a refund bundle created for it.
The reversed payment ID.
The reversed payment ID is a unique identifier for unpaid direct debit payments. It has the format REV_{payment reference}, for example REV_FLW356132734.
A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc.
reversed_amount object
The amount of the refund in the billing currency. This is the amount Flywire will take from the recipient to refund it back to the payer.
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 amount of the payment reversal in the billing currency. This is the amount Flywire will take from the recipient to cover the unpaid payment.
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.
currency object
The currency in which Flywire takes the funds back from the recipient (same as the recipient's 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 number of subunits of this currency's units, for example 100.
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 reason for the callback (Refund finished), indicates that this callback has been sent because a refund for the payment has been finished.
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. |
The Flywire code for a finished refund for a payment (106) .
Flywire error code for the error message why charging the payment failed.
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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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": "reversed",
"event_date": "2021-05-20T11:33:02Z",
"event_resource": "payments",
"data": {
"payment_id": "PTU146221637",
"amount_from": "4800",
"currency_from": "EUR",
"amount_to": "50000",
"currency_to": "USD",
"status": "reversed",
"expiration_date": "2021-05-31T11:24:45Z",
"external_reference": "a-reference",
"country": "ES",
"payment_method": {
"type": "card"
},
"reversed_type": "refund",
"entity_id": "RPTUDD91239F",
"reversed_amount": {
"value": "10000",
"currency": {
"code": "USD",
"subunit_to_unit": "100"
}
},
"reason": "Refund finished",
"reason_code": "106"
"recurring_id": "IPTQQ18ECD5B31AB",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"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]"
},
}
}
Only 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 direct debit payment went into the delivered status (which means you received the funds from Flywire).
-
Then the direct debit payment fails and remains unpaid (which means Flywire did not receive the funds).
What does it mean when a direct debit payment is unpaid?
A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc.
-
Then Flywire will start a recovery process and the payment status will change from delivered to reversed.
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed.
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 last part of a timestamp indicates the time zone:
-
Z → Means UTC (Coordinated Universal Time).
Example: 2024-09-20T14:30:00Z = 2:30 PM in UTC.
-
+hh:mm or -hh:mm → Offset from UTC.
Example: 2024-09-20T14:30:00+02:00 = 2:30 PM in a time zone 2 hours ahead of UTC (e.g., Central European Summer Time).
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 callback status.
For payments in status
Initiated:
| Status | 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. The period starts from the day the Pre-Authorization Payment is created. If you want to hold funds for longer, you can extend the holding period. If you want to release the block on the funds before the holding period ends, you can cancel the Pre-Authorization Payment. The blocked amount returns back to the cardholder's credit:
|
|
|
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 amount that is being held on the card has been adjusted. |
For payments in status
Processed:
| Status | Description |
|---|---|
|
|
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 payments in status
Guaranteed:
| Status | Description |
|---|---|
|
|
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. |
For payments in status
Delivered:
| Status | Description |
|---|---|
|
|
The status changes from guaranteed to delivered when Flywiresent 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. |
|
|
When a payment is in status This status tells you that a refund has successfully been completed for the payment. |
For payments in status
Failed:
| Status | Description |
|---|---|
|
|
The status failed can only occur for card |
For payments in status
Cancelled:
| Status | Description |
|---|---|
|
|
The payment status |
For payments in status
Reversed:
| Status | Description |
|---|---|
|
|
Only 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:
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed. |
The time and date the payment will expire automatically if no funds were received.
For card payments:
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. The period starts from the day the Pre-Authorization Payment is created.
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.
-
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 callbackId parameter when you created the payment.
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.
|
|
direct_debit |
Payment is done via direct debit. |
The type of the payment reversal.
Possible values:
-
refund
More info
When a payment is in status
Delivered and returns a reversed callback, it means a refund for the payment has 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.
-
unpaid
More info
Only 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 direct debit payment went into the delivered status (which means you received the funds from Flywire).
-
Then the direct debit payment fails and remains unpaid (which means Flywire did not receive the funds).
What does it mean when a direct debit payment is unpaid?
A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc.
-
Then Flywire will start a recovery process and the payment status will change from delivered to reversed.
Note that if the payment fails in an earlier status (processed or guaranteed) the payment will be cancelled instead of reversed.
-
The entity ID depends on the type of reversed callback.
The refund ID.
The refund ID is a unique reference generated by Flywire to identify a refund. It is generated for each refund after a refund
Format:
Either:RABC1AB23CD4
R 3-letter portal/recipient ID 8 hexadecimals
Or: R1ABC1D1AB23CD4
R number 5-alphanum portal/recipient ID 8 hexadecimals
The refund ID identifies a single refund within a refund bundle. The single refund starts with an R and the refund bundle it is part of starts with a BUDR.
Refunds
A refund is a way to return funds back to your payer via Flywire. You can define if you want to return the full amount (full refund) or just part of the amount (partial refund) of the original payment.
Refund Essentials: What You Should Know
-
A payment needs to be in status
Delivered before you can create a refund for it (see Payment Statuses for details about payment statuses). -
Each refund is connected to one payment, it is not possible to create one "shared" refund for multiple payments.
-
A payment can only have one active refund at a time. When the refund is done (in status finished) you can create a new refund for the payment.
-
The refunded amount, whether it's one full refund or several partial refunds added together, can't be more than the initial payment amount.
-
Refunds and bundles are recipient-specific. The settings for refunds (how the money will be collected, the cut-off time for refund bundles, and if approvals are needed for a bundle) depend on the recipient of the original payment.
-
A refund is always part of a refund bundle, even if the bundle only contains one refund. This means even if you only create one single refund, there will automatically be a refund bundle created for it.
Refund bundles
Flywire processes refunds collectively in refund bundles to streamline the reconciliation process. Bundling refunds means Flywire only needs to collect money from the original payment recipient once, reducing the number of transactions needed for refunds.
The refund bundle cycle
-
Creating a refund for recipient A automatically generates a refund bundle for recipient A.
-
Each recipient has a set cut-off time for their refund bundles. All refunds created for the recipient will be added to the bundle until the cut-off time is reached.
More details about the cut-off time
The cut-off time controls when Flywire starts to process pending refunds. Since Flywire processes refunds in bundles and not as single refunds, there is a time span where you can add more refunds to a bundle before it gets processed. For example, if the cut-off time is 1 day, you can add more refunds to the refund bundle for 1 day until Flywire starts processing it or - if your refund bundles need approval - until the bundle can be approved and then processed.
The cut-off time is set individually for each recipient. Please contact the Solutions team if you want to set or change the cut-off time for a recipient.
You can also specify a timezone when setting up the cut-off time for a recipient with Flywire. -
When the cut-off time for recipient A is reached, Flywire either processes the bundle or requires your approval first, based on the recipient's settings.
More details about approvals
All refund bundles must be approved before processing, but there is a difference between how they get approved. It depends on the settings for the recipient of the original payment which type of approval is needed:
Type of approval approval_type (setting for the recipient) Manual approval
Manual approvals create an extra step in processing refunds. Flywire waits for your approval before processing a refund bundle (see Approving a refund bundle).
manual Automatic approval
Flywire processes refund bundles automatically after the cut-off time.
automatic To add or change the settings for refund approvals of a recipient please contact the Solutions team.
For details about how to approve a refund bundle see see Approving a refund bundle.
-
Creating a refund for recipient A now creates a new bundle (no matter if the previous bundle is being processed or waiting for approval) and the cycle starts again.
Refund Bundle Essentials: What You Should Know
-
A refund bundle has a bundle ID that enables you to identify it and retrieve all refunds in this bundle.
-
Refunds and bundles are recipient-specific. The settings for refunds (how the money will be collected, the cut-off time for refund bundles, and if approvals are needed for a bundle) depend on the recipient of the original payment.
-
A refund is always part of a refund bundle, even if the bundle only contains one refund. This means even if you only create one single refund, there will automatically be a refund bundle created for it.
The reversed payment ID.
The reversed payment ID is a unique identifier for unpaid direct debit payments. It has the format REV_{payment reference}, for example REV_FLW356132734.
A direct debit payment can fail when it was initiated but the Flywire partner (for example, the bank) could not retrieve the funds from the payer's bank account, which means the payment remains unpaid and Flywire doesn't receive the funds. There can be different reasons for this, for example due to insufficient funds, payment was cancelled by the bank, account is closed, wrong account number, payer cancelled the payment, etc.
reversed_amount object
The amount of the refund in the billing currency. This is the amount Flywire will take from the recipient to refund it back to the payer.
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 amount of the payment reversal in the billing currency. This is the amount Flywire will take from the recipient to cover the unpaid payment.
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.
currency object
The currency in which Flywire takes the funds back from the recipient (same as the recipient's 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 number of subunits of this currency's units, for example 100.
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 reason for the callback (Refund finished), indicates that this callback has been sent because a refund for the payment has been finished.
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. |
The Flywire code for a finished refund for a payment (106) .
Flywire error code for the error message why charging the payment failed.
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 "
Custom fields are fields that are specific to your portal.
These fields are defined when the recipient (portal) is set up by Flywire.
payer object
The payer information is not automatically included. Returning payer information is disabled by default and needs to be enabled by Flywire.
Please reach out to your Flywire contact 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":"reversed",
"event_date":"2023-04-28T12:02:23Z",
"event_resource":"payments",
"data":{
"payment_id":"ALA356132734",
"amount_from":"14700",
"currency_from":"USD",
"amount_to":"14700",
"currency_to":"USD",
"status":"reversed",
"expiration_date":"2023-05-09T12:01:22Z",
"external_reference":"0a78cc69-585f-4250-b368-1fa990a463b3",
"country":"US",
"payment_method":{
"type":"direct_debit"
},
"reversed_type": "unpaid",
"entity_id": "REV_ALA356132734",
"reversed_amount": {
"value": "14700",
"currency": {
"code": "USD",
"subunit_to_unit": "100"
}
},
"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",
"recurring_id": "IPALA356132734",
"fields":{
"booking_reference": "ID123456",
"booking_description": "A description"
},
"payer": {
"first_name": "Peter",
"last_name": "Payer",
"middle_name": null,
"address1": "456 Elm Street",
"address2": null,
"city": "Springfield",
"country": "US",
"state": "IL",
"zip": "62701",
"phone": "0012175556789",
"email": "[email protected]"
},
}
}
How to set up Payment Status Notifications
This information only applies to callbacks that return information about payments. Callbacks for Payment Requests are set up in a different way.
Types of Notification URLs
There are two different URLs for receiving callbacks:
Static URL
A static callback URL is a fixed URL defined in your portal. All payments for this portal will send callbacks to this URL.
The static callback URL has been defined when your portal was set up. If you don't use a static callback URL yet and want to start using it, please reach out to your Flywire contact.
Dynamic URL
A dynamic callback URL is a URL that you define when you create the payment. Since this URL can be different for every payment you create, it is called dynamic. You define the URL for the
Checkout integration via the callbackUrl parameter.
If you want to receive callbacks, it is required to provide both a callback URL and a callback ID, otherwise no callbacks will be triggered.
You must also set the callback version to 2.
You cannot provide a dynamic callback URL for payments that are part of a Payment Request. To receive callbacks about those payments, you have to use the static URL. Alternatively, you can use callback notifications for Payment Request status updates, but note that the content of those callbacks is different from payment status callbacks.
How defining static and dynamic URLs affect callbacks
= not set |
= set |
| Static URL |
Dynamic URL |
Result |
|
|
You won't receive callbacks . |
|
|
You'll receive callbacks to your static URL. You'll also receive callbacks for payments that are part of Payment Requests. |
|
|
You'll receive callbacks to both URLs. You'll also receive callbacks for payments that are part of Payment Requests, but only to the static URL. |
|
|
You'll receive callbacks to your dynamic URL You will not receive callbacks for payments that are part of Payment Requests since there is no static URL. |
Parameters for Payment Status Notifications Settings
You'll encounter two parameters that influence the payment status notifications for a payment whenever you are creating a payment.
-
For 529 Payments:
-
Creating an Order (defines the parameters for the payment) and then Charging an Order (Creating a Payment) (creates the payment with the defined parameters). Note that it is possible to change the parameters before charging by Editing an Order.
-
-
For self-managed recurring payments:
-
When the first payment gets charged immediately via the Checkout Session.
-
When you already have the payment method token and mandate ID: Creating a Payment with a Token
-
-
For Flywire-hosted recurring payments:
-
You don't create the payments yourself, Flywire creates the payments for you. You start the plan that contain the payments by creating a Checkout Session.
-
-
For One Off Payments:
-
By creating a Checkout Session.
-
| Parameter | Description | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
external_reference string |
The external reference helps you to identify a payment, since the Flywire-generated payment reference might not be the way you typically identify payments. With the external reference, you can enter your own identifier, such as an ID or invoice number. The external reference is included in all status notifications to help you map a payment to a callback notification. (see Payment Status Notifications) |
||||||||||||||||||
|
notifications_url string (url) |
The notifications URL enables you to receive callbacks about the payment status (see Payment Status Notifications). The notifications URL is the dynamic URL for receiving callbacks. There are two different URLs for receiving callbacks: Static URL
Dynamic URL
How defining static and dynamic URLs affect callbacks
If you are using the Checkout or Pay-By-Link integration: If you want to receive callbacks, it is required to provide both a callback URL and a callback ID, otherwise no callbacks will be triggered. You must also set the callback version to 2. |
Failed notifications: What happens if a callback can't get delivered?
When Flywire tries to send a notification to the callback URL you provided and receives an error, there will automatically three re-attempts:
-
First time with a delay of 180 seconds (3 minutes)
-
Second time with a delay of 1800 seconds (30 minutes)
-
Third time with a delay of 10800 seconds (3 hours)
Failed callback report
Flywire logs all failed callback sending attempts. If after the third try sending the callback is still unsuccessful, Flywire sends a failed callback report to an approved contact for review. You as a client must provide the contact details for someone to receive the failed callback report.
Validating Payment Status Notifications
Validating notifications is optional, as it’s on your server side, but for security reasons it is recommended to validate all notifications.
How to validate a notification
To validate a notification, check its X-Flywire-Digest header. This value is generated by Flywire using your Shared Secret to encrypt the notification body. To verify the notification, generate the digest using the same method and compare it to the X-Flywire-Digest value in the header. If they match, the notification is legitimate and hasn't been tampered with.
- Step-by-step Guide
- Full Node.js Example
- PHP Example
-
Retrieve the raw HTTP body of the notification you received.
Make sure you use the raw HTTP body of the notification. You must generate the X-Flywire-Digest value using the exact payload you received in the notification. If you change the body in any way the values won't match later.
-
Encrypt the received notification twice:
1) Encrypt the raw HTTP body of the received notification with your Shared Secret using the SHA-256 algorithm.
2) Take the result and encrypt it in Base64.
The examples show you how to do this in different programming languages. In each example, exchange the shared_key with your Shared Secret and message_body with the raw HTTP body of the notification.
What is my Shared Secret?
For API integration:
Your Shared Secret is used to validate notifications. You receive your Shared Secret together with your API credentials via a secure email after you registered your application.
For other integrations:
A Shared Secret is a string of characters that is used to authenticate requests and validate callbacks. Note that each portal might have a different shared secret. If you have access to multiple portals within your company, make sure you use the correct shared secret for each portal. Please reach out to your Flywire contact to get the shared secret for a portal.
- Ruby
- .NET
- JavaScript
digest = OpenSSL::Digest.new('sha256') encrypted_payload = OpenSSL::HMAC.digest(digest, shared_secret, notification_body) Base64.encode64(encrypted_payload).strip # Step 1: Define the hashing algorithm to use for the HMAC. # This initializes the SHA-256 hashing mechanism. hash_algorithm = OpenSSL::Digest.new('sha256') # Step 2: Compute the HMAC in binary format. # This uses the shared secret and the message body to produce the HMAC signature. hmac_binary = OpenSSL::HMAC.digest(hash_algorithm, shared_secret, message_body) # Step 3: Encode the HMAC in Base64 for use in the X-Flywire-Digest header. x_flywire_digest = Base64.encode64(hmac_binary).strippublic static string Digest(string shared_secret, string message_body) { // Step 1: Initialize the HMACSHA256 object with the shared secret. // This sets up the hashing algorithm (SHA-256) and the secret key for HMAC. using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(shared_secret))) { // Step 2: Convert the message body into a byte array. // The message body is the message payload you want to hash var bytes = Encoding.UTF8.GetBytes(message_body); // Step 3: Compute the HMAC hash of the message body. // This generates the HMAC using the shared secret and the message body. var hashedBytes = hmacsha256.ComputeHash(bytes); // Step 4: Convert the hashed byte array into a Base64 string. return Convert.ToBase64String(hashedBytes); } }const crypto = require('crypto'); function createDigest(shared_secret, message_body) { // Step 1: Initialize the HMAC with the SHA-256 algorithm and the shared secret. const hmac = crypto.createHmac('sha256', shared_secret); // Step 2: Update the HMAC with the message body. // The message body is the message payload you want to hash hmac.update(message_body); // Step 3: Get the HMAC digest and encode it in Base64. const digestHeader = hmac.digest('base64'); return digestHeader; // The `digestHeader` is the X-Flywire-Digest header. } -
Compare your Base64 string to the value in the X-Flywire-Digest parameter of the notification you received.
If the values match, the notification came from Flywire and hasn't been changed by a third party.
If the values don't match, you shouldn't trust the notification.
// Import the Express framework for setting up the server and the crypto library for hashing
const express = require("express");
const crypto = require("crypto");
const app = express(); // Create an Express app
const port = 3000; // Define the port the server will listen on
// PART 1: Server Setup
// Listen for incoming requests on the specified port
app.listen(port, () => {
console.log(`Example Flywire Webhook App listening on port ${port}`);
});
// PART 2: Middleware and Routing
// Use express.raw middleware to treat incoming JSON data as raw data (needed for HMAC verification)
app.use(express.raw({ type: "application/json" }));
// Define a route that will handle POST requests sent to /flywire-notification
app.post("/flywire-notification", (req, res) => {
// Extract the raw request body and the digest header from the incoming request
const payload = JSON.stringify(req.body); // Convert raw request body to JSON string
const requestDigest = req.header("X-Flywire-Digest"); // Retrieve the digest header from Flywire
const sharedSecret = "YOUR SHARED SECRET"; // Define the shared secret for HMAC hashing
// PART 3: Verification
// Generate a digest using the payload and shared secret, matching Flywire's HMAC-SHA256 and Base64 encoding
const serverDigest = digest(payload, sharedSecret);
// Compare the digests to verify if the request is from Flywire
if (requestDigest === serverDigest) {
// Parse the payload and process data if verification is successful
const data = JSON.parse(payload).data;
console.log(`Processing notification: ${data.payment_id} - ${data.status}`);
}
// Send a 200 OK response back to Flywire indicating the request was processed
res.sendStatus(200);
});
// Helper function to create a digest (HMAC-SHA256 + Base64) from the data and shared secret
function digest(data, sharedSecret) {
const hmac = crypto.createHmac("sha256", sharedSecret); // Create HMAC using SHA256
hmac.update(data); // Update with the data (payload)
return hmac.digest("base64"); // Return the digest in Base64 format
}
<?php
// Read the raw incoming data from the request body
$data = file_get_contents('php://input');
// Define the shared secret for verifying the request authenticity
$sharedSecret = "YOUR SHARED SECRET";
// Retrieve the 'X-Flywire-Digest' header from the incoming request
$requestDigest = getHeader("X-Flywire-Digest");
// Generate the server's own digest from the incoming data and shared secret
$serverDigest = digest(trim($data), $sharedSecret);
// Compare the request digest with the server's digest to verify authenticity
if ($requestDigest == $serverDigest) {
// Process notification (only if the verification passed)
}
// Function to create an HMAC-SHA256 digest and encode it in Base64
function digest($data, $secret) {
$digest = hex2bin(hash_hmac('sha256', $data, $secret)); // Create HMAC hash
return trim(base64_encode($digest)); // Encode the hash in Base64
}
// Helper function to retrieve a specific header from the request
function getHeader($header) {
foreach (getallheaders() as $name => $value) { // Loop through all headers
if ($name == $header) { // Check if the header matches
return $value; // Return the header value if matched
}
}
}
?>
= not set
= set