Create a payment mandate

Learn how to create a new payment mandate to set up recurring payments

Use the following steps to learn how to create a new payment mandate for your user. You'll need this mandate to set up recurring payments.

To create a payment mandate, you need to:

  1. Authenticate your request properly, which requires:
    1. An access_token with the correct scopes, included as a bearer header with your request.
    2. You to sign your requests with a valid Tl-Signature header.
    3. An Idempotency-Key header so you can retry your requests.
  2. Make a POST mandate creation request, including the right beneficiary and constraints for the mandate.

1. Generate an access_token and authenticate your request

A VRP mandate needs an access_token that you've created with either the recurring_payments:sweeping or recurring_payments:commercial scope. The purpose of these two scopes are:

  • recurring_payments:sweeping: The sweeping use case for open banking variable recurring payments, where users can move funds between two accounts in their name.
  • recurring_payments:commercial: The commercial use case for open banking variable recurring payments. This permission needs certain agreements to be in place and can allow some uses of VRP that aren't defined in the VRP specification.

To generate an access_token with one of these scopes, make a POST request to the /token/connection endpoint.

curl -X POST
    -d grant_type=client_credentials
    -d client_id=${client_id}
    -d client_secret=${client_secret}
    -d scope=payments recurring_payments:sweeping
    https://auth.truelayer-sandbox.com/connect/token
curl -X POST
    -d grant_type=client_credentials
    -d client_id=${client_id}
    -d client_secret=${client_secret}
    -d scope=payments recurring_payments:commercial
    https://auth.truelayer-sandbox.com/connect/token

The access_token you receive in response to your request is used as a bearer header when you make a mandate creation request.

You must also sign your request with a Tl-Signature header and include an Idempotency-Key header with your request.

Any payments you create on the mandate need the payments scope as well as the sweeping or commercial scopes.

2. Mandate creation request

To create a mandate, make a POST request to the /v3/mandates endpoint, providing values for the parameters below.

These are the available parameters in a request to create a payment on a mandate:

ParameterDescription
mandate.typeMust be either sweeping or commercial, and must be the same as the scope used for the access_token.
mandate.provider_selection.typeMust be either user_selected or preselected, and determines whether the user selects their banking provider, or if it's preselected (typically through a provider selection screen prior to mandate creation). There's more information about provider selection below.
mandate.beneficiary.typeMust be either merchant_account or external_account, and determines whether the mandate is paying a merchant account or external account. There's more information about beneficiaries below.
mandate.beneficiary.account_holder_nameThe name of the beneficiary. This is what displays as the beneficiary on the remitter's bank statement when a payment is made on the mandate.

In a pay-in to a merchant account, this takes priority as the name the user sees on their statement. However, if omitted in a pay-in to a merchant account, the name associated with the merchant account is used by default.
mandate.referenceA reference for the mandate. This field is available for regulated customers only.

If not specified, a reference is generated based on the remitter's name.
currencyThe currency of payments made on the mandate as an ISO 4217 code. TrueLayer supports GBP and EUR.

You cannot make a payments on a mandate from GBP to EUR, or the other way around.
userSome personal information about the user who will send funds over the mandate, and an ID.

You can use a user ID from a previous Payments API v3 request to represent a user who has previously made a payment or created a mandate.

For a mandate, it's mandatory to include the payer's full name and one of their email address or phone number.

Some providers have upper limits for this field. If you need to shorten a name to fit these limits, we recommend removing middle names first, then initialising the first name. For example:

Jonathan Alexander Doe > Jonathan Doe > J Doe

Learn more about the user information to include in your payment requests.
constraints.valid_fromThe date and time that the mandate becomes valid at, in the format YYYY-MM-DDTHH:mm:ss:sssZ.
constraints.valid_toThe date and time that the mandate becomes invalid at, in the format YYYY-MM-DDTHH:mm:ss:sssZ.
constraints.maximum_individual_amountThe maximum value of a single payment on this mandate. This is specified as a minor value ('pence' or 'cent' value). If multiple payments are made on the mandate, their total can exceed this individual payment value.
constraints.periodic_limitsA set of rules about the maximum value of payments that can be made over a period of a day, week, fortnight, month, half_year, or year. You can specify whether these limits are relative to the point of mandate creation or the calendar year. There's more information below.
metadataAn optional field to provide metadata for the mandate. To do this, provide up to 10 key-value pairs. Each key has a maximum length of 40 characters, and each value a maximum length of 500 characters.
related_productsEnables you to enable a related product for a payment. Currently, you can only enable SignUp+ by including an empty signup_plus object.

📘

After creating a mandate, you cannot update or change it. To change the constraints (for example, the maximum possible value of a single payment), you need to create a new mandate. You can revoke mandates you no longer need to use.

From the parameters above, there are a few that require more consideration than others. These are provider selection, the beneficiary, and some of the constraints of the mandate.

Provider selection in mandates

There are two types of provider selection you can choose at mandate creation: user_selected and preselected. To choose one, provide it as a value for the mandate.provider_selection.type parameter.

For user selected mandates, the user can choose the banking provider that the mandate sets up payments from. The list of providers they can choose from depends on the values you provide for the mandate.provider_selection.filter object. The filter object works the same way as it does for single payments.

For preselected mandates, you need to provide the provider_id for the banking provider the user wants to pay from. Optionally, you can provide the user's bank details as part of the mandate.provider_selection.remitter object to simplify the flow further.

Beneficiaries in mandates

There are two types of beneficiary you can choose at mandate creation: merchant_account and external_account. To choose one, provide it as a value for the mandate.beneficiary.type parameter.

If you choose a merchant account as the beneficiary, you need to provide the associated merchant_account_id.

If you choose an external account as the beneficiary, you need to provide the name associated with the beneficiary account, and then provide the applicable sort code and account number or IBAN. These are provided as part of the mandate.beneficiary.account_holder_name and mandate.beneficiary.account_identifier parameters respectively.

The periodic limits constraint in mandates

Periodic limits are one of several constraints you can define for a mandate, in addition to a start date, end date, and maximum value of an individual payment. Periodic limits enable to you specify a maximum amount that can be paid through a mandate over a specific time period.

There are six optional child objects for the constraints.periodic_limits parameter:

  • day
  • week
  • fortnight
  • month
  • half_year
  • year

For each of these objects, there are two child parameters you can set, which affect their behaviour:

  • maximum_amount: This is the maximum amount that can be paid over the mandate for the parent time period, such as day or week. This must be greater than or equal to constraints.maximum_individual_amount.
  • period_alignment: When the parent time period, such as day or week, applies from. There are two possible values: consent or calendar:
    • A value of consent means the maximum amount that can be paid over the parent time period starts from the point the user consents to the mandate.
    • A value of calendar means the maximum amount that can be paid over the parent time period is always based on calendar dates. If the user consents midway through a period, the maximum_amount is prorated to the end of the time period. For example, if a user agrees a maximun of 5,000 per month and consents halfway through the month, for the remainder of that first month, they can pay a maximum of 2,500 over the mandate.

You can specify a maximum_amount for several different time periods, and they all apply.

🚧

The UK bank Monzo does not support the day, week, fortnight, and half_year periodic limit objects. They also do not support the calendar method for period_alignment.

Mandate creation request and response examples

This is an example of a mandate creation request:

curl --request POST \
     --url https://api.truelayer.com/v3/mandates \
     --header "Content-Type: application/json" \
     --header "Idempotency-Key: $(uuidgen)" \
     --header "Tl-Signature: TestRequest..Signature" \
     --header "Authorization: Bearer $AUTH_TOKEN" \
     --data '{
  "mandate": {
    "type": "sweeping",
    "provider_selection": {
       "filter": {
          "countries": ["GB"],
          "release_channel": "private_beta"
       },
       "type": "user_selected"
    },
    "beneficiary": {
       "type": "external_account",
       "account_holder_name": "My Bank Account",
       "account_identifier": {
          "type": "sort_code_account_number",
          "sort_code": "111111",
          "account_number": "10001000"
       }
    }
  },
  "currency": "GBP",
  "user": {
    "id": "f9b48c9d-176b-46dd-b2da-fe1a2b77350c",
    "name": "Remi Terr",
    "email": "[email protected]",
    "phone": "+44777777777"
  },
  "constraints": {
    "valid_from": "2022-05-10T00:00:00.000Z",
    "valid_to": "2022-05-11T00:00:00.000Z",
    "maximum_individual_amount": 100,
    "periodic_limits": {
      "week": {
        "maximum_amount": 1000,
        "period_alignment": "calendar"
      }
    }
  }
}'

If the mandate creation request is successful, the response contains the id of the mandate, the id of the user on the mandate and the resource_token.

{
  "id": "string",
  "user": {
    "id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941"
  },
  "resource_token": "string"
}

The resource_token is a token you need to use in the subsequent calls made to authorise the newly created mandate. This token is short-lived (15 minutes) and it can be safely shared with a frontend channel.

Error handling

In case you encounter errors in your integration, refer to the payments API errors page to check error codes and the appropriate actions to modify your request.

Update mandate details

If you need your user to change or update any mandate details in the future:

  1. Create a new mandate with the new details needed.
    Optionally, you can revoke the old mandate .
  2. Have your user authorise the new mandate.