Installment Plan Status Notifications
Installment plan status notifications enable you to track the progress of a plan.
How do I get started?
-
For testing notifications: See Flywire API Sandbox
-
For your production environment: See How to set up Installment Plan Status Notifications.
Installment Plan Statuses
Status | Notification | Description |
---|---|---|
in_progress |
![]() |
The installment plan has started and is in progress. Payments will be created by Flywire according to the plan. You will receive notifications for each payment of the plan under the same notifications URL you provided for the plan, see Payment Status Notifications for details about those notifications. |
finished |
![]() |
The installment plan has been successfully completed, meaning the total amount has been paid. While you are getting this notification, your payer will get an email from Flywire informing them that the installment plan has successfully completed. |
cancelled |
![]() |
The installment plan has been cancelled. Cancelling an installment plan means the plan was stopped before the total amount was paid. No more payments will be created for this plan. ![]()
|
Content of Installment Plan Status Notifications
-
In Progress
-
Finished
-
Cancelled

Type of the event (status change).
Possible types:
in_progress |
The installment plan has started and is in progress. Payments will be created by Flywire according to the plan. You will receive notifications for each payment of the plan under the same notifications URL you provided for the plan, see Payment Status Notifications for details about those notifications. |
finished |
The installment plan has been successfully completed, meaning the total amount has been paid. While you are getting this notification, your payer will get an email from Flywire informing them that the installment plan has successfully completed. |
cancelled |
The installment plan has been cancelled. Cancelling an installment plan means the plan was stopped before the total amount was paid. No more payments will be created for this plan. ![]()
|

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

The resource that has generated the notification.
Possible values:
-
recurring_installment_plan

The external reference.
The external reference is used to match a notification to an installment plan. All payments belonging to the plan will also use this external reference. It is included in notifications about the installment plan and all payments belonging to the plan. You can use any kind of identifier or reference from your own system that helps you identify the plan and its payments. Max size of 50 characters.
For tracking installment plans via notifications see Installment Plan Status Notifications.
For tracking payments via notifications see Payment Status Notifications.

The number of installments of this installment plan.
data object

The plan ID.
A plan ID is the unique identifier for a Flywire installment plan.
Format:
IPABC18EADF349BE
IP3-letter portal/recipient ID11 characters

The date when the installment plan starts.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The date when the installment plan ends.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The payer currency in ISO 4217 format.


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 in ISO 4217 format.

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

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

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

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

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

The last four digits of the card number or bank account number.
{
"event_type": "in_progress",
"event_date": "2024-04-04T13:47:11Z",
"event_resource": "recurring_installment_plan",
"callback_id": "My reference",
"number_of_installments": 10
"data": {
"id": "IPLRP18EA95D0A57",
"start_date": "2024-04-04T13:46:30Z",
"end_date": "2025-01-04T14:46:30Z",
"currency_from": "USD",
"amount_to": 500000,
"currency_to": "CAD",
"payment_method": {
"type": "card",
"brand": "VISA",
"card_classification": "credit",
"card_expiration": "3/2030",
"last_four_digits": "1111"
}
}

Type of the event (status change).
Possible types:
in_progress |
The installment plan has started and is in progress. Payments will be created by Flywire according to the plan. You will receive notifications for each payment of the plan under the same notifications URL you provided for the plan, see Payment Status Notifications for details about those notifications. |
finished |
The installment plan has been successfully completed, meaning the total amount has been paid. While you are getting this notification, your payer will get an email from Flywire informing them that the installment plan has successfully completed. |
cancelled |
The installment plan has been cancelled. Cancelling an installment plan means the plan was stopped before the total amount was paid. No more payments will be created for this plan. ![]()
|

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

The resource that has generated the notification.
Possible values:
-
recurring_installment_plan

The external reference.
The external reference is used to match a notification to an installment plan. All payments belonging to the plan will also use this external reference. It is included in notifications about the installment plan and all payments belonging to the plan. You can use any kind of identifier or reference from your own system that helps you identify the plan and its payments. Max size of 50 characters.
For tracking installment plans via notifications see Installment Plan Status Notifications.
For tracking payments via notifications see Payment Status Notifications.
data object

The plan ID.
A plan ID is the unique identifier for a Flywire installment plan.
Format:
IPABC18EADF349BE
IP3-letter portal/recipient ID11 characters

The number of installments of this installment plan.

The date when the installment plan starts.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The date when the installment plan ends.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The total amount of all payments of the installment plan.

The billing currency in ISO 4217 format.

The billing currency is the currency in which the recipient of the payment is billing their payer. The billing currency depends on the
{
"event_type": "finished",
"event_date": "2023-09-08T1429Z",
"event_resource": "recurring_installment_plan",
"callback_id": "My reference"
"data": {
"id": "IPLRP18EA95D0A57",
"number of installments": 4,
"start_date": "2023-09-30T00:00:00Z",
"end_date": "2023-10-30T00:00:00Z"
"total_amount": "1000000"
"currency":"USD"
}
}

Type of the event (status change).
Possible types:
in_progress |
The installment plan has started and is in progress. Payments will be created by Flywire according to the plan. You will receive notifications for each payment of the plan under the same notifications URL you provided for the plan, see Payment Status Notifications for details about those notifications. |
finished |
The installment plan has been successfully completed, meaning the total amount has been paid. While you are getting this notification, your payer will get an email from Flywire informing them that the installment plan has successfully completed. |
cancelled |
The installment plan has been cancelled. Cancelling an installment plan means the plan was stopped before the total amount was paid. No more payments will be created for this plan. ![]()
|

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

The resource that has generated the notification.
Possible values:
-
recurring_installment_plan

The external reference.
The external reference is used to match a notification to an installment plan. All payments belonging to the plan will also use this external reference. It is included in notifications about the installment plan and all payments belonging to the plan. You can use any kind of identifier or reference from your own system that helps you identify the plan and its payments. Max size of 50 characters.
For tracking installment plans via notifications see Installment Plan Status Notifications.
For tracking payments via notifications see Payment Status Notifications.

The number of installments of this installment plan.

The amount that has already been paid before the plan got cancelled. The amount is 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.
data object

The plan ID.
A plan ID is the unique identifier for a Flywire installment plan.
Format:
IPABC18EADF349BE
IP3-letter portal/recipient ID11 characters

The date when the installment plan starts.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The date when the installment plan ends.
Timestamps use ISO 8601 format with UTC (YYYY-MM-DDTHH:MM:SSZ, e.g., 2025-03-31T13:21:27Z).

The payer currency in ISO 4217 format.


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 in ISO 4217 format.

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

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

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

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

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

The last four digits of the card number or bank account number.
{
"event_type": "cancelled",
"event_date": "2024-04-04T13:47:11Z",
"event_resource": "recurring_installment_plan",
"callback_id": "My reference",
"number_of_installments": 10,
"amount_paid" : "2000",
"data": {
"id": "IPLRP18EA95D0A57",
"start_date": "2024-04-04T13:46:30Z",
"end_date": "2025-01-04T14:46:30Z",
"currency_from": "USD",
"amount_to": 500000,
"currency_to": "CAD",
"payment_method": {
"type": "card",
"brand": "VISA",
"card_classification": "credit",
"card_expiration": "3/2030",
"last_four_digits": "1111"
},
}
}
How to set up Installment Plan Status Notifications
When you are creating an installment plan (see Checkout Sessions - Flywire-Managed Recurring Payments), you'll encounter two parameters that influence the status notifications:
Parameter | Description |
---|---|
external_reference string |
The external reference. The external reference is used to match a notification to an installment plan. All payments belonging to the plan will also use this external reference. It is included in notifications about the installment plan and all payments belonging to the plan. You can use any kind of identifier or reference from your own system that helps you identify the plan and its payments. Max size of 50 characters. The external reference is called callback_id in the installment plan notifications.
For tracking installment plans via notifications see Installment Plan Status Notifications. For tracking payments via notifications see Payment Status Notifications. |
notifications_url string (url) |
The notifications URL to receive callbacks for the installment plan and all payments belonging to this plan. For tracking installment plans via notifications see Installment Plan Status Notifications. For tracking payments via notifications see Payment Status Notifications. |
Validating Installment Plan 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.
-
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?
The Shared Secret is a string of characters used for security validations.
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:
Your Shared Secret is used to validate notifications and authenticate requests. You receive your Shared Secret from the Flywire Solutions team after your portal has been set up (please contact the Solutions team in case you don't have your Shared Secret). Note that each portal might have a different shared secret. If you have access to multiple portals, make sure you use the correct shared secret for each 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).strip
public 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.