List of Configuration Parameters

Basic Settings

Environment

// Set the target environment (demo, prod)
env: "demo",

Recipient of the Payment (Portal)

// Your portal code (may differ between demo and prod)
recipientCode: "FLW",

Payment Settings

Amount

// Set the amount of the payment
amount: 1234.56,

Sorting Payment Options

paymentOptionsConfig object

Contains optional configurations for the payment options displayed in the Checkout form.

sort array

Flywire makes every effort to display the payment option to payers in the most appropriate order based on payer behavior. You may prefer to change this order to better suit your and your payers needs. You can define the order in which payment options are shown to your payer based on payment currency, payment price (amount), and payment method (type).

The order in which currency , amount , and type are set in the sort array affects the final sort order.

  // Show the cheapest local payment option first but prefer bank transfers
  // over cards and online methods if they are the same price
  paymentOptionsConfig: {
    sort: [
      { currency: ["local", "foreign"] },
      { amount: "asc" },
      { type: ["bank_transfer", "credit_card", "online"] },
    ],							
  },

Filtering Payment Options

paymentOptionsConfig object

Contains optional configurations for the payment options displayed in the Checkout form.

filters object

By default, Flywire displays all payment options for a portal. In some cases, you might want to restrict the available payment options, for example if you want to accept only bank transfers for payments over a certain amount or only show card payments a certain time before a booking.

You can use two filters to restrict payment options:

  • Restrict to specific types of payments

  • Restrict to specific currencies

paymentOptionsConfig: {
    // Only allow local card and online payments
    filters: {
        type: ['online', 'credit_card'],
        currency: ['fx']
    }
}

Split Payments

A split payment allows you to divide a payment between multiple portals.

This means if your customer makes a payment, a portion of that amount can be sent to your partners, with the remaining balance going to you. This ensures that different parties receive their share of a payment in one simple transaction.

You can define multiple partner recipients for one payment and set specific amounts for each partner.

Each recipient must have a portal code from Flywire to receive their portion.

 

recipientCode string

The portal code for the base portal. Any remaining amount left after the payables distribution will be sent to this account.

In this example, the total amount is 100 and there are two split payments (payables) made to partners, one with amount 10 and one with 20. This means that the base portal will receive 70 of the total amount.

amount decimal

The total amount charged to the payer.

payables array

Contains the settings for each split payment.

  • The payables array must contain at least one element.

  • The payables array cannot include duplicate recipients.

  • Each recipient must be a valid portal code and cannot be the same as the base portal code.

  • The sum of all payable amount parameters must not exceed the base payment amount.

amount decimal

The amount subtracted from the total amount. This is how much of the total amount will go to this partner.

recipient string

The portal code of the partner who receives this share of the payment.

description string

A description of this payment for the partner.

// The base portal code
recipientCode: "Your Portal Code",

// The base (total) amount charged to the payer
amount: 100.00,

// Split payments configuration
payables: [
    {
        // Subtracted from the base amount of 100.00
        amount: 10.00,
        recipient: "First Partner Portal Code",
        description: "First partner payment description"
    },
    {
        // Subtracted from the base amount of 100.00
        amount: 20.00,
        recipient: "Second Partner Portal Code",
        description: "Second partner payment description"
    }
]

Pre-filling Fields of the Form

Pre-filling Payer Info

// Pass in partial payer information (missing parameters can
// alternatively be omitted rather than included with empty or
// null values)
  firstName: "John",
  lastName: "Doe",
  email: "[email protected]",
  phone: "+44 1234 567 890",
  address: "",
  city: "",
  state: "",
  zip: "",
  country: null,

Pre-filling Custom Info

recipientFields object

A recipient (portal) can have various custom fields. You define those fields when you set up your portal together with Flywire.

Custom fields can be mandatory or optional. All mandatory fields need to be filled out in order to create a payment.

The custom fields vary by portal - please check your specific portal configuration to view your available fields.

When you are pre-filling custom fields and want to leave some fields empty, you can either pass them and set their value to null or you can just omit the field.

  // Pass in partial custom field information (missing parameters can
// alternatively be omitted rather than included with empty or null
// values)
recipientFields: {
	booking_reference: "REF1234",
	additional_information: null,
},

Displaying the Form

Displaying Input Pages to the Payer

There are two input pages for collecting information that are displayed to the payer in the Checkout Experience form before they choose their preferred payment method:

  • Payer information

  • Custom information for the recipient

The default for both parameters is false, which means omitting the parameters means the pages will not be displayed. If you are not submitting the full information yourself or want the payer to verify it, you have to set the parameters to true.

Display Page for Requesting Payer Info

// Display the payer information page
requestPayerInfo: true,

Display Page for Requesting Custom Fields Info

This page displays custom fields of a recipient (portal) to your payer.

// Display the custom fields information page
requestRecipientInfo: true,

Read Only Fields

readonlyFields array (string)

You can set any of the input fields (for both the payer information and the custom fields) to read only with the readonlyFields array. This way you can ensure that the payer can't overwrite your pre-filled field values.

  • If you do not use this parameter, all fields will be editable.

  • If you use this parameter, any field passed here will be read-only. Any field not passed will still be editable.

// Pass some payer data
firstName: "John",
lastName: "Doe",
country: "US",


// Pass some custom field data
recipientFields: {
    booking_reference: "REF1234"
},

// Make the fields with passed data read-only
readonlyFields: [
    "firstName",
    "lastName",
    "country",
    "booking_reference"
],

Skip Steps

// Display the payer and custom information input boxes
// skipping either page if all the information has been passed in.
requestPayerInfo: true,
requestRecipientInfo: true,
skipCompletedSteps: true,

Embed To (No-Pop Option)

If you prefer to embed the Flywire Checkout Experience within an HTML element on your page rather than have it pop-up in an overlay you can use the embedTo parameter with a unique element selector.

Although this approach is possible Flywire does not recommend using it since it might lead to unexpected behavior in the overall look and feel of the Checkout Experience form.

Setting on your website

<div id="embedTarget"></div>

Checkout configuration

 // Unique embedded element selector
embedTo: '#embedTarget',

Locale

// Set the locale the checkout should be displayed in
locale: "en",

Validation of the Form's Fields

Input Validation for Pre-filling Fields

When you are pre-filling fields of the Checkout Experience form, it might happen that you are using values that do not pass the validation, for example an email address that doesn't contain an @. If any of the data does not pass validation, an array of error objects will be returned to the onInvalidInput callback function.

Your payer can correct invalid data in the form, but only if you are displaying the input pages for payer info and recipient info via setting requestPayerInfo or requestRecipientInfo to true (see Displaying the Form).

Example for including a validation callback

Please provide your own validation reporting feature rather than alerting the user and logging to the console.

// Recommended but not required - include a validation callback.
onInvalidInput: function (errors) {
	errors.forEach(function(error) {
	alert(error.msg);
	});
},

Response example

Example of the errors array that is passed as an argument into the function.

 

Messages in the msg parameter will be translated into the language set by the locale parameter when initiating the Checkout Experience form.

 

Please use the msgId field to test for and handle specific error types.

You can view metadata related to all the fields required in the configuration object by checking the window.FlywirePayment.fields object in the browser console after the flywire-payment.js script has loaded.

[
{
	id: "email",
	msg: "Please enter a valid email address",
	msgId: "emailConstraintNotice",
},
{
	id: "amount",
	msg: "Required",
	msgId: "validation.required",
},
{
	id: "amount",
	msg: "Invalid amount format",
	msgId: "validation.invalidAmountFormat",
	},
];

Skip Extended Validation

Flywire performs quality checks on the information provided for every payment.

In cases where the information provided doesn’t pass Flywire's validation checks the payment will be processed but then placed in a quality check queue. To reduce the chances of payments being held in this queue, Checkout validates the information provided up-front and the Checkout Experience form alerts payers to any potential validation errors before processing.

Should you wish to disable this feature you can set the skipMQC parameter to true.

  • true (disables the pre-validation in the form)

  • false (default, the form alerts payers to validation errors, reduces the chances of a payment being held up in the quality check queue)

// Skip the quality check validation rules
skipMQC: true,

Communication with the Payer

Send Payer Emails

 // Send payers email notifications on payment status changes
payerEmailNotifications: true,

Payer Live Chat Support

 // Show payers a live chat support option
showLiveChat: true,

After-Payment Settings

The after-payment settings define how information is sent back to your website.

The payment flow for the Checkout integration is:

  1. Customer enters information.

    Your customer opens the Checkout Experience form on your website and enters their payment details.

  2. Information is sent back to your website.

    After the payment is completed, the Checkout Experience window automatically closes after a few seconds.

    This triggers the Checkout integration to send back the payment status and details to your website. This can be done in two different ways:

    You can either use the returnUrl parameter or the onCompleteCallback parameter, never both.

    For security reasons, the token is only returned via onCompleteCallback handler. The returnUrl does not return the token.

    This means that when you are tokenizing, you must only use the onCompleteCallback handler.

    returnUrl :

    While the payer is redirected to the return URL, Flywire attaches query string parameters containing payment information to the set URL. This way, your website can receive and process the payment information without requiring additional API calls.

    onCompleteCallback:

    The payer stays on the original page. You specify an onCompleteCallback function in the Checkout configuration that handles the parameters containing payment information. The parameters are returned as a JSON args object to the callback handler.

  3. You use the information for your own systems and the customer.

    You can use the returned parameters to update your backend, display information to your payer, or for your internal logging and processing of payments.

 

You can also define what happens if the payer closes the modal with the X button before the payment is completed, see onCancel

returnUrl

Note if you are tokenizing:

For security reasons, the token is only returned via onCompleteCallback handler. The returnUrl does not return the token.

This means that when you are tokenizing, you must only use the onCompleteCallback handler.

// Set the return URL where payers are redirected to on completion
returnUrl: "https://httpbin.org/get";

onCompleteCallback

Note if you are tokenizing:

For security reasons, the token is only returned via onCompleteCallback handler. The returnUrl does not return the token.

This means that when you are tokenizing, you must only use the onCompleteCallback handler.

onCompleteCallback object

A JavaScript callback function that is executed once the payment is completed and the modal has closed.

The payer stays on the original page. You specify an onCompleteCallback function in the Checkout configuration that handles the parameters containing payment information. The parameters are returned as a JSON args object to the callback handler.

It depends on the type of payment which parameters are returned, see Parameters returned via returnUrl or onCompleteCallback handler.

// The callback function that is called once the payment is complete
onCompleteCallback: function(args) {
console.log(args);
}

Parameters returned via returnUrl or onCompleteCallback handler

A standalone payment is a one-time payment for a specific amount. Standalone payments are not part of a Payment Request or a recurring payment plan.

Example for response via returnUrl:

(Click to see the return URL in JSON formatting. For a detailed description of the parameters see the response via onCompleteCallback handler below.)

http://httpbin.org/get?reference=FLY123567890&status=success&amount=1234.56&payment_method=online&_=REF1234&sig=abcdefgh

Example for response via onCompleteCallback handler:

{
    status: "success",   
    amount: "1234.56",
    paymentMethod: "bank_transfer",
	bankTransferDueDate: "2024-05-27T14:54:57Z"
	reference: "FLY1234567890",
    _: "REF1234",
    sig: "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}

Example for response via returnUrl:

(Click to see the return URL in JSON formatting. For a detailed description of the parameters see the response via onCompleteCallback handler below.)

http://httpbin.org/get?reference=2e828d42-9b90-4cbd-969c-7320bd559115&status=active&amount=0&payment_method=scheduled

Example for response via onCompleteCallback handler:

{
  "status": "active",
  "paymentMethod": "scheduled",
  "amount": 0,
  "reference": "82804964-0497-4e07-990a-60076a463a29"
}

Example for response via returnUrl:

(Click to see the return URL in JSON formatting. For a detailed description of the parameters see the response via onCompleteCallback handler below.)

https://postman-echo.com/get?reference=d1fda11c-44f5-463a-a75b-9c97c2c1f46a&status=active&amount=1200.11&amountCurrency=USD&
payerAmount=1069&payerAmountCurrency=EUR&payment_method=subscription

Example for response via onCompleteCallback handler:

{
  "status": "active",
  "amount": 1200.11,
  "paymentMethod": "subscription"
  "reference": "d475906f-17ff-45f7-812e-52f9a06f21ae",						
  "amountCurrency": "USD",
  "payerAmount": 1069,
  "payerAmountCurrency": "EUR",
}

For security reasons, the token is only returned via onCompleteCallback handler. The returnUrl does not return the token.

This means that when you are tokenizing, you must only use the onCompleteCallback handler.

If you choose optional tokenization and the customer did not opt in to save their card, the response parameters are the same as standalone payments, see Checkout for Standalone Payments - After Payment Completion.

Example for response via onCompleteCallback handler:

{
    "status": "success", 
    "amount": "123.45", 
    "payment_method": "recurring", 
    "reference": "FLY123456789", 
    "amountCurrency": "USD", 
    "payerAmount": "175", 
    "payerAmountCurrency": "EUR", 
    "digits": "5454", 
    "expirationMonth": "3", 
    "expirationYear": "2030", 
    "token": "ABCD1234"
}

Example for response via returnUrl:

(Click to see the return URL in JSON formatting. For a detailed description of the parameters see the response via onCompleteCallback handler below.)

https://httpbin.org/get?reference=TVO817932102&status=success&amount=4000&payment_method=credit_card&sig=b1a30dbe88e65d1f5b055efa511a4c2094716ccd86c1a8b65c514b6e26fff8d7

Example for response via onCompleteCallback handler:

{
"args": {
	"amount": "4000",
	"payment_method": "credit_card",
	"reference": "TVO817932102",
	"sig": "b1a30dbe88e65d1f5b055efa511a4c2094716ccd86c1a8b65c514b6e26fff8d7",
	"status": "success"
},

onCancel

Payers can close the Checkout Experience window by clicking the X button. If you want to handle this event you can supply an onCancel callback.

// The callback function that is called when a payer closed the window
onCancel: function() {
console.log("Checkout cancelled");
}

Modal Handle

After the payment is completed, the Checkout Experience window automatically closes after a few seconds.

If you want to control the behavior of the Checkout Experience modal programmatically, you can do this with the reference (or "handle") you are given when you initiate the modal (via the initiate function). This handle has two built-in methods that you can call:

  • modal.render(): Opens the modal for the payer to start interacting with it.

  • modal.close(): Allows you to programmatically close the modal when you want, for example, after a successful payment, a cancellation, or a timeout.

var modal = window.FlywirePayment.initiate(config);
modal.render();

setTimeout(function() {
modal.close();
console.log("Checkout closed after 10 seconds");
}, 10 * 1000);

Callbacks for Payment Status Notifications

For details like the content of callbacks or the different versions see Payment Status Notifications.

 

If you want to receive callbacks, you must provide a callback URL and a callback ID, otherwise no callbacks will be triggered. You also must set the callback version to 2.

// Enable payment status notification callbacks
callbackUrl: "https://api.your-domain.com/flywire-notifications",
callbackId: "REF1234",
callbackVersion: "2"

Security

Nonce

// Supply a nonce to be used in signature generation
nonce: "REF1234",

Signature Verification

Receiving the Signature

The sig is a cryptographic signature generated by Flywire that verifies that the data has not been altered during transmission. The sig is returned via returnUrl or the onCompleteCallback handler (depending on which one you are using). You can use it to verify the other parameters in the response, see Signature Verification.

It depends on the type of payment which parameters are returned, see Parameters returned via returnUrl or onCompleteCallback handler.

{
"args": {
	"amount": "4000",
	"payment_method": "credit_card",
	"reference": "TVO817932102",
	"sig": "b1a30dbe88e65d1f5b055efa511a4c2094716ccd86c1a8b65c514b6e26fff8d7",
	"status": "success"
},

Using the Signature for Verification

When you receive the payment information back, the signature (sig) is like a digital fingerprint. To make sure the message is authentic and hasn't been tampered with, you recreate this fingerprint using the parameters of the message and your shared secret.

  1. Take the parameters from the message.

  2. Encrypt the parameters together with the shared secret of the portal as a SHA256 hash.

    This generates a new value.

    If you don't know the shared secret of the portal you are using, please reach out to your Flywire contact.

  3. Compare this new value with the signature (sig) that came with the message. If they match, the payment information that was returned to you is verified.

Signature verification should always happen securely on your server, and the shared secret should never be exposed or sent to the browser (the user's side).


const crypto = require("crypto");

//
// Retrieve this value from your settings
//
const sharedSecret = "1234567890123456789012345678901234567890";

//
// Retrieve these values from the returnURL query string params
//
const _ = "REF1234";
const reference = "FLY1234567890";
const status = "success";
const amount = "1234.56";
const paymentMethod = "online";
const sig = "631da0e951478c11bcb9831764de45c21a9c79d2a3b76361dd57a7127219ebcb";

//
// Regenerate the signature locally
//
const data = _ + sharedSecret + reference + status + amount + paymentMethod;
const signature = generateSignature(data);

//
// Compare and continue
//
if (signature === sig) {
  console.log("Match");
}

//
// Utility function
//
function generateSignature(data) {
  const hash = crypto.createHash("sha256");
  hash.update(data);

  return hash.digest("hex");
}
<?php //
// Retrieve this value from your settings
//
$sharedSecret = '1234567890123456789012345678901234567890';

//
// Retrieve these values from the returnURL query string params
//
$nonce = 'REF1234';
$reference = 'FLY1234567890';
$status = 'success';
$amount = '1234.56';
$paymentMethod = 'online';
$sig = '631da0e951478c11bcb9831764de45c21a9c79d2a3b76361dd57a7127219ebcb';

//
// Regenerate the signature locally
//
$payload = $nonce . $sharedSecret . $reference . $status . $amount . $paymentMethod;
$compiledSignature = hash('sha256', $payload);

//
// Compare and continue
//
if($sig == $compiledSignature){
  print "Match";
}
?>