Connect to PayEx ledger APIs 

Introduction

This guide describes the requirements for server-to-server communication between an external client and PayEx ledger APIs.

https://developer.payex.com/xwiki/wiki/developer/download/Main/Invoicing/invoice-service/invoice-service-apis/Technical%20reference/1.%20Security/WebHome/Security%20-%20Clients.20210616.png

Terms

  • Mutual TLS (mTLS): Defined as "two or more entities verify the others' legality before any data or information is transmitted"
  • Ingress: Exposes HTTPS routes from the outside to ledger APIs.
  • LedgerNo: A ledger is represented by an ledger number. The term company number\companyNo is also used.
  • Client: Initiates a request. This request will always refer to a specific ledger.
  • Client certificate: A x509-certificate issued by PayEx to secure the ingress to ledger APIs as part of a mTLS setup.
  • TenantOwnerNo: A tenant owner number represents one or many ledgers as a group. Can in it self also represent a ledger (i.e if a client issues requests for a small number of ledgers, there is no need to use a separate "TenantOwnerNo"). Client certificates are always issued to a specific "TenantOwnerNo",
  • Reference token: Sometimes also called opaque tokens are just a references to a stored token. Reference-tokens are issued by PayEx to gain access to ledger APIs. Tokens are always issued to a specific "LedgerNo" and the ledger number in the request-url must match the ledger number in the token used to make the request.
  • Credentials: A combination of client certificate and access token in a request.

Environments and urls

PayEx ledger offers two environments

  • https://api.sandbox.payex.com/ledger
    This is our sandbox for testing APIs and workflows

  • https://lf-api.payex.com/ledger
    This is our production environment

Each environment will require a specific set of credentials. Certificates and tokens used for the sandbox-environment cannot be used for production and vice versa.

TLS (Transport Layer Security) 1.2 is required for both endpoints

Client certificates

Both https://api.sandbox.payex.com/ledger and https://lf-api.payex.com/ledger are secured by mutual TLS and requires a client certificate. Each request must include the client certificate and will be validated to allow access to the APIs.

Lifetime

PayEx will issue these certificates and they are typically valid for two years.

Scope

  • One certificate per client and environment

Client certificates are bound to the ingress for each environment. A client can server one or many ledgers using the same client certificate.

Formats

One zip-file containing

  • pfx: PKCS#12 archive containing client certificate, signing certificate and private key
  • key: Private key, encrypted pem-format
  • crt: Client certificate and signing certificate, pem-format

Pfx and crt\key contains the same certificate\key information using different formats.

Zip-file:

<tenantOwnerNo>_CertificateBundle_<timestamp>[part of thumbprint].zip

Access tokens

Ledger APIs are protected by token based authentication. An authorization header containing an access token for a specific ledger must be included in each request.

Example


> GET /ledger/customer/v1/838383/customers/12345 HTTP/1.1
> Host: api.sandbox.payex.com
> User-Agent: insomnia/2021.3.0
> Authorization: Bearer 61774729D026F8F3....
> Accept: */*

Lifetime

PayEx will issue these tokens and they will be in the form of reference tokens. A reference token is typically valid for 5000 days  (~13years) but this may change when new tokens are issued.

Scope

  • Each access token gives access to exactly one ledger in a specific environment.

Example:

A company managing 10 ledgers in production and 1 ledger in sandbox will be issued a total of 11 access tokens

10 production-tokens intended for https://lf-api.payex.com/ledger

1 sandbox-token intended for https://api.sandbox.payex.com/ledger

Testing credentials

Both sandbox and production environment offers an url for testing credentials

  • https://api.sandbox.payex.com/ledger/connection-test
  • https://lf-api.payex.com/ledger/connection-test

Example using curl (on linux)

curl -v --key ./certificate.key --cert ./certificate.crt --pass 12345... -H "Authorization: Bearer E1B0126DB71577C00...." https://api.sandbox.payex.com/ledger/connection-test
  • -v: Verbose
  • key: Private key as an encrypted pem-file
  • pass: Password for "key"
  • cert: Certificate as pem-file
  • -H "Authorization: Token in an authorization header

A successful connection-test will include information about what ledger the token is issued to and when the credentials will expire. Credentials should be renewed well before expiration.

{
    "Status": Ok ledger 131313000, token expires 2035-01-17T23:00:00 UTC, certificate expires 2023-05-10T23:59:59 UTC"
}

Problems

Some of the problems that might occur

  • The client certificate is missing, revoked or invalid:
TLSv1.2 (IN), TLS alert, handshake failure (552):
error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Closing connection 0
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
  • The supplied token is invalid or the authorize-header is incorrect:
< HTTP/1.1 401 Unauthorized
< Transfer-Encoding: chunked
< Server: Microsoft-IIS/10.0
< WWW-Authenticate: Bearer error="invalid_token"
  • The client certificate is valid but token does not have a cnf-claim:
    The token may have been incorrectly issued without a "proof of possession"-requirement. If that is the case, a new token must be issued with the correct requirements.

{
    "Title": "Mutual TLS Proof of Possession failed",
    "Status": 401,
    "Detail": "Incoming token has a no x5t#S256 claim but incoming request has a client certificate",
    "Reason": null
}
  • LedgerNo in token does not match ledger number in request-url:
    The client may represent the ledger numbers used in both token and request-url but if the two does not match, the request will fail. In the example below, a token issued for "838383" is used to access ledger "838384"

{
  "reason": {
    "type": "OwnerNumber",
    "value": "838384"
  },
  "title": "The requested is forbidden",
  "type": "ledger/customer/v1/problems/forbidden",
  "status": 403,
  "instance": "/traceId/698ab2d7-53ef-4e85-85f2-a3c2f5a00674",
  "detail": "The requested /ledger/customer/v1/838384/customers/12345 is forbidden with current credentials."
}

Exchanging the secrets

Both the certificates and the tokens are sensitive information that must only be managed by those individuals with a business need for it. It is a Class 2 information class with an Extended security level.

The basic principles are:

  • The certificates are distributed to the integrator through a specific Team area in Microsoft Teams, where the specific dedicated technical contact at the integrator is invited.
  • The tokens are distributed through e-mail or through the same Team channel as the certificates.
  • Password to access the certificates are sent via encrypted e-mail to the explicitly stated technical contact with sensitivity levels set to Confidential.

N.B. The technical contact must be agreed in advance before set-up. To access a Team area within PayEx, name and e-mail address to the technical contact are needed, including the domain of the integrator (i.e. payex.com for PayEx employees)

Removal of certificates and tokens

As soon as the integrator confirmes fetching the certificates and tokens and have successfully completed a connection test the certificates and tokens will be removed from the Teams area.

Any issues should render the creation of a new certificate or token (i.e. no re-distribution of already "delivered" certificates should exist).

HTTP Headers

PayEx supports some HTTP headers for tracking that are used for troubleshooting purposes. It is not a requirement to use any of these http headers but it is highly recommended to implement at least "X-Request-ID" as a minimum for any future troubleshooting and support. The value of those headers is preferably a uniquely generated GUID and is set by the caller.

X-Request-ID

This HTTP header uniquely identifies every HTTP request, and is set by the caller on all requests passed to PayEx.

X-Correlation-ID

As an option for improved troubleshooting PayEx also supports the header "X-Correalation-ID". This HTTP header is a uniquely generated value (on the caller side) that is set on all requests that is part of an operation or event chain that consists of multiple requests. The value is thus unique per operation or event chain rather than for each request.

Example request

Request
POST /ledger/invoice/v1/123/invoices/321/register-direct-payment HTTP/1.1
Host: -
Authorization: Bearer <Token>
Content-Type: application/json
X-Request-ID: 59b2a460-c86c-404b-97dc-53665ca87fef
X-Correlation-ID: 7925766e-0ed4-42ca-b8d2-79abebb915bf

{
   "amount" : 100.00,
   "paymentDate" : "2021-04-27",
   "cause" : "psp"
}
Created by David Persson on 2024/01/10 13:30