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 the payments 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 a Tl-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:

ParameterTypeRequired?Description
typestringYesThe type of payment that the link creates. Can only be "single_payment".
expires_atstring
(RFC-3339 format)
NoThe 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_configurationobjectYesThe 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_itemsarray of objectsNoA list of the items that the user pays for through the payment link.
referencestringNoA 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_uristring NoThe 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_itemsTypeRequired?Description
nameStringYesThe product name that displays on the checkout screen.

Supports special characters and has a character limit of 150 characters.
price_in_minorNumberYesThe 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.
quantityNumberYesThe 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.
urlstringNoThe 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 all product_items does not have to have a total that is the same as payment_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.

A flow diagram explaining the lifecycle of a payment link.

A flow diagram explaining the lifecycle of a payment link.

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.