Worldline

Token creation - Build checkout form with Klarna Web SDK

Klarna’s tokenized payments replace raw payment details with secure digital tokens, allowing customers to safely save their payment method for easy, repeat purchases like subscriptions or on-demand services.

Klarna’s tokenized payments replace raw payment details with secure digital tokens, allowing customers to safely save their payment method for easy, repeat purchases like subscriptions or on-demand services. Each token has usage rules that add security and simplify checkout. The process involves creating a token when saving a payment method and charging the token when making a payment.

Overview

This guide explains how to integrate the Klarna Web SDK to (1) present Klarna in your checkout, (2) create a customer token with or without an initial purchase, and (3) hand off authorization to [acquiring-partner]. The flow supports subscriptions and on‑demand use cases and keeps you in full control of your payment form.

This integration approach applies only when you build and control your own payment form within the checkout. It provides full ownership of the customer experience while Klarna delivers ready-made UI components to manage the payment interface.

What you'll build

  • Dynamic presentation of Klarna as a payment option.
  • A payment process where a token is created with or without an initial purchase.
  • Return to the checkout and authorization via [acquiring-partner] if a purchase is involved.

Out of scope

  • Recurring/token‑charge flows (customer‑present and customer‑not‑present).
  • Fully server‑side or native mobile SDK integrations.

Prerequisites

Before you integrate, check that you meet the following prerequisites:

  1. 1.
    Ensure that you have Klarna enabled with [acquiring-partner].
  2. 2.
    Confirm you have access to the Klarna Portal.
  3. 3.
    Inside Klarna Portal:
    1. 3.1.
      Confirm that you have generated a client identifier with your domain URL allowlisted.
    2. 3.2.
      Confirm that you have generated an API key.
  4. 4.
    Confirm that you have registered webhooks for payment.request.state-change.completed events following Webhooks guidelines.
  5. 5.
    Add Terms and Conditions for Web SDK.

Subscribing to webhooks in the Klarna Portal will be available in a future release.

Integration overview

Here's an overview of all the steps to display Klarna and initiate payments via the WebSDK:

  1. 1.
    Present Klarna as a payment option in the payment form. If one-time payment has been implemented, adapt the request parameters for tokenization. Rendering the payment presentation according to the response stays the same.
  2. 2.
    Customer clicks the Klarna payment button in your checkout.
  3. 3.
    You create a server-side payment request to Klarna and share available interoperability data points. If one-time payment has been implemented, adapt the request parameters for tokenization while keeping response handling the same.
  4. 4.
    If customer interaction is required, Klarna returns a payment_request_id.
    • 4.1.
      The payment_request_id is used to initiate the purchase flow with Klarna’s WebSDK.
    • 4.2.
      The Klarna purchase journey is launched.
    • 4.3.
      The customer completes the Klarna purchase journey.
  5. 5.
    Klarna returns a customer_token and/or interoperability_token via webhook.
  6. 6.
    You create an authorization request with [acquiring-partner] and share the required interoperability data points. This is required only when a purchase was involved.
  7. 7.
    [acquiring-partner] responds with an approval and order completion.
  8. 8.
    Customer is redirected to your confirmation page.
sequenceDiagram participant C as Customer participant P as Partner participant K as Klarna participant AP as [acquiring-partner] C->>P: Visit checkout page P->>K: Initialize Klarna SDK P->>K: Request presentation instructions K->>P: Return assets and instructions P->>P: Render payment selector C->>P: Select Klarna payment method P->>P: Update Klarna presentation<br>Show Klarna payment button C->>P: Click Klarna payment button Note over P,AP: Handle the "Pay with Klarna" button click C->>P: Click Klarna payment button P->>K: POST /v2/payment/requests Note over P,K: Share interoperability data points alt Customer interaction required K->>P: Return payment request id P->>K: Return payment request id<br>to Klarna SDK K->>C: Start Klarna purchase journey C->>K: Complete Klarna purchase journey end K->>P: Payment request completed event via webhook Note over K,P: customer_token and/or interoperability_token P->>AP: Authorize payment Note over P,AP: Share interoperability data points AP->>P: Respond with approval Note over P,AP: Order completed P->>C: Redirect to confirmation page

Integration details

Present Klarna in the payment form (frontend)

Presenting Klarna in the payment form involves retrieving the visual assets, localized text, and display instructions required to correctly render Klarna as a payment option and display the payment button. This dynamic presentation ensures a consistent customer experience, accurate localization, and optimized conversion performance, while adapting seamlessly to different checkout states.

On a high level, the process involves:

  1. 1.
    Initialize Klarna Web SDK in your checkout experience.
  2. 2.
    Request Klarna’s payment presentation for the current payment context.
  3. 3.
    Render Klarna payment option(s) dynamically in the payment form according to the instructions.
  4. 4.
    Allow the customer to select and deselect a Klarna payment option.
  5. 5.
    Display the Klarna button and start the payment process when clicked.

The expected outcomes are as follows:

undefined
undefined
Initial presentationWhen Klarna is selected

Klarna's payment presentation best practice


To ensure the best user experience and optimal conversion rates when presenting Klarna as a payment option, please apply the following recommendations:


  • Display Klarna descriptor dynamically alongside other payment options in your payment form.
  • Embed Klarna’s UI elements directly in your frontend for a consistent and responsive design.

The next sections in this guideline will walk through how this can be achieved using Klarna Web SDK.

Initialize the Web SDK

The Klarna Web SDK (klarna.mjs) follows the JavaScript module approach and should be included in places where you need to have a reference to the SDK such as while rendering any components or initiating a payment flow. Here are the initialization parameters:

ParameterPresenceDescription
clientIdrequiredA credential used to identify the Partner, which can be obtained from the Klarna Portal. To ensure the credential functions properly, make sure to register all domains where the Web SDK will be used.
productsoptionalAn array used to specify which products should be loaded to optimize performance by limiting the amount of data downloaded. If the PAYMENT product is included, only the Klarna.Payment package will be loaded. If the products array is omitted, all available packages will be loaded by default.
localeoptionalLanguage and region code (e.g., en-US). If omitted, Klarna may default based on the customer’s browser settings.
sdkTokenoptionalThe short-lived token exchanged from the klarna_network_session_token. Enables restoring the customer's session state securely on the client.

For the full API specifications, refer to Klarna Web SDK. SDK initialization sample

JAVASCRIPT
<script type="module">
  const { KlarnaSDK } = await import("https://js.klarna.com/web-sdk/v2/klarna.mjs")

  const Klarna = await KlarnaSDK({
    clientId: "[client-id]",
    products: ["PAYMENT"],
    locale: "en-US", // optional
  })

  // Klarna SDK ready to be utilized
  // Klarna.Payment.button().mount('#payment_container')
</script>

If the domain is not registered, subsequent method calls will result in an error.

Do
  • Load the Web SDK from https://js.klarna.com/web-sdk/v2/klarna.mjs to remain compliant.

  • Keep the SDK in the top‑level (1st‑party) browsing context.

  • Specify products for performance.

  • Disclose Web SDK tracking. Learn more here

Don't
  • Don’t include the Web SDK in a bundle or host it yourself.

  • Don't load the Web SDK inside an iframe.

  • Don't omit products.

  • Don't use the Web SDK without disclosing tracking technologies.

Request payment presentation

Klarna payment presentation provides all the visual assets, localized texts, and instructions needed to correctly display Klarna in your checkout form.

Use the initialized SDK instance to call the Klarna.Payment.presentation() method.

Basic checkout context parameters must be provided:

ParameterPresenceDescription
amountconditionalThe transaction amount in minor units following ISO 4217 exponents (e.g., $118.00 = 11800, ¥1400 = 1400). This field is required if any of the intents include PAY, SUBSCRIBE, or DONATE; otherwise, it is optional.
currencyrequiredThree-letter ISO 4217 currency code (e.g., USD, EUR).
localeoptionalLocale code to localize texts and formats (e.g., en-US, de-DE). If you don’t set this, it will automatically use the value chosen when you first set up the Web SDK. If that’s not available, it will use your browser’s settings instead.
intentsoptionalSpecify the intent of the checkout flow: PAY, SUBSCRIBE, SIGNUP, SIGNIN, DONATE, ADD_TO_WALLET. If omitted, intents defaults to ["PAY"].

For the full API specifications, refer to Klarna Web SDK.

Performance optimization It is important to ensure that Klarna is displayed at roughly the same time as other payment methods, with an acceptable delay of less than 100 ms. To achieve this, begin initializing the Klarna Web SDK and invoke the payment presentation method concurrently while loading the list of all enabled payment methods from your server.

Sample code

JSON
{
  "amount": 11800, // subscription billing amount.
  "currency": "USD",
  "locale": "en-US",
  "intents": ["SUBSCRIBE"],
  "subscription_billing_interval": "MONTH",
  "subscription_billing_interval_frequency": 1
}

Render Klarna according to instructions

The PaymentPresentation interface provides the full Klarna branding package and instructions tailored to the customer's purchase:

AttributePresencePurpose
instructionrequiredSpecifies how Klarna as a payment option(s) should be displayed (e.g., whether to show, preselect, or display as show-only). Adhering to these payment presentation instructions ensures customers have the best possible experience and optimizes conversion rates.
paymentOptionoptionalDefines the default payment option applicable to all purchase types. This object includes the visual elements required to represent Klarna during checkout.

The paymentOption object structure is as follows:

AttributePresencePurpose
paymentOptionIdrequiredThe identifier of the payment option. The value is required to be sent to the Payment Authorize API or the Payment Request API when initiating the payment.
iconrequiredKlarna badge/logo suitable for checkout forms.
headerrequiredThe main descriptor that introduces Klarna in the payment form. The value will be dynamically adjusted based on the locale provided.
subheaderrequiredThe descriptor subheader which must be loaded inline below the main descriptor header. Short and enriched descriptive texts. Provides transparency on available options like installments, pay later, etc.
messageoptionalEnriched tailored description with link.
badgeoptionalBadge used for saved options or promotions.
termsoptionalDefines terms/disclosures potentially with links.
paymentButtonrequiredPayment button that starts the Klarna purchase journey.

For the full API specifications, refer to Klarna Web SDK.

Follow the payment presentation instruction

This section describes how to apply Klarna’s payment presentation instructions, which define how Klarna should appear in your checkout. Following these instructions ensures a consistent experience across payment states and is required for features like Klarna Express Checkout and Sign in with Klarna.

The instruction attribute has the following values:

InstructionDescription
SHOW_KLARNAShow Klarna alongside other payment methods.
PRESELECT_KLARNAShow Klarna pre-selected but still alongside others. This is returned when using the customer_token issued from the Sign in with Klarna feature or the tokenization flow.
SHOW_ONLY_KLARNAShow Klarna as the only payment method. This is returned when the customer has finished the first step of Klarna Express Checkout multistep.

For the full API specifications, refer to Klarna Web SDK.

Skip this section if you don't use any Conversion Boost features from Klarna such as Klarna Express Checkout, Sign-in with Klarna, Klarna Messaging or Klarna Prequalification.

Here are example outcomes illustrating how Klarna should be displayed for each instruction:

undefined
undefined
undefined
Show KlarnaPreselect KlarnaShow only Klarna

The presentation instructions are derived from possible customer purchase journeys described in the How to present Klarna article. Sample code:

JAVASCRIPT
function renderKlarna(paymentPresentation) {
  if (!paymentPresentation) return;

  const root = qs("#klarna-payment-method");
  if (!root) {
    console.error("Missing #klarna-payment-method container.");
    return;
  }

  root.innerHTML = `<div id="klarna-option-default" class="klarna-option default" style="display:none;">
</div>
`;
Mount payment option components

Once an instance of PaymentPresentation is created, the Klarna payment option(s) must be rendered dynamically in the payment selector according to Klarna’s presentation guidelines. The following diagram displays different visual components and how they are rendered in different selection states:

  1. 1.
    Icon
  2. 2.
    Badge
  3. 3.
    Header
  4. 4.
    Subheader
  5. 5.
    Message
  6. 6.
    Terms
  7. 7.
    Button

Mount the Klarna payment option components within your designated Klarna payment method to render them dynamically in the payment form. When defining the layout, allocate sufficient space for all components and choose the appropriate variants to match your payment form structure. The message component must always occupy a full row to ensure legibility, positioned directly beneath the header, sub-header, and logo, as illustrated above.

Ensure that all components—including those not immediately visible—are mounted during initialization, and manage their visibility through your own logic or UI controls.

JAVASCRIPT
function renderKlarnaOption(containerId, option) {
  const container = qs(`#${containerId}`);
  if (!container) {
    console.error(`Missing #${containerId} container.`);
    return;
  }

  const ids = {
    icon:    `${containerId}-icon`,
    header:  `${containerId}-header`,
    subhdr:  `${containerId}-subheader`,
    badge:   `${containerId}-badge`,

Handle payment option selection and deselection

When a Klarna payment option is selected/deselected, ensure the additional visual components are shown/hidden properly.

JS
/**
 * Toggle the Klarna payment option selected state.
 * Use for both SDK preselection (PRESELECT_KLARNA) and user interactions.
 */
function toggleKlarnaPaymentOptionSelection(containerId, isSelected) {
  const container = qs(`#${containerId}`);
  if (!container) {
    console.error(`Missing container #${containerId}.`);
    return;
  }

  const display = isSelected ? "block" : "none";

Configure payment button

The payment presentation instance allows you to mount the prebuilt button component. The Klarna Payment Button is context-aware and dynamically adapts to your configuration.

Klarna payment button variants

Choose the theme and shape of the payment button to best fit into your online store in a way that complements your brand and encourages user engagement. More details on the button styling can be found here.

Configure Klarna payment button

The paymentButton.component() can be configured with the following set of parameters:

ParameterDescription
idSets a custom DOM ID on the rendered button. Useful for testing or styling.
shapeDefines the button’s shape. Possible values are:default, pill, rect
themeSets the visual theme of the button. Possible values are: default, light, dark, outlined
localeSets the language and region (e.g., en-US). If you don’t set this, it will automatically use the value chosen when you first set up the Web SDK. If that’s not available, it will use your browser’s settings instead.
disabledDisables the button when set to true. Useful during form validation or async operations.
loadingForces the button into a loading state. Useful when awaiting async setup or validation.
intentsSets the purpose of the payment. Used to personalize the button and flow if not set when creating the PaymentPresentation instance.
initiateFunction that returns a Promise resolving to either a PaymentRequestData, a paymentRequestId, or a returnUrl. This will be handled differently depending on the integration path.
initiationModeDefines how Klarna launches the purchase journey.

For the full API specifications, refer to Klarna Web SDK.

Sample code

JAVASCRIPT
option
  .paymentButton
  .component({
    id: "klarna-payment-button",  // optional test hook
    shape: "pill",                // "default" | "pill" | "rect"
    theme: "default",             // "default" | "light" | "dark" | "outlined"
    intents: ["PAY"],
    initiationMode: "DEVICE_BEST", // "DEVICE_BEST" | "ON_PAGE" | "REDIRECT"
    initiate: (klarnaNetworkSesionToken, paymentOptionId) => initiateKlarnaPayment(klarnaNetworkSesionToken, paymentOptionId)
  })
  .mount(`#${containerId}-payment-button`);

The button will automatically handle customer interaction and trigger the Klarna purchase flow via the initiate function.

Start payment processing on payment button click (frontend and backend)

Starting payment processing involves coordinating the frontend and backend to securely initiate the Klarna Purchase Journey once the customer clicks the Klarna button. This process ensures the customer’s intent is captured, a Payment Request is created, and Klarna Purchase Journey is launched in a seamless and reliable way.

On a high level, the process involves:

  1. 1.
    Capturing the customer’s action when they click the Klarna button.
  2. 2.
    Forward the payment context to the backend.
  3. 3.
    Creating a Payment Request through Klarna’s APIs.
  4. 4.
    Returning the result to the frontend to start the Klarna Purchase Journey.

Retrieve the interoperability_token and payment_option_id (frontend)

JS
async function initiateKlarnaPayment(paymentOptionId) {
  try {
    // 1) Get a klarna network session token from the Klarna SDK
    const klarnaNetworkSessionToken = await klarna.Network.Session.token();

    // 2) Ask your backend to create a payment request
    const response = await fetch('/api/payment-request', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ klarnaNetworkSessionToken, paymentOptionId })
    });

Create Payment Request (backend)

Call the Payment Request API to initiate a transaction. If customer verification is required, Klarna processes the request and creates a unique payment identifier for tracking. The payment request is then returned in the SUBMITTED state with the interaction details needed to complete the payment flow.

Request

Configure customer token scopes

To enable tokenized payments, include the required scope parameter when calling the Payment Request APIAPI. Klarna will then issue a customer token that contains those specified scopes which define the permitted actions and level of access for subsequent transactions.

ScopeDefinitionUse cases
payment:customer_presentEnables tokenization of the customer for subsequent on-demand charges. Depending on risk assessment and the initially selected payment method, charges might go through immediately as a one-click experience or, in certain cases, require a step-up.*On-demand with initial purchase *On-demand without purchase
payment:customer_not_presentEnables tokenization of the customer for subsequent subscription charges. It allows the Partners to initiate tokens charges without requiring a step-up flow since the customer is not present during the transaction.*Subscription with free trial *Subscription without free trial

Choosing the correct token scope is crucial for ensuring successful payments and maximizing conversion:

  • payment:customer_present: choose this token scope for payments where the customer is actively present in the payment flow and can authenticate if required, so it's not suitable for subscription charges.
  • payment:customer_not_present: choose this token scope for payments where the customer is not present in the payment flow. While this scope could also work for a customer present payment, there may be limitations in the payment options Klarna can offer under this scope.

Configure customer interaction parameters

The return_url and app_return_url parameters define the redirect targets when the Klarna interaction ends, regardless of whether the purchase is approved or aborted. Correct configuration of these URLs is required to ensure customers return to the correct web or mobile app context and can continue the checkout or post-purchase flow without interruption.

  • return_url

    • Used for web-based flows. After the customer completes or aborts the Klarna purchase flow, Klarna redirects the customer to this URL. This may be a URL owned by the Acquiring Partner (which then handles further redirection) or a URL provided by the Partner.
  • app_return_url

    • Used for mobile app flows. During the purchase journey, the customer may be redirected to the Klarna app or a third-party app (for example, a bank app). This URL allows Klarna to return the customer to the Partner’s mobile app. The app_return_url must be a registered URL scheme (for example, partnerapp://klarna) or a universal link that resumes the payment flow. The Partner must reopen the integrating app in its previous state, without triggering additional navigation or state changes.

Visual representations for Web flow and App handover flow:

undefined
undefined
Web handoverApp handover

return_url and app_return_url are not mutually exclusive

In different scenarios, either or both of the return_url and app_return_url can be triggered:

Example 1: Only return_url is triggered – Pure web flow

The customer starts the Klarna purchase flow in a web browser on a desktop. After approving the purchase, they are redirected to the return_url.

Example 2: Only app_return_url is triggered – App-to-app flow

The Partner’s native mobile app opens the Klarna purchase flow using a universal link. If the Klarna app is installed, the customer is taken directly into the Klarna app. After approval, they are redirected to the app_return_url, returning them to the Partner's app.

Example 3: Both URLs are triggered – WebView flow with app handover

The Partner’s native mobile app starts the Klarna purchase flow in a System WebView. If the customer needs to authenticate via an external banking app, they’re handed back to the Partner's app using app_return_url. They then resume the purchase flow in the WebView and, upon completion, are redirected to the return_url.

Requirements

  • Accept the return URL parameters in the Partner-facing APIs.
  • Validation should be implemented, but it must not be more restrictive than what is specified in Klarna’s Payment Authorize APIAPI.
  • Forward the return URL parameters unmodified to Klarna.

Provide supplementary purchase data

Supplementary Purchase Data refers to additional transaction details shared with Klarna that provide greater context about a purchase. These data points—such as line items, subscription details, or industry-specific attributes—help improve underwriting accuracy, fraud assessment, and the customer’s post-purchase experience. They may be required in certain industries and support multiple use cases, including better acceptance rates, enhanced fraud prevention, improved customer experiences within the Klarna app, and more effective risk monitoring.

Supply subscriptions or ondemand_service data points depending on the use cases based on the following structure:

Influence on payment option availability and subsequent charges

In addition to improving underwriting and fraud assessment, providing accurate details about subscriptions and on-demand services directly affects which payment options Klarna can offer during the purchase journey. For example, the “Pay in N” option may be unavailable for subscriptions with short billing intervals. These configurations aren’t fixed and may change over time based on Klarna’s internal criteria. Supplying precise data also helps reduce the likelihood of rejections and step-up authentication during subsequent token charges.

Handle token creation with or without a purchase

ScenarioDefinitionRequestOutcomes
Token creation onlySaves a customer’s payment method for future use without completing a purchase. It’s used for cases like subscription setup, adding a payment method to a wallet, or storing payment details during account creation.
  • amount is omitted.
  • request_customer_token is present.
  • customer_token is returned.
Token creation with a purchaseCombines payment and tokenization in one flow, allowing the customer to complete a purchase while saving their payment method for future use.
  • amount and related purchase details such as line_items are present.
  • request_customer_token is present.
  • customer_token is returned.
  • klarna_network_session_token is returned.

[ Token creation only]

Sample payload

JSON
{
  "currency": "USD",
  "supplementary_purchase_data": {
    "subscriptions": [{
      "subscription_reference": "MONTHLY PLAN",
      "name": "9.99 for spotify",
      "free_trial": "ACTIVE",
      "billing_plans": [{
        "billing_amount": 999,
        "currency": "USD",
        "from": "2025-08-01",
        "interval": "MONTH",

[ Token creation with purchase]

Sample payload

JSON
{
  "currency": "USD",
  "amount": 999,
  "supplementary_purchase_data": {
    "subscriptions": [{
      "subscription_reference": "PREMIUM_INDIVIDUAL",
      "name": "9.99 for spotify",
      "free_trial": "INACTIVE",
      "billing_plans": [{
        "billing_amount": 999,
        "currency": "USD",
        "from": "2025-08-01",
Response

When the request succeeds, Klarna returns a payment request in the SUBMITTED state.

The response includes:

  1. 1.
    payment_request_id — a unique identifier for the payment request.
  2. 2.
    payment_request_url — the URL used to initiate the customer’s purchase journey.

Sample payload

JSON
{
  "payment_request_id": "krn:payment:eu1:request:10be1d49-7beb-6b24-b9dd-8c14d0528503",
  "state": "SUBMITTED",
  "state_context": {
    "customer_interaction": {
      "method": "HANDOVER",
      "payment_request_id": "krn:payment:eu1:request:10be1d49-7beb-6b24-b9dd-8c14d0528503",
      "payment_request_url": "https://pay.klarna.com/l/ZjW2Xipgh0tjbrBGD7hzJM"
    }
  },
  "expires_at": "2025-02-26T17:25:34.534721775Z",
  "created_at": "2025-02-24T17:25:34.534721775Z",

Handle the response (frontend)

Share the payment request ID acquired from the server side as a response to the initiate callback:

JS
async function initiateKlarnaPayment(paymentOptionId) {
  try {
    // 1) Get a klarna network session token from the Klarna SDK
    const klarnaNetworkSessionToken = await klarna.Network.Session.token();

    // 2) Ask your backend to create a payment request
    const response = await fetch('/api/payment-request', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ klarnaNetworkSessionToken, paymentOptionId })
    });

Configure initiationMode

The initiationModeis a parameter which controls how the Klarna Purchase Journey is launched (redirect / modal window) on different devices (mobile/desktop/native):

initiationModeDescription
DEVICE_BESTAutomatically 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.
  • Native webview: Always redirect Note: for this initiationMode, a return_url is required in the customer_interaction_config object.
ON_PAGEThe Klarna Purchase Journey is triggered on the same page. The customer never leaves the page. The Klarna Purchase Journey is open in a pop-up if possible and fallback to fullscreen iframe if necessary.
REDIRECTThe customer will be redirected to the Klarna Purchase Journey. Note: for this initiationMode, a return_url is required in the customer_interaction_config object.

After a successful initiation, the Klarna Purchase Flow is presented to the customer, allowing them to:

  • Authenticate with Klarna (e.g., via login or one-time passcode)
  • Select their preferred payment method (such as Pay in 3, Pay Later, etc.)
  • Confirm and complete the payment
Phone collection in the Klarna Purchase Journey

Phone collection in the Klarna Purchase Journey

Monitor and retrieve customer_token and/or interoperability_token (backend)

To retrieve the required token(s), Klarna provides multiple integration methods. Subscribing to Klarna webhook events is required and may be combined with additional methods to improve resilience.

Using webhooks ensures reliable completion handling, particularly when the customer closes the browser before returning, network interruptions occur during redirects, or post-processing is required before notifying the customer.

The customer token is a unique identifier that represents a customer's payment settings and preferences, allowing for secure and streamlined future transactions without requiring the customer to re-enter their payment details.

The customer_token does not expire once issued. It represents a long-lived authorization that allows returning customers to make future purchases securely and seamlessly without re-entering their payment information.

The token remains valid as long as:

  • The customer’s account and payment agreement with Klarna are active.
  • The merchant does not explicitly revoke or delete the token.
  • The customer does not withdraw consent or remove their saved payment method through Klarna.

The klarna_network_session_token is issued by Klarna after the customer approves the purchase. Use this token to finalize the authorization and create the corresponding Klarna payment transaction.

The klarna_network_session_token is valid for only 1 hour and must be used within this time frame to finalize the authorization.

Method: Subscribe to webhook events (required)

Subscribe to the payment.request.state-change.completed webhook event using the guidelines provided here. Klarna sends this event when the Payment Request reaches the COMPLETED state.

This event indicates that the customer has finished the step-up interaction and that the Acquiring Partner can proceed with finalizing the authorization.

Sample payload

JSON
{
  "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:live:HGBY07TR",
    "recipient_account_id": "krn:partner:global:account:live:LWT2XJSE",
    "product_instance_id": "krn:partner:product:payment:ad71bc48-8a07-4919-[...]",
    "webhook_id": "krn:partner:global:notification:webhook:120e5b7e-abcd-4def-[...]",
    "live": false
Method: Read the payment request

As an alternative method, retrieve the Klarna token(s) by calling the Read Payment Request APIAPI.

Once the Payment Request reaches the COMPLETED state, the token(s) are available in the state_context object of the Payment Request.

Sample payload

JSON
{
  "payment_request_id": "krn:payment:eu1:request:10be1d49-7beb-6b24-b9dd-8c14d0528503",
  "state": "COMPLETED",
  "previous_state": "IN_PROGRESS",
  "state_context": {
    "klarna_network_session_token":"krn:network:eu1:live:session-token:[...]",
    "klarna_customer": {
      "customer_token": "krn:customer-token:[...]",
      "customer_token_reference": "ee679eb3-b918-44f6-8f3f-93930a0775e5"
    }
  },
  "expires_at": "2025-02-26T17:25:34.534721775Z",

Authorize the payment (backend)

Make sure to add the interoperability_token received via the webhook and the purchase details within the call to [acquiring-partner]. If everything is implemented correctly, Klarna will approve the payment transaction.

BASH
curl -X POST https://api.acquiring-partner.com/payment \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "USD",
    "payment_methods": {
      "klarna": {
        "klarna_interoperability_token": ""
      }
    }
  }'

In rare cases where there's discrepancy between the amount and purchase details submitted in the original payment request and the information submitted to [acquiring-partner], Klarna may reject and ask the customer to approve the purchase again.

Related articles

API & SDK references

API