Skip to main content

Authentication - CSR/JWT (Production)

Production Environment

This is the certificate setup for the production environment. Use a separate production certificate – the test environment certificate CANNOT be used!

Which products require this?

This authentication method is used for the following products:

  • Payment API
  • Statement API
  • Balance API
  • qvik EAM
  • Payment Request

The Online Payment Page uses HMAC-based authentication → HMAC authentication (production)


Creating the Configuration File​

Using the production registration number specified in the bank contract, the configuration file must be created according to the following template. The string at the end of the highlighted line (27.) (example: AB1234) must be replaced with the production registration number.

Production registration number

The production registration number differs from the test registration number used in the test environment! Check your bank contract or ask your bank representative.

The production registration number can be found in the top right corner next to the username on the Raiffeisen Pay Portal:

The registration number is found in the top right corner.
Good to know

Please make sure there is no space between the production registration number and the colon!

csr_details_minta_v02.txt
oid_section = oids

[req ]
default_bits = 2048
prompt = no
default_md = sha512
distinguished_name = dn
req_extensions = req_ext

[ oids ]
apiUserType = 1.2.3.45

[ dn ]
C=HU
ST= Budapest
L= Budapest
O=APIUser
OU=APIUser_OU
emailAddress=admin@yourdomain.com
CN = apiuser@yourdomain.com

[ req_ext ]
subjectAltName = @alt_names
basicConstraints = critical, CA:FALSE
keyUsage = digitalSignature, keyEncipherment
apiUserType = ASN1:UTF8String:PaymentHUB
2.5.4.97 = ASN1:UTF8String:AB1234

[ alt_names ]
DNS.1 = yourdomain.com
FieldExplanation
STEnter the county from which the service is used
LEnter the city from which the service is used
emailAddressThe email address of the system administrator user who also created the "API user" on the Raiffeisen Pay Portal
CNThe value of the Common Name field in the certificate to be issued. By convention: apiuser@yourdomain.com, where yourdomain.com is the company's own website (but another email address can also be used)
2.5.4.97Reserved OID, for identifying the organization. The last highlighted 6 digits in the example ASN1:UTF8String:AB1234 must be replaced with the company's registration number (important: no space between the 6 characters and the colon).
DNS.1Please copy the company's website name here (for forming the SAN – subject alternative name block)
Security

In the production configuration file, use real company domain name and email address. This information is embedded in the certificate.


Generating the Private Key and CSR File​

Creating the private-public key pair and the certificate signing request (CSR) file required for signing the authentication token is essential.

Using the configuration file produced above, the private key and CSR file must be generated using openssl, following the template below:

openssl genrsa -out key_production.pem 2048
openssl req -new -key key_production.pem -out csr_production.pem -config csr_details_production.txt

Result:

  • key_production.pem - Private key (for signing JWT token)
  • csr_production.pem - Certificate Signing Request (to be uploaded to RPP)

Generating KID and Uploading the Certificate​

1. Uploading CSR to RPP​

Log in to the production Raiffeisen Pay Portal: https://payportal.raiffeisen.hu

On the Certificates tab, click the Upload New Certificate Request button.

Upload new certificate request

Select the production CSR file generated in the previous step (csr_production.pem), upload it and give it a name.

Naming

Use a descriptive name: "Production API Certificate 2026-01" - this makes it easier to track expiry dates later.

Select CSR file Rename CSR file

2. Extracting KID and Credentials​

After this, the necessary information can be extracted from the RPP portal interface:

  • Technical User ID
  • x-api-key (API key)
  • KID (Key ID) - to be used in JWT token header
Extract information
Using KID

The KID (Key ID) value must be used in the kid header field when generating JWT tokens.

Credential security

NEVER commit the API key or KID to a git repository! Use environment variables or a secrets manager.


Signature structure

The Detached JWS consists of three main components: Header, Payload and Signature. These are detailed below.


1. Header​

The header contains the metadata required for signature validation. The header must be composed in JSON format and then Base64URL encoded.

Required fields​

FieldTypeDescription
kidstringKey ID - The unique identifier belonging to the certificate. Can be obtained from the RaiffeisenPay Portal.
typstringToken type - always "JWT"
algstringSigning algorithm - "RS512" (RSA-SHA512)
iatintegerIssued At - Unix timestamp in seconds (time of signing)
jtistringJWT ID - Unique identifier (UUID v4). A new value must be generated for each API call!

Header template​

{
"kid": "<KID value from the RaiffeisenPay Portal>",
"typ": "JWT",
"alg": "RS512",
"iat": <unix_timestamp>,
"jti": "<uuid_v4>"
}

Header example​

{
"kid": "/SN=15349700155842404063/C=HU/L=Budapest/OU=only_for_development_use/CN=p19026_openbanking_-_api_user_certificates",
"typ": "JWT",
"alg": "RS512",
"iat": 1585563716,
"jti": "e395cf5e-0fc4-430b-9f7e-bee20855b475"
}
KID value

The kid value can be obtained from the RaiffeisenPay Portal after uploading the certificate.


2. Payload​

The payload is the HTTP request body in JSON format. This is the data you sign and send to the server.

:::danger Critical: Formatting consistency The JWS signature is unique to the given header and payload combination. The JSON sent in the HTTP body MUST EXACTLY match the signed payload.

Many JWT libraries remove whitespace and line breaks before signing. If the formatting of the sent body differs from the signed one, the API will reject the request.

Solution: Use the same JSON string for both signing and sending as the HTTP body. :::

Payload example​

{
"orderID": "order_123456",
"creditorAccount": "HU96120106590163520000100000",
"transactionAmount": 1000,
"transactionCurrency": "HUF"
}

3. Signature​

The signature is the cryptographic fingerprint of the header and payload combination, created with your private key.

Troubleshooting​

JWT error codes​

Error codeProblemSolution
JWT_GENERAL_ERRORIncorrect JWT assembly or body/payload mismatchVerify that the HTTP body exactly matches the signed payload
JWT_CERT_EXPIREDExpired certificateGenerate and activate a new certificate on the RPP portal
JWT_CERT_NOT_ACTIVECertificate not activatedActivate the certificate on the RPP portal
JWT_IAT_EXPIREDThe iat timestamp is too old or in the futureUse accurate, current system time
JWT_JTI_DUPLICATESame jti value used twiceGenerate a new UUID for each call
JWT_NOT_EXISTSMissing x-jws-signature headerAdd the Detached JWT to the header

Common errors​

ErrorCauseSolution
401 UnauthorizedIncorrect JWS signatureCheck JWS generation and that the body matches the signed payload
401 UnauthorizedWrong KIDVerify that you are using the correct KID
401 UnauthorizedExpired certificateGenerate and upload a new CSR
Invalid signatureWrong private keyVerify that you are using the private key belonging to the CSR

Next steps​

For Payment API, Balance API and Statement API users

After CSR setup and KID extraction, Consent creation and approval is still required on the RPP portal.

Consent management (production) →

For EAM and Payment Request users

With the KID in hand, you can now initiate the first production API call.

First API call (production) →