Checkout for Flywire-Managed Recurring Payments
With Flywire-managed recurring payments, you use Flywire's pre-defined installment plans. You only have to configure the plan settings (for example the number of installments) in Flywire Dashboard, Flywire will take care of the rest.
Since Flywire knows your plan settings, payments get initiated automatically according to the schedule.
Flywire also manages all emails to your payers on your behalf - these are mandatory to inform them about the recurring payments.
You need access to Flywire Dashboard to define the settings for the plans. If you don't have access yet, contact your Relationship Manager.
Available payment methods:
-
Card
How do Checkout Sessions of this type work?
-
You have to create a Checkout Session to either generate a URL or a session ID, depending on your implementation.
-
Your payer accesses the UI Form on your website where they fill it out and confirm it.
-
You get a postMessage via the event listener that contains a URL for confirming the Checkout Session.
-
You receive the installment plan ID in the response.
Creating a Checkout Session for Flywire-Managed Recurring Payments
Request
Parameters for the Request Body

The type of the Checkout Session. Must be recurring.
charge_intent object

Must be installment.
payor object
You have the option to pass payer information to pre-fill the fields of the UI form.
For a description of all fields and their valid values form see:
-
Payment Element if you are using Flywire Elements
-
Checkout Experience if you are using Checkout

Before pre-filling the payer fields, consider your use case and who the actual payer will be. The UI forms collect the card holder or bank account owner information. There can be cases when this person is different from the payer in your system.
For example, if you are a school and your system stores information about a student, you consider the student as the “payer”. But the person who actually pays could be the student’s parent. In this case, it would not make sense to pre-fill the fields with the student’s information, since the card holder is a different person. On the other hand, the payer can always edit the fields in the UI form, which means even if you are pre-filling the fields with the wrong details the payer can always correct them.
In order to create the best payment experience for your payers, consider which information you store in your system and how useful it is for them when fields are already filled out.
options object
Contains settings for the UI form.
form object

The language you want to translate the form to. The localization affects the labels of the form fields and the action button.
The default is English (“en”).

Language | Value for locale |
---|---|
English | en |
Spanish | es-ES |
Chinese | zh-CN |
Korean | ko |
Portuguese | pt-PT |
Japanese | ja |
French | fr-FR |
Bahasa Indonesia | id |
Arabic | ar |
Vietnamese | vi |
Italian | it-IT |
German | de-DE |

The show_payor_information parameter gives you the option to skip the payer information page of the form. This shortens the time your payer has to interact with the form if you already provided all the necessary information. If you skip the page, the page for selecting the payment method is shown immediately.
If you don't provide the parameter, the payer information page is shown by default.
Note:
-
If you want to skip the page, all mandatory payer information fields must be pre-filled by you.
-
If field values are missing or are invalid, the payer information page will be displayed so that the payer can add or correct the information.
Possible values:
-
true default, payer information page is displayed
-
false payer information page is not displayed, page for selecting the payment method is shown immediately
recipient object
Contains the fields of the recipient.
fields array
It depends on the recipient which fields are optional or required. If a field is required, you must provide it here. Optional fields can be left out.

You can check which fields are required for a recipient with this request (replace {recipientId} with the recipient ID):
Required fields have the required parameter set to true. For more info see Getting Details about a Recipient.

Identifier of the field.

The value for this field.
items array

An item is something that your payer can pay for (for example: tuition fees, housing, etc.). When you create a payment, you display the items to your payer and they can choose for which items they want to pay. How many items there are depends on the recipient's configuration.

You can only use one item in this request. The id
of the item must be called default
.

Identifier of the item.
You can only use one item in this request. The id
of the item must be called default
.

The amount for this item 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 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
For API integrations:
When you set up your application that accesses the Flywire API, you had the option to define a notifications URL. This is the static notifications URL. Callbacks will be sent to this URL for all payments you created via the Flywire API.
The recipient of a payment may also have a static notifications URL defined which might be different from your static notifications URL as a client. In that case, callbacks will also be sent to the recipient's notifications URL.For other integrations:
When you set up your portal together with Flywire, you had the option to define a callback URL for that portal. Callbacks will be sent to this URL for all payments for this portal.
If you don't use a static callback URL yet and want to start using it, please contact the Solutions team.
Dynamic URL
The URL you can set in a parameter when you are creating a payment is the dynamic notifications URL. Since this URL can be different for every payment you create, it is called dynamic.
How defining static and dynamic URLs affect callbacks
![]() |
![]() |
Static URL |
Dynamic URL |
Result |
![]() |
![]() |
You won't receive notifications. |
![]() |
![]() |
You'll receive notifications to your static URL. |
![]() |
![]() |
For API integrations: The dynamic URL will override the static URL and you'll receive notifications only to the dynamic URL. For other integrations: You'll receive callbacks to both URLs. This is called "dual callback URL". A dual callback URL means you defined a static URL in your portal and you are sending callbacks to a different callback URL via the parameter for the payment. In this case, callbacks will be sent to both URLs. This
approach can be useful if you want to update two separate systems.
|
![]() |
![]() |
You'll receive notifications to your dynamic URL |

The external reference.
The external reference is used to match a notification to a particular payment. You can use any kind of identifier or reference from your own system you might need to identify the payment.

The recipient ID.
The recipient ID is the unique three-letter ID that identifies the recipient, for example FWU for Flywire University. The recipient ID has been assigned by Flywire when the recipient has been set up.

You can use this request to get a list of all recipients that are available to you as a client and what their recipient ID is:
For details see Getting a List of all available Recipients.

The payor_id depends on how you want to uniquely identify a payer. Usually, you use an ID from another system, for example your ERP. Spaces are not allowed.
curl https://base-url-placeholder/checkout/sessions
-X POST
-H "Content-Type: application/json"
-H "X-Authentication-Key: {api_key}"
-d '{
"type": "recurring",
"charge_intent": {
"mode": "installment"
},
"payor": {
"first_name": "Peter",
"last_name": "Payer",
"address": "123 High Street",
"city": "London",
"country": "GB",
"state": "",
"phone": "0044123456789",
"email": "[email protected]",
"zip": "SW1A 1AA"
},
"options": {
"form": {
"locale": "en",
"show_payor_information": true
}
},
"recipient": {
"fields": [
{
"id": "custom_field_1",
"value": "ID12345"
},
{
"id": "custom_field_2",
"value": "2020"
}
]
},
"items": [
{
"id": "default",
"amount": 33000
}
],
"notifications_url": "https://webhook.site/9bf9cf8d-1d8c-46d1-b147-ca5841ff2ede",
"external_reference": "My payment reference",
"recipient_id": "TQQ",
"payor_id": "my_payer_ID"
}
Response
- Response with no warnings
- Response with warnings

The Checkout Session ID.
This is the session ID you need if you are using Flywire Elements with Smart Rendering or Checkout as Javascript with API.

Smart Rendering means you render Flywire Elements on your website with the help of the Flywire SDK script.
Extensive customization
-
Select which payer fields to display.
-
Customize the appearance, such as fonts and colors.
-
Choose the language.
Responsive layout
Optimized responsive layout for desktop and mobile devices.
Easy event handling
Simply define what should happen in case of success or errors - no need to filter individual postMessages.

The time before the Checkout Session expires in seconds.
hosted_form object
Only relevant when you render the form via iframe. More info:
-
iframe rendering for Flywire Elements
-
iframe rendering for Checkout

The hosted-form-URL. This is the URL your iframe displays.

The method (GET).
warnings array

The field where the error occurred.
For a description of all fields and their valid values form see:
-
Payment Element if you are using Flywire Elements
-
Checkout Experience if you are using Checkout
errors array
You can decide which information from the response you want to filter out in your backend before passing the URL to your frontend.

The error text.

The error type.
{
"id": "494d2e9d-c0c9-407c-9094-5b3b2a02c00f",
"expires_in_seconds": 1800,
"hosted_form": {
"url": "https://payment-checkout-dev-apache.flywire.cc/v1/form?session_id=494d2e9d-c0c9-407c-9094-5b3b2a02c00f",
"method": "GET"
},
"warnings": []
}
When are warnings returned?
If the warning array contains warnings, it means that you tried to pre-fill the UI form with invalid values. You can use these warnings to check the data in your system for mistakes.
Are warnings an error?
No, warnings inform you of issues with field values, but you will still receive the URL and can display the form to your payer.
How do the warnings affect the form?
If a drop down field (like country) is affected by invalid values, the field will be empty, meaning no selection from the drop down is made yet. Your payer has to select the value from the drop down manually.

The Checkout Session ID.
This is the session ID you need if you are using Flywire Elements with Smart Rendering or Checkout as Javascript with API.

Smart Rendering means you render Flywire Elements on your website with the help of the Flywire SDK script.
Extensive customization
-
Select which payer fields to display.
-
Customize the appearance, such as fonts and colors.
-
Choose the language.
Responsive layout
Optimized responsive layout for desktop and mobile devices.
Easy event handling
Simply define what should happen in case of success or errors - no need to filter individual postMessages.

The time before the Checkout Session expires in seconds.
hosted_form object
Only relevant when you render the form via iframe. More info:
-
iframe rendering for Flywire Elements
-
iframe rendering for Checkout

The hosted-form-URL. This is the URL your iframe displays.

The method (GET).
warnings array

The field where the error occurred.
For a description of all fields and their valid values form see:
-
Payment Element if you are using Flywire Elements
-
Checkout Experience if you are using Checkout
errors array
You can decide which information from the response you want to filter out in your backend before passing the URL to your frontend.

The error text.

The error type.
{
"id": "e6bf6f63-46e0-4bd7-9bce-8106c02d0b3f",
"expires_in_seconds": 1800,
"hosted_form": {
"url": "https://payment-checkout-dev-apache.flywire.cc/v1/form?session_id=e6bf6f63-46e0-4bd7-9bce-8106c02d0b3f",
"method": "GET"
},
"warnings": [
{
"source": "email",
"errors": [
{
"text": "must be a valid email",
"error_type": "invalid_email"
}
]
}
]
}
The Payer's side: Filling out and sending the UI Form
After you created the Checkout Session, your payer accesses the UI Form on your website. Depending on the UI Form, your payer goes through different steps to fill it out and send it.
What does my payer see?
Your payer sees the Flywire-Plans form that collects the payer information.

After entering their information, your payer is asked to pick the installment plan (number of installments) and the payment method they want to use.

Your payer is then asked to either create a Flywire account or log into an existing one.

After creating an account or logging into an existing one, your payer sees an overview of the plan they choose.

Your payer is then asked to enter their card information to pay for the payments.

An installment plan with the information provided is now created. The window will close automatically after a few seconds.

The postMessage of the Event Listener
After your payer sent the form, the event listener will return a successful postMessage. The postMessage contains the following information:
confirm_url object
Contains the confirm URL. The confirm URL is the full url for the request to confirm the session, already resolved with the correct session ID.

The method (POST).

The confirm URL. The confirm URL is the full url for the request to confirm the session, already resolved with the correct session ID.
payor object
The email address your payer entered in the UI Form.

This parameter helps you filter the PostMessages to only return the result of the Checkout Session. This is only necessary when you render via iframe (see Implementing the Payment Element for Elements and Implementing the Checkout Experience for Checkout).

The plan ID.
A plan ID is a unique identifier for a Flywire installment plan. A plan ID always starts with IP ("Installment Plan") followed by the recipient ID and 11 random characters.
Example: IPTQQ18EADF349BE

Indicates if the Checkout Session was successful.
true: Checkout Session successful
false: Checkout Session failed
You can use this parameter to filter the PostMessages to only return successful ones. This is only necessary when you render via iframe (see Implementing the Payment Element for Elements and Implementing the Checkout Experience for Checkout).
{
confirm_url: {
method: "POST",
url: "https://api-platform.flywire.com/payments/v1/checkout/sessions/494d2e9d-c0c9-407c-9094-5b3b2a02c00f/confirm",
},
payor: {
email: "[email protected]"
},
source: "checkout_session",
plan_id: "IPTQQ18EADF349BE",
success: true,
}
Confirming a Checkout Session
Request
As a security measure to ensure that you are the one who created the session, you have to confirm the Checkout Session.
How to Resolve the Path Placeholders of the Endpoint
You don't need to manually resolve the {ID} in the endpoint, as Flywire provides the fully resolved URL via postMessage.
Why should I use the confirm url
from the postMessage?
-
It already contains the correct Checkout Session ID, no need to retrieve it from somewhere else.
-
You always receive the URL after the form has been sent. If you would try to confirm a Checkout Session before the form has been sent, you'll get an error message
curl https://base-url-placeholder/checkout/sessions/494d2e9d-c0c9-407c-9094-5b3b2a02c00f/confirm
-X POST
-H "Content-Type: application/json"
-H "X-Authentication-Key: {api_key}"
Response

The plan ID.
A plan ID is a unique identifier for a Flywire installment plan. A plan ID always starts with IP ("Installment Plan") followed by the recipient ID and 11 random characters.
Example: IPTQQ18EADF349BE
{
"plan_id": "IPTQQ18EADF349BE"
}