Sign your requests

Learn how to sign your POST requests to the PayDirect API.

All POST requests to PayDirect API have to be signed. Signing provides a second layer of security on top of the authorisation bearer token and guarantees that the payload has not been tampered with.

Supported algorithms

We only support ES512 signing algorithm for POST requests to PayDirect API.

Generate certificates

ES512 belongs to the family of Elliptic Curve Digital Signature Algorithms (ECDSA).
To sign a POST request using ECDSA you will need to generate an Elliptic Curve (EC) key pair. You will need:

  • a public key, to be uploaded in the PayDirect Settings page in our Console.
  • a private key, to be used for signing requests, which you should not share with anyone outside of your organisation.

ES512, in particular, requires a key pair that use the P-521 family of elliptic curves (also known as secpt521r1). You can generate a key pair using openssl.
To generate the private key, run:

openssl ecparam -genkey -name secp521r1 -noout -out ec512-private-key.pem

You can then obtain the public key by running:

openssl ec -in ec512-private-key.pem -pubout -out ec512-public-key.pem

ec512-public-key.pem is the file you should upload in the PayDirect Settings page in our Console.

Inspect certificates

You can inspect the generated public key using:

openssl ec -inform PEM -pubin -in ec512-public-key.pem -text -noout

You can inspect the generated private key using:

openssl ec -inform PEM -in ec512-private-key.pem -text -noout

Sign a POST request

You need to specify a X-Tl-Signature header in your POST request.
The header value is a JWS with detached content, signed using the ES512 algorithm.

A JWS with detached content has the following structure:

<Base64URLSafeEncoding(JOSEHeader)>..<Base64URLSafeEncoding(signature)>

The payload segment is omitted in the JWS with detached content to generate the signature.

The JOSE header must contain:

  • The alg header parameter with ES512 as value;
  • The kid header parameter, with the id of the certificate used for signing as value (i.e. the UUID value shown in the PayDirect Settings in Console next to your uploaded public certificate).
{
  "alg": "ES512",
  "kid": "9f2b7bd6-c055-40b5-b616-120ccfd33c49"
}

The JWS payload should be the serialised HTTP request body.

{
  "transaction_id": "<UUID>",
  "beneficiary_name": "A person",
  "beneficiary_iban": "GB17CLRB04066800000072",
  "beneficiary_reference": "Sandbox",
  "currency": "GBP",
  "amount_in_minor": 1,
  "context_code": "withdrawal"
}

You can find code examples on GitHub.

Test your signing logic

You can send a POST request to our /v1/test-signature endpoint to verify that you have correctly implemented request signing. The /v1/test-signature endpoint will validate your X-TL-Signature header and return a 204 No Content in case of success. It does not perform any kind of validation on the body schema.

curl -X POST \
     -H "Authorization: Bearer ${access_token}" \
     -H "X-TL-Signature: ${signature}" \
     --data '{
        "nonce": "9f952b2e-1675-4be8-bb39-6f4343803c2f",
     }' \
https://paydirect.truelayer-sandbox.com/v1/test-signature

Did this page help you?