Authorize a customer-initiated payment when the Klarna Web SDK is embedded in the checkout. The SDK orchestrates the Klarna Purchase Journey through the Klarna payment button; the Partner's backend creates the Payment Request and finalizes the authorization.
Use this guide when the Klarna Web SDK is embedded in the checkout and the Partner wants to launch the Klarna Purchase Journey from the Klarna payment button — keeping the customer on the page in a popup or modal instead of redirecting them away.
The underlying API calls are the same as in the server-side flow: createPaymentRequest, retrieve the klarna_network_session_token, then authorizePayment. What differs is the orchestration: the SDK handles the customer-facing Klarna Purchase Journey through the initiate callback on the Klarna payment button, while the Partner's backend remains responsible for creating the Payment Request and authorizing the payment.
When the checkout is server-rendered and the Web SDK is not embedded, follow Authorize a customer-initiated payment (server-side) instead. That guide covers the same underlying API calls using a full-page redirect to the Klarna Purchase Journey and a webhook to deliver the Klarna Network Session Token.
This guide focuses on the orchestration that follows: creating the Payment Request, retrieving the Klarna Network Session Token, and authorizing the payment. For displaying Klarna in the payment selector and configuring the Klarna payment button, see Build Payment Presentation with the Klarna Web SDK.
When the customer selects Klarna in the checkout and clicks the Klarna payment button:
The Web SDK invokes the initiate callback configured on the payment button.
Inside initiate, the SDK supplies the klarna_network_session_token and paymentOptionId to the callback as arguments. The Partner's frontend posts both to its own backend.
The Partner's backend calls createPaymentRequest with the payment context and customer_interaction_config, and returns the resulting payment_request_url to the frontend.
The frontend resolves the initiate callback with { paymentRequestUrl }. The SDK launches the Klarna Purchase Journey in a popup, modal, or redirect depending on the configured initiationMode — DEVICE_BEST is the recommended default. See Step 3: Configure how the Klarna Purchase Journey is launched.
The customer completes the Klarna Purchase Journey (authentication, payment method selection, confirmation).
The Payment Request transitions to COMPLETED and Klarna sends a payment.request.state-change.completed webhook carrying the klarna_network_session_token.
The Partner's backend calls authorizePayment with the Klarna-Network-Session-Token header to create the Payment Transaction. Optionally include step_up_config so Klarna can return STEP_UP_REQUIRED (and a new Payment Request) instead of DECLINED when additional customer interaction is needed.
When Klarna returns STEP_UP_REQUIRED, the SDK can launch the Klarna Purchase Journey for the new Payment Request. After the customer completes it, a new Klarna Network Session Token arrives via webhook and the backend calls authorizePayment again.
sequenceDiagram
autonumber
participant C as Customer
participant FE as Partner frontend (Web SDK)
participant BE as Partner backend
participant K as Klarna
C->>FE: Clicks Klarna payment button
FE->>FE: SDK invokes initiate(klarna_network_session_token, paymentOptionId)
FE->>BE: POST /api/payment-request (klarna_network_session_token, paymentOptionId)
BE->>K: createPaymentRequest (HANDOVER, return_url, supplementary_purchase_data)
K->>BE: payment_request_url
BE->>FE: { paymentRequestUrl }
FE->>K: SDK launches Klarna Purchase Journey (modal/popup/redirect)
C->>K: Customer completes the Klarna Purchase Journey
K-->>BE: Webhook payment.request.state-change.completed
Note over K,BE: klarna_network_session_token
BE->>K: authorizePayment with Klarna-Network-Session-Token header (optional step_up_config)
alt APPROVED
K->>BE: APPROVED, payment_transaction
BE->>FE: Confirmation
FE->>C: Show success page
else DECLINED
K->>BE: DECLINED
BE->>FE: Decline
FE->>C: Show failure / alternative payment page
else STEP_UP_REQUIRED (only if step_up_config was sent)
K->>BE: STEP_UP_REQUIRED, new Payment Request
BE->>FE: New paymentRequestUrl
FE->>K: SDK launches step-up Purchase Journey
C->>K: Customer completes step-up Purchase Journey
K-->>BE: Webhook with new klarna_network_session_token
BE->>K: authorizePayment again with new Klarna Network Session Token
K->>BE: APPROVED / DECLINED
BE->>FE: Result
FE->>C: Show success / failure page
end
The initiate callback is configured on the Klarna payment button when it is mounted. The SDK invokes it the moment the customer clicks the button and supplies the klarna_network_session_token and paymentOptionId as arguments. Use the callback to forward both to the backend, create the Payment Request, and resolve the callback with the resulting paymentRequestUrl.
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
asyncfunctioninitiateKlarnaPayment(klarnaNetworkSessionToken, paymentOptionId) {
try {
// Forward the token and paymentOptionId to the backend so it can create the Payment Requestconst response = awaitfetch('/api/payment-request', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ klarnaNetworkSessionToken, paymentOptionId })
});
if (!response.ok) thrownewError('Network or server error');
From the backend endpoint called by the initiate callback, call createPaymentRequest with the payment context and a customer_interaction_config. For Web SDK integrations, set method = HANDOVER and provide a return_url (and optionally an app_return_url for native apps). The same fields apply as in the server-side flow — see Payment Request for the full resource model and Supplementary purchase data for the recommended data points.
Include at minimum:
Parameter
Required
Description
currency
Yes
Currency in ISO 4217 format.
amount
Yes
Total amount of the Payment Request, including tax and discounts.
customer_interaction_config.method
Yes
Set to HANDOVER. The SDK orchestrates how the Klarna Purchase Journey is launched (modal, popup, or redirect) based on initiationMode.
customer_interaction_config.return_url
Yes
URL on the Partner's domain where Klarna redirects the customer when the SDK falls back to a redirect — used by the recommended DEVICE_BEST mode on mobile and by REDIRECT mode.
customer_interaction_config.app_return_url
Optional
App scheme or universal link that returns the customer to the Partner's native app after a mid-flow handover to a third-party app (for example, a bank app or the Klarna app). Not a substitute for return_url.
payment_request_reference
Recommended
The Partner's own reference for the Payment Request, used for reconciliation.
supplementary_purchase_data
Recommended
Additional purchase context (line items, customer, shipping, purchase reference). Improves underwriting and fraud detection and powers customer communication. See Supplementary purchase data.
acquiring_config
Conditional
Routes the Payment Request to a specific Payment Account or Payment Acquiring Account. Required when the Partner's Klarna setup includes more than one account. Provide either payment_account_id (account-only routing) or payment_acquiring_account_id together with payment_account_reference (acquiring-account routing). When omitted, Klarna uses the default account configured for the Partner.
A successful call returns the created Payment Request in SUBMITTED state. For the full list of states a Payment Request can transition through, see Payment Request — States. The backend returns the payment_request_id to the frontend so the initiate callback can resolve and the SDK can launch the Klarna Purchase Journey.
The Web SDK launches the Klarna Purchase Journey using the initiationMode parameter set on the Klarna payment button. It controls whether the journey opens in a popup, an in-page iframe, or as a full-page redirect.
initiationMode
Description
DEVICE_BEST
Default and recommended. Selects the best launch method per device — popup on desktop (with redirect fallback), redirect on mobile, redirect in native WebViews. Requires return_url in customer_interaction_config.
ON_PAGE
Launches the Klarna Purchase Journey on the same page in a popup (or full-screen iframe as fallback). The customer never leaves the page.
REDIRECT
Redirects the customer to the Klarna Purchase Journey. Requires return_url in customer_interaction_config.
Register event handlers on the KlarnaPayment SDK interface to track the lifecycle of the Klarna Purchase Journey on the client side:
Event handler
Purpose
on("complete", callback)
Triggered when the customer completes the purchase. During a redirect flow, fires once the success page loads.
on("abort", callback)
Triggered when the customer aborts the Klarna Purchase Journey.
on("error", callback)
Triggered when an error occurs during the Payment Request lifecycle. When defined, all errors are emitted to this handler instead of being thrown.
JAVASCRIPT
1
2
3
4
5
6
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.returntrue;
});
Use Web SDK events to enhance the customer experience — for example, displaying clear error messages when a purchase is aborted, or disabling page interactions while payment authorization is in progress.
Never use SDK events to trigger Payment Authorization. Always rely on Klarna webhooks to receive the klarna_network_session_token and finalize the payment after the customer completes the purchase.
Once the customer completes the purchase, Klarna issues a klarna_network_session_token and the Payment Request transitions to COMPLETED. This token is used in Step 5 to finalize the authorization.
Klarna provides multiple methods to retrieve the token. Subscribing to the webhook event is required and may be combined with reading the Payment Request as a fallback for resilience.
The klarna_network_session_token is valid for only 1 hour and must be used within this time frame to finalize the authorization. See Klarna Network Session Token — Expiration for the expiration model and where to read the expiration timestamp.
Klarna sends this event when the Payment Request reaches the COMPLETED state, indicating that the customer has approved the purchase and the authorization can be finalized. Subscribe via the Webhooks registration guide.
As a fallback (for example, when the webhook is delayed or the handler missed it) retrieve the token by calling readPaymentRequest. Once the Payment Request reaches the COMPLETED state, the token is available in state_context.klarna_network_session_token.
Finalize the payment by calling authorizePayment with the klarna_network_session_token in the Klarna-Network-Session-Token request header. Klarna creates the Payment Transaction and returns the result.
The customer's selected payment method is carried by the Klarna Network Session Token. There is no need to send payment_option_id.
Include at minimum:
Parameter
Required
Description
Klarna-Network-Session-Token (header)
Yes
The Klarna Network Session Token received in Step 4.
The Partner's own reference for the Payment Transaction, used for reconciliation.
supplementary_purchase_data
Recommended
Same supplementary data sent in the Payment Request. Significant differences may cause Klarna to require re-confirmation.
acquiring_config
Conditional
Routes the Payment Transaction to a specific Payment Account or Payment Acquiring Account, and optionally requests the currency Klarna uses to settle the transaction. Use the same routing fields set on the Payment Request, and add settlement_currency (ISO 4217) when a settlement currency that differs from the Payment Transaction currency is required. See Request settlement currency.
step_up_config
Recommended
Opts the Partner in to the STEP_UP_REQUIRED outcome. When included, Klarna can request additional customer interaction (returning a new Payment Request) instead of declining cases where it needs more risk signals. Without it, those cases are returned as DECLINED. Set customer_interaction_config.method = HANDOVER and provide a return_url (and optionally app_return_url) so Klarna knows where to send the customer back after the step-up Klarna Purchase Journey. See Payment Authorization.
Klarna returns a payment_transaction_response object. The result field indicates the outcome and determines the next action:
Result
Description
Next steps
APPROVED
The authorization succeeded and a payment_transaction was created.
Store the payment_transaction_id and proceed with post-purchase operations (capture, refund, etc.). Show the customer a confirmation page.
DECLINED
The authorization was not approved. No transaction is created. Common causes include an expired Klarna Network Session Token, significant discrepancies between the Payment Request and the authorize call, or risk evaluation requiring additional customer interaction when step_up_config was not included in the request.
Show the customer a decline or alternative payment page.
STEP_UP_REQUIRED
Klarna requires additional customer interaction before approving. Only returned when step_up_config was included in the authorize request. The response includes a new Payment Request with state_context.customer_interaction.payment_request_url.
Pass the new paymentRequestUrl back to the Web SDK so it can launch the step-up Klarna Purchase Journey. When the customer completes it, a new Klarna Network Session Token arrives via webhook. Call authorizePayment again with the new token.
Without step_up_config in the authorize request, Klarna cannot return STEP_UP_REQUIRED. It returns DECLINED instead in cases where additional customer interaction would have been needed. Klarna recommends including step_up_config by default to recover those cases.
When authorizePayment returns STEP_UP_REQUIRED, Klarna creates a new Payment Request that drives the customer through an additional Klarna Purchase Journey to gather the missing risk signals. The integration loops once more through Step 3, Step 4, and Step 5 — using the new Payment Request — and ends with a second authorizePayment call that returns APPROVED or DECLINED.
Extract payment_request.payment_request_id from the STEP_UP_REQUIRED response and return it to the frontend. Apply the same pattern used in Step 1 — return a JSON response that the initiate callback can use:
The frontend resolves the initiate callback with the new paymentRequestUrl. The Web SDK launches the step-up Klarna Purchase Journey using the same initiationMode configured on the Klarna payment button — no additional SDK calls are needed:
A second payment.request.state-change.completed webhook is delivered, carrying a fresh klarna_network_session_token for the new Payment Request. Handle it with the same webhook handler used in Step 4.
Call authorizePayment again, using the new klarna_network_session_token in the Klarna-Network-Session-Token header. Send the same currency, request_payment_transaction.amount, acquiring_config, and supplementary_purchase_data used in the original authorize call. Klarna returns APPROVED or DECLINED — STEP_UP_REQUIRED is not returned a second time once the customer has gone through the step-up Klarna Purchase Journey.
Treat the step-up loop as a single recoverable detour, not a full restart. Reuse the Payment Transaction reference, supplementary data, and routing from the first authorize call — only the Klarna Network Session Token changes between the two requests.