How the customer authorizes consents and payments on Klarna's XS2A v2 (Berlin Group openFinance) PSD2 API — decoupled SCA through a push notification in the Klarna app, the authorization endpoints, polling the SCA status, and the 10-minute window.
4 min read
Every consent and every payment must be authorized by the customer (the PSU) with Strong Customer Authentication before it takes effect. Klarna's XS2A v2 API uses the decoupled approach: the customer approves in the Klarna app, on their own device, while you poll the API for the outcome. There is no redirect and no OAuth step.
The only SCA method is PUSH_OTP — a push authorization in the Klarna app (authentication method id KlarnaApp). The consent and payment creation responses list it in scaMethods. Because it is the only method, it is selected for you and you do not need to send a body when starting an authorization.
Authorization endpoints
An authorization is a sub-resource of the consent or payment it authorizes. The path is /v2/{service}/{product-type}/{resourceId}/authorisations, where:
List the authorization ids of the consent or payment
GET {base path}
Read the SCA status
GET {base path}/{authorisationId}
Update the authorization (for example supply the PSU-ID)
PUT {base path}/{authorisationId}
Only authorisations is supported as the last path segment. cancellation-authorisations is rejected with 400 SERVICE_INVALID.
The flow
1.
Create the consent or payment. For a payment, the response contains a startAuthorisation link next to self and status. The consent creation response contains no links, so build the path above from the returned consentId.
2.
Start the authorization.POST to the startAuthorisation link (or the consent path) with these headers:
Header
Value
X-Request-ID
A UUID you generate.
PSU-ID
The customer's email address — the one registered with their Klarna account.
PSU-IP-Address
The customer's IP address. Mandatory whenever PSU-ID is sent.
HTTP
1
2
3
4
POST /v2/payments/sepa-credit-transfers/{paymentId}/authorisations
X-Request-ID: 7c0e8a3e-5f4b-4e0c-9a61-2a7d1b6f3c11
PSU-ID: john.doe@example.com
PSU-IP-Address: 203.0.113.17
The response is 201 with the authorisationId, the scaStatus and a scaStatus link to poll:
The customer is now asked to approve in the Klarna app. You can also start the authorization without PSU-ID and supply it later with a PUT on the authorization; the authorization only becomes started once the customer is identified.
3.
The customer approves or rejects in the Klarna app.
4.
Poll the SCA status.GET the scaStatus link until the status is final:
scaStatus
Meaning
scaMethodSelected
The authorization exists and the SCA method is selected, but the customer is not identified yet (you started it without PSU-ID).
psuIdentified
The customer was identified from the PSU-ID, but the SCA has not been started. You typically don't see this status: an identified customer with a selected SCA method moves straight on to started.
started
Waiting for the customer to answer in the Klarna app.
finalised
The customer approved. The consent becomes usable, or the payment moves on (see Payment status).
failed
The customer rejected, the 10-minute window elapsed, or the customer's account could not be used for this consent or payment.
The customer has 10 minutes from the moment the authorization is started to answer. After that the authorization is failed, a payment that was waiting becomes RJCT, and a late approval no longer has any effect. Start a new consent or payment to try again.
Errors you may see when starting an authorization
Response
When
400 FORMAT_ERROR
PSU-ID is not a valid email address, or PSU-IP-Address is missing while PSU-ID is sent.
401 PSU_CREDENTIALS_INVALID
No Klarna customer is known for the PSU-ID. The authorization moves to failed.
409 STATUS_INVALID
The authorization cannot be updated in its current state, or it is already linked to a different PSU.
Errors use the body {"apiClientMessages":[{"category","code","text"}]}.
Testing in the sandbox
The sandbox has no real Klarna app, so it answers the push for you. The outcome and the delay are driven by a +tag in the PSU-ID email — see Simulating Strong Customer Authentication and the test PSUs.