Create a payment link
Learn how to create a payment link with the TrueLayer Payments API v3.
Before you start
To create a payment link, you need to set up authentication. This means that you need to:
- Generate an
access_token
with thepayments
scope.
You include this as a bearer header with your request. - Generate public and private keys and set up request signing,
This enables you to generate aTl-Signature
header to include with your request.
Your requests to the payments API should also include an idempotency key, which you can provide in the Idempotency-Key
header.
Create a payment link
To create a payment link, you need to make a POST request to the /v3/payment-links
endpoint.
This request should include the access_token
, Tl-Signature
, and Idempotency-Key
headers.
In the request, use these parameters:
Parameter | Type | Required? | Description |
---|---|---|---|
type | string | Yes | The type of payment that the link creates. Can only be "single_payment" . |
expires_at | string (RFC-3339 format) | No | The date and time the payment link expires at. If you don't provide this parameter, the payment link expires 24 hours after creation by default. |
payment_configuration | object | Yes | The payment the link creates when accessed. This follows the same structure as the create payment request in Payments v3, except: This configuration only supports the bank_transfer payment method, and does not support a data_access_token . |
product_items | array of objects | No | A list of the items that the user pays for through the payment link. |
reference | string | No | A reference for the payment link. This is shown in the UI the user accesses through the link and isn't shared with the provider. |
return_uri | string | No | The URL that the end user is redirected to after they successfully complete the payment authorisation flow. If you don't provide a URL, the end user is not redirected and is shown a success screen. |
Payment link request and response example
This is an example of a payment link creation request. In this example, the request is for a payment link to buy furniture such as a table and chairs, as seen in the product_items
parameter.
curl --request POST \
--url https://api.truelayer-sandbox.com/v3/payment-links \
--header 'Authorization: Bearer {Your access token}' \
--header 'Content-Type: application/json' \
--header 'Idempotency-key: {A random UUID}' \
--header 'Tl-Signature: {Tl-Signature header}' \
--data '{
"expires_at": "2024-07-22T07:30:53.527Z",
"reference": "{reference string}",
"return_uri": "https://console.truelayer.com/redirect-page",
"payment_configuration": {
"amount_in_minor": 110,
"currency": "GBP",
"payment_method": {
"type": "bank_transfer",
"provider_selection": {
"type": "user_selected"
},
"beneficiary": {
"type": "merchant_account",
"merchant_account_id": "af6b1163-14bb-4491-afc7-abeb67adc07f"
}
},
"user": {
"id": "f61c0ec7-0f83-414e-8e5f-aace86e0ed35",
"name": "Jonathan Sandbridge",
"email": "[email protected]",
"phone": "+44123456789",
"date_of_birth": "1992-11-28",
"address": {
"address_line1": "40 Finsbury Square",
"city": "London",
"state": "London",
"zip": "EC2A 1PX",
"country_code": "GB"
}
}
},
"product_items": [
{
"name": "Table",
"price_in_minor": 10,
"quantity": 1,
"url": "https://www.example.com/table"
},
{
"name": "Sofa",
"price_in_minor": 20,
"quantity": 1,
"url": "https://www.example.com/sofa"
},
{
"name": "Chair",
"price_in_minor": 20,
"quantity": 4,
"url": "https://www.example.com/chair"
},
{
"name": "Shelf",
"price_in_minor": 30,
"quantity": 2,
"url": "https://www.example.com/table/shelf"
},
{
"name": "Bracket",
"price_in_minor": 20,
"quantity": 4,
"url": "https://www.example.com/bracket"
},
{
"name": "Rug",
"price_in_minor": 10,
"quantity": 1,
"url": "https://www.example.com/rug"
}
],
"type": "single_payment"
}'
If your request is successful, the response contains an id
for the payment link and the link itself, in the form of a URI.
{
"id": "aKiW35RWSyF",
"uri": "https://payment.truelayer.com/checkout/aKiW35RWSyF"
}
The response when you create a payment link doesn't contain a payment id
, just one for the payment link. If you want to track the payment through its id
, this is included in the payment_link_payment_created
webhook you receive when your user creates a payment through the payment link.
Products on your checkout page
When you create a payment link, you can provide an optional array of product_items
. These display on the checkout page of the payment link, giving the user a preview of what they're paying for.
There are several objects you can configure for each item in the product_items
array:
Object within product_items | Type | Required? | Description |
---|---|---|---|
name | String | Yes | The product name that displays on the checkout screen. Supports special characters and has a character limit of 150 characters. |
price_in_minor | Number | Yes | The value of the product, which displays to the right of the product name on the checkout screen. On the checkout page, the price_in_minor for each product_item is multiplied by its quantity . |
quantity | Number | Yes | The quantity of the product, which displays beneath the product name if it has a quantity of two or more. Each quantity object must have a value of one or more or you receive an error. |
url | string | No | The link for each product. If provided, the product name on the checkout page is linked to this URL, so the customer can check what the product is. |
The sum of the
price_in_minor
for allproduct_items
does not have to have a total that is the same aspayment_configuration.price_in_minor
.
Payment link lifecycle
A payment link remains valid even if a user's initial payment fails, enabling the user to try and make the payment again.
The only two scenarios that invalidate a payment link are:
- The payment link expires (after the time specified in
expires_at
passes). - The payment in the payment link succeeds.
Both of these events cause the payment link to be disabled.
You can set the expires_at
parameter to a date and time in RFC-3339 format. This specifies how long your user can pay with your link before it expires. If you don't set a value for expires_at
, the payment link will be usable for 24 hours, but you can specify a longer expiration period if you prefer.
Updated 6 months ago