Skip to main content

Authentication

Comprehensive guide for Open Banking API authentication using OAuth 2.0 with mutual TLS.

🔐 Authentication Overview​

Authentication Methods​

Open Banking API uses dual authentication:

  1. 🔑 Certificate Authentication (mTLS)

    • QWAC certificate for TLS client authentication
    • Required for all API requests
    • QSealC request signing is not used — the API does not read signature headers
  2. 🔐 OAuth 2.0 Authorization

    • Authorization Code flow with PKCE
    • User consent and authentication
    • Access token for API requests

OAuth 2.0 Implementation​

Authorization Code Flow with PKCE​

Configuration Endpoint​

One authorisation server, not per profile

The OAuth endpoints are not version-specific. The metadata document lives at the host root, outside the /xs2a/... paths, and both profiles use the same one.

https://open-banking-api.paysera.com/.well-known/oauth-authorization-server

The scaOAuth link returned with a payment or consent points straight at it. Read the document and use the authorization_endpoint and token_endpoint it advertises rather than building them yourself.

Mutual TLS (mTLS)​

🔑 Certificate Configuration

mTLS Setup​

Configure your HTTP client with certificates:

const https = require('https');
const fs = require('fs');

// Certificate configuration
const httpsAgent = new https.Agent({
cert: fs.readFileSync('path/to/qwac-cert.pem'),
key: fs.readFileSync('path/to/qwac-key.pem'),
ca: fs.readFileSync('path/to/ca-bundle.pem'),
rejectUnauthorized: true
});

// Using with fetch
const response = await fetch('https://open-banking-api.paysera.com/xs2a/berlin/1.3/v1/accounts', {
agent: httpsAgent,
headers: {
'Authorization': `Bearer ${accessToken}`,
'Consent-ID': consentId,
'X-Request-ID': generateUUID()
}
});

Certificate Validation​

Paysera validates:

  • ✅ Certificate chain to trusted CA
  • ✅ Certificate validity period
  • ✅ TPP authorization number in certificate
  • ✅ Certificate not revoked (OCSP check)

Scopes and Permissions​

Paysera does not use permission-style scopes such as accounts or payments. The scope of the authorization request (Step 1) names the one resource the PSU is authorising:

ScopeAuthorises
AIS:<consentId>The account information consent with that ID
PIS:<paymentId>The payment with that ID

Request one scope per authorisation: each consent and each payment is authorised on its own. To read accounts and initiate a payment, authorise the consent and the payment separately.

What you may read is set by the consent, not by the scope. The access object of the consent request lists the accounts and whether you need their balances, their transactions, or both.

The scope returned with the access token can carry additional values next to the one you requested.

Bulk payments, periodic payments and payment cancellation are not supported, so there is no scope for them.

Error Handling​

⚠️ Common Errors and Solutions

OAuth Errors​

ErrorDescriptionSolution
invalid_requestMissing or invalid parameterCheck required parameters
unauthorized_clientClient not authorizedVerify client_id
access_deniedUser denied consentHandle gracefully
invalid_scopeRequested scope invalidUse AIS:<consentId> or PIS:<paymentId>
server_errorInternal server errorRetry with backoff

Certificate Errors​

ErrorDescriptionSolution
certificate_invalidInvalid certificateCheck certificate validity
certificate_expiredCertificate expiredRenew certificate
certificate_not_foundCertificate not registeredRegister with Paysera
certificate_revokedCertificate revokedObtain new certificate

Token Errors​

ErrorDescriptionSolution
invalid_tokenToken invalid or expiredRefresh token
insufficient_scopeToken lacks required scopeRequest new consent
token_expiredAccess token expiredUse refresh token
invalid_grantRefresh token invalidRe-authenticate user

Error Response Format​

{
"error": "invalid_request",
"error_description": "The redirect_uri is missing",
"error_uri": "https://docs.paysera.com/errors#invalid_request"
}

Testing & Debugging​

Common Issues​

Certificate Issues:

# Test certificate connectivity
openssl s_client -connect open-banking-api.paysera.com:443 \
-cert qwac-cert.pem \
-key qwac-key.pem \
-CAfile ca-bundle.pem

Token Issues:

// Debug token expiry
console.log('Token expires at:', new Date(tokenExpiryTimestamp));
console.log('Time remaining:', tokenExpiryTimestamp - Date.now());

Request Debugging:

// Log all requests for debugging
console.log('Request:', {
url: request.url,
headers: request.headers,
method: request.method


## Resources

- 📖 [Getting Started Guide](/guides/open-banking/getting-started)
- 🔐 [Security Requirements](/guides/open-banking/getting-started/security)
- 💻 [Code Examples](/guides/open-banking/examples)
- 📚 [API Reference](/api/open-banking)
- ❓ [FAQ](/guides/open-banking/resources/faq)

:::tip[Pro Tips]
- Always implement PKCE for OAuth flows
- Cache discovery endpoint response
- Implement automatic token refresh before expiry
- Use SDK libraries when available
- Monitor certificate expiry dates proactively
:::