Create a payment mandate
Learn how to create a payment mandate for variable recurring payments.
The steps on this page explain how to create a new payment mandate for your user. You need this mandate to set up recurring payments.
Authentication
Before you can create a mandate, you need to first setup authentication. Authentication for the Payments API has two parts. You must:
- You must set up request signing so you can create a
Tl-signature
for your mandate creation request. - Generate an
access_token
to include as a bearer token for your request.
The next section explains how to generate this access token.
Generate a client_credentials
access token
client_credentials
access tokenEach VRP mandate requires an access_token
with a grant_type
of client_credentials
. This is explained under Option 3 on this API reference page.
Additionally, the token requires the appropriate scopes. Specifically, each access_token
should have one scope between recurring_payments:sweeping
or recurring_payments:commercial
scopes:
Scope name | Description |
---|---|
recurring_payments:sweeping | The sweeping use case for open banking variable recurring payments. This is supported by all providers. |
recurring_payments:commercial | The commercial use case for open banking variable recurring payments. This permission requires specific agreements to be in place and may allow certain uses of VRP that are not defined as part of the VRP specification. |
payments
scopeIn order to use the mandate to create a payment, you will also need a
payments
scope.
We recommend you create a separate token with that scope when you need it.
This is an example of a request to generate a client_credentials
access token:
curl -X POST
-d grant_type=client_credentials
-d client_id=${client_id}
-d client_secret=${client_secret}
-d scope=recurring_payments:sweeping
https://auth.truelayer-sandbox.com/connect/token
Mandate creation request
To create a mandate, make a POST request to the /v3/mandates
endpoint, providing values for the parameters below. See the full API reference for more details.
Parameter | Description |
---|---|
mandate.type | Must be either sweeping or commercial , and should correspond to the scope used for the access_token . |
mandate.provider_selection.type | Must 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.type | Must be either merchant_account or external_account, and determines whether the mandate is paying a merchant account or external account. There're more information about beneficiaries below. |
mandate.beneficiary.account_holder_name | The 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. 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 |
mandate.reference | A reference for the mandate. This field is available for regulated customers only. |
currency | The currency that payments on the mandate will be made in. |
user | An object that contains several parameters you can use to provide personal information for the user. If you are not regulated, you must provide a minimum of the user's name and one of their email address or phone number. Learn more. |
constraints.valid_from | The date and time that the mandate becomes valid at, in the format YYYY-MM-DDTHH:mm:ss:sssZ . |
constraints.valid_to | The date and time that the mandate becomes invalid at, in the format YYYY-MM-DDTHH:mm:ss:sssZ . |
constraints.maximum_individual_amount | The 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_limits | A 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. |
metadata | An 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_products | An optional field for adding related products, at least one product should be set. |
You cannot edit a mandate
You cannot change the details of a mandate after creation. As such, you must ensure the details of a mandate such as the beneficiary and constraints are correct at the time of creation.
Provider selection for 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 in 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 for 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.
Periodic limits for 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
object:
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 toconstraints.maximum_individual_amount
.period_alignment
: When the parent time period, such as day or week, applies from. There are two possible values:consent
orcalendar
:- 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, themaximum_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.
- A value of
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
, andhalf_year
periodic limit objects. They also do not support thecalendar
method forperiod_alignment
.
Mandate creation request example
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 the 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:
- Create a new mandate.
- Ask the user to authorise the new mandate.
- Optionally, delete the existing mandate.
NEXT STEPS
Updated 13 days ago