APPROVED, STEP_ UP_ REQUIRED, DECLINED)amount, currency, supplementary_ purchase_ data, klarna_ network_ session_ token, klarna_ network_ data)initiate callback, which calls your backend. Your backend then forwards the request to Klarna and returns the result.initiate callback: The Klarna web SDK calls your configured callback when the customer initiates a payment authorization.klarna_ network_ session_ token and payment_ option_ id from your frontendSTEP_ UP_ REQUIRED, APPROVED, or DECLINED outcomes and return the result to your frontendinitiationMode: Control how the Klarna Web SDK launches the Klarna Purchase Journey for step-upSTEP_ UP_ REQUIRED)initiate callback function configured in your Payment Presentation. This callback calls your backend authorization endpoint.initiate callback to call your backend endpoint and handle authorization results. The frontend is responsible for:klarnaNetworkSessionToken and paymentOptionIdresult fieldpaymentRequestUrl to the Klarna Web SDK if step-up is required (the SDK handles launching the Klarna Purchase Journey)async function initiateKlarnaPayment(klarnaNetworkSessionToken, paymentOptionId) {
try {
// 1) Ask your backend to authorize the payment
const response = await fetch('/api/authorize-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ klarnaNetworkSessionToken, paymentOptionId })
});
if (!response.ok) throw new Error('Network or server error');initiate callback calls.POST / api/ authorize-payment (or your chosen path)initiate callback):| Parameter | Type | Required | Description |
|---|---|---|---|
klarnaNetworkSessionToken | string | Yes | The session token provided by the Klarna Web SDK through the initiate callback |
paymentOptionId | string | Yes | The payment option identifier selected by the customer, provided by the Klarna Web SDK through the initiate callback |
{
"klarnaNetworkSessionToken": "krn:network:us1:test:session-token:eyJhbGciOiJIU[...]",
"paymentOptionId": "S0xBUk5BXzE3NzI3MjQ5MTQzMjk="
}
curl https://api-global.test.klarna.com/v2/accounts/{partner_account_id}/payment/authorize \
-H 'Authorization: Basic <API key>' \
-H 'Content-Type: application/json' \
-H 'Klarna-Customer-Token: krn:partner:us1:test:identity:customer-token:ACZawkw7-2[...]' \
-H 'Klarna-Network-Session-Token: krn:network:us1:test:session-token:eyJhbGciOiJIU[...]' \
-d '{
"currency": "USD",
"supplementary_purchase_data": {
"purchase_reference": "ORDER-12345",
"line_items": [customer_ token can be obtained from the Payment Tokenization flow.amount, currency, and supplementary_ purchase_ data values collected from the Partner (same as used during Payment Presentation)step_ up_ config with HANDOVER method to allow the customer to complete authentication when neededstep_ up_ config. customer_ interaction_ config. interaction_ expiry to override the default 3-hour Payment Request lifetime. See Custom Payment Request expiry.payment_ transaction_ response. result field. Your backend reads this field and returns the appropriate data to your frontend so it can proceed.result field indicates the outcome and determines your next action. It has the following possible values:| Result | Description | Next steps |
|---|---|---|
STEP_ | Additional customer interaction is needed to complete the authorization (step-up scenario). A payment_ is created. | Handle this result when Klarna requires additional customer interaction to complete authorization:
|
APPROVED | The authorization succeeded and a payment_ was created. | The Payment Authorization is complete. Handle this result when Klarna authorizes the payment without requiring customer interaction:
|
DECLINED | The authorization was not approved and no transaction was created. | Handle the rejection in your frontend (for example, offer the customer alternative payment methods):
|
{
"payment_transaction_response": {
"result": "STEP_UP_REQUIRED"
},
"payment_request": {
"payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-[...]",
"payment_request_reference": "backend-request-ref-12345",
"amount": 11800,
"currency": "USD",
"state": "SUBMITTED",// Example Node.js/Express endpoint
app.post('/api/authorize-payment', async (req, res) => {
try {
const { klarnaNetworkSessionToken, paymentOptionId } = req.body;
// Call Klarna Payment Authorize API
const klarnaResponse = await callKlarnaAuthorizeAPI({
klarnaNetworkSessionToken,
paymentOptionId,
amount: 11800,STEP_ UP_ REQUIRED with the paymentRequestUrl, the Klarna Web SDK automatically launches the Klarna Purchase Journey (see Step 5).step_ up_ config when calling authorizePaymentcustomer_ interaction_ config object, tell Klarna where to redirect the customer after they complete or stop the Klarna Purchase Journey.return_ url after they finish — whether they complete or stop the flow. This can be a URL managed by the Acquiring Partner (which handles redirection logic) or one collected directly from the Partner.app_ return_ url brings the customer back to the Partner's mobile app when this happens.partnerapp:/ /klarna) that resumes the payment flow. Klarna invokes this URL after the customer completes a native app-based step, such as biometric authentication or Klarna app login. Partners are expected to resume the mobile app in its last state without applying state changes or deep link navigations.return_ url and app_ return_ url are not mutually exclusive. Depending on the device and environment, either or both may be triggered:| Scenario | Description |
|---|---|
| Pure web flow | The customer starts the Klarna Purchase Journey in a desktop browser. After completing the flow, Klarna redirects them to return_. |
| App-to-app flow | The Partner's native app opens the Klarna Purchase Journey using a universal link. If the Klarna app is installed, the customer goes directly into it. After completion, Klarna redirects them to app_. |
| WebView flow with app handover | The Partner's native app starts the Klarna Purchase Journey in a System WebView. If the customer must authenticate via an external banking app, app_ returns them to the Partner's app mid-flow. They then resume in the WebView and, on completion, are redirected to return_. |
return_ url or app_ return_ url from the Partner, do not request a second one — this would increase the minimum integration requirements for Klarna to work.STEP_ UP_ REQUIRED result along with a Payment Request containing the payment_ request_ url which is required for the Klarna Web SDK to launch the Klarna Purchase Journey.initiationModeinitiate function on the Klarna Payment button. The function returns a promise that resolves to an object containing the paymentRequestUrl:const buttonConfig = {
initiate: () => {
// Call to Payment Authorize API returns STEP_UP_REQUIRED
return { paymentRequestUrl: "https://pay.test.klarna.com/na/requests/6bbf6775-[...]/start" };
},
initiationMode: "DEVICE_BEST", // "DEVICE_BEST" (default) | "ON_PAGE" | "REDIRECT"
};
// Render and mount the button with the assigned configuration
paymentPresentation.paymentButtoninitiationMode parameter controls how the Klarna Purchase Journey is launched when your backend returns STEP_ UP_ REQUIRED. Configure this in your frontend payment button.| initiationMode | Description |
|---|---|
DEVICE_ | Automatically selects the best way to launch the Klarna Purchase Journey depending on the device - this is the default and recommended value: *Mobile: Always redirect *Desktop: pop-up if possible, fallback to redirect
|
ON_ | The Klarna Purchase Journey is triggered on the same page. The customer never leaves the page. The Klarna Purchase Journey opens in a pop-up if possible and fallback to fullscreen iframe if necessary. |
REDIRECT | The customer will be redirected to the Klarna Purchase Journey. Note: for this initiationMode, a return_ is required in the customer_ object when calling the Payment Authorize API. |
initiationMode parameter only affects the customer experience when your backend returns STEP_ UP_ REQUIRED. If your backend returns APPROVED, the customer proceeds directly to the confirmation page without launching the Klarna Purchase Journey.
return_ url in customer_ interaction_ config, except when a pop-up experience is used and the customer stops the flow.klarna_ network_ session_ token to the Acquiring Partner to finalize the payment.KlarnaPayment SDK interface to track Klarna Purchase Journey stages:| Event handler | Purpose |
|---|---|
on("complete", callback) | Triggered when the customer accepts the purchase. During a redirect flow, the handler fires once the success page loads. Pending updates are triggered even if the handler is registered after the page loads, removing the need for polling. |
on("abort", callback) | Triggered when the customer stops the Klarna Purchase Journey. |
on("error", callback) | Triggered when initiate() (including a click on the payment button), fetch() or cancel() fails. The error is still thrown afterwards, so try/catch around your own calls keeps working. A failed button click has no caller to catch it, so handle it here. Not triggered when the customer closes the payment window, which is a cancellation rather than an error, or for presentation(). |
paymentRequest properties:| Property | Definition |
|---|---|
paymentRequestId | Unique identifier of the Payment Request. |
state | Current state of the Payment Request. |
previousState | Previous state of the Payment Request. |
stateReason | The reason the Payment Request is in its current state. |
stateContext | State-specific context. The klarna_ is stored here when the Payment Request reaches the COMPLETED state. |
klarna.Payment.on("complete", (paymentRequest) => {
console.log("Payment request completed");
// By default, Klarna will redirect to the submitted return_url upon completion.
// Return false if you want to prevent the redirection to the success page.
return true
});
klarna_ network_ session_ token and finalize the payment after the customer approves the purchase.STEP_ UP_ REQUIRED, the customer needs to complete the Klarna Purchase Journey before you can finalize the authorization. Your backend monitors for step-up completion by the customer to know when to proceed.klarna_ network_ session_ token that you'll need for the finalization call in Step 7.klarna_ network_ session_ token is valid for only 1 hour, so be sure to use it promptly.payment. request. state-change. completed webhook event using the guidelines provided here. Klarna sends this event when the Payment Request reaches the COMPLETED state.{
"metadata": {
"event_type": "payment.request.state-change.completed",
"event_id": "d9f9b1a0-5b1a-4b0e-9b0a-9e9b1a0d5b1a",
"event_version": "v2",
"occurred_at": "2024-01-01T12:00:00Z",
"correlation_id": "2d1557e8-17c3-466c-924a-bbc3e91c2a02",
"subject_account_id": "krn:partner:global:account:test:HGBY07TR",
"recipient_account_id": "krn:partner:global:account:test:LWT2XJSE",
"product_instance_id": "krn:partner:product:payment:ad71bc48-8a07-4919-[...]",COMPLETED state, the token(s) are available in the state_ context object of the Payment Request.
Sample payload{
"payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-[...]",
"state": "COMPLETED",
"previous_state": "IN_PROGRESS",
"state_context": {
"klarna_network_session_token": "krn:network:us1:test:session-token:eyJhbGciOiJIU..."
},
"expires_at": "2025-02-26T17:25:34.534721775Z",
"created_at": "2025-02-24T17:25:34.534721775Z",
"updated_at": "2025-02-24T17:25:34.534721775Z",klarna_ network_ session_ token from webhook or polling, finalize the authorization by calling the Payment Authorize API again with the new token.klarna_ network_ session_ token in the Klarna-Network-Session-Token request headeramount, currency, supplementary_ purchase_ data, klarna_ network_ data) used in the initial authorizationpayment_ transaction_ reference to link the requestscurl https://api-global.test.klarna.com/v2/accounts/{partner_account_id}/payment/authorize \
-H 'Authorization: Basic <API key>' \
-H 'Content-Type: application/json' \
-H 'Klarna-Network-Session-Token: krn:network:us1:test:session-token:eyJhbGciOiJIU...' \
-d '{
"currency": "USD",
"supplementary_purchase_data": { ... },
"klarna_network_data": "{\"content_type\":\"vnd.klarna.network-data.v2+json\",\"content\":{\"operation\":\"payment_request\",\"request\":{\"supplementary_purchase_data\":{...}}}",
"request_payment_transaction": {
"amount": 11800,klarna_ network_ session_ token has expired (1-hour validity) or the payment context doesn't match the initial authorization, the finalization call returns DECLINED.APPROVED with the payment transaction:{
"payment_transaction_response": {
"result": "APPROVED",
"payment_transaction": {
"payment_transaction_id": "krn:payment:us1:transaction:791bbb7b-813a-[...]",
"amount": 11800,
"currency": "USD",
"payment_pricing": {...},
"payment_funding": {
"type": "GUARANTEED",klarna_ network_ response_ dataklarna_ network_ response_ data in the Partner-facing API to ensure Partners can easily identify and use the parameter{
"checkout_id": "cs_27234RBQD9NAKD032BN",
"amount": 17800,
"status": "completed",
"currency": "USD",
"additional_data": {
"klarna_network_response_data": "{\"content_type\":\"vnd.klarna.network-data.v2+json\",\"content\":{\"operation\":\"payment_request\",\"response\":{\"result\":\"APPROVED\",\"payment_transaction\":{\"payment_transaction_id\":\"krn:payment:us1:transaction:791bbb7b-813a-[...]\"}}}}"
}
}