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. 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 Worldline. 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 Worldline 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. Ensure that you have Klarna enabled with Worldline.
  2. Confirm you have access to the Klarna Portal.
  3. Inside Klarna Portal:
    1. Confirm that you have generated a client identifier with your domain URL allowlisted.
    2. Confirm that you have generated an API key.
  4. Confirm that you have registered webhooks for payment.request.state-change.completed events following Webhooks guidelines.
  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. 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. Customer clicks the Klarna payment button in your checkout.
  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. If customer interaction is required, Klarna returns a payment_request_id.
    1. The payment_request_id is used to initiate the purchase flow with Klarna’s WebSDK.
    2. The Klarna purchase journey is launched.
    3. The customer completes the Klarna purchase journey.
  5. Klarna returns a customer_token and/or interoperability_token via webhook.
  6. You create an authorization request with Worldline and share the required interoperability data points. This is required only when a purchase was involved.
  7. Worldline responds with an approval and order completion.
  8. Customer is redirected to your confirmation page.
sequenceDiagram participant C as Customer participant P as Partner participant K as Klarna participant AP as Worldline 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. Initialize Klarna Web SDK in your checkout experience.
  2. Request Klarna’s payment presentation for the current payment context.
  3. Render Klarna payment option(s) dynamically in the payment form according to the instructions.
  4. Allow the customer to select and deselect a Klarna payment option.
  5. Display the Klarna button and start the payment process when clicked.

​The expected outcomes are as follows:

ParameterPresenceDescription

clientId

requiredA 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.

products

optionalAn 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.

locale

optionalLanguage and region code (e.g., en-US). If omitted, Klarna may default based on the customer’s browser settings.

sdkToken

optionalThe 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
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

amount

conditionalThe 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.

currency

requiredThree-letter ISO 4217 currency code (e.g., USD, EUR).

locale

optionalLocale 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.

intents

optionalSpecify 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

Render Klarna according to instructions

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

AttributePresencePurpose

instruction

requiredSpecifies 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.

paymentOption

optionalDefines 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

paymentOptionId

requiredThe 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.

icon


required
Klarna badge/logo suitable for checkout forms.

header


required
The main descriptor that introduces Klarna in the payment form. The value will be dynamically adjusted based on the locale provided.

subheader

requiredThe 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.

message

optionalEnriched tailored description with link.

badge

optionalBadge used for saved options or promotions.

terms

optionalDefines terms/disclosures potentially with links.

paymentButton

requiredPayment 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_KLARNA

Show Klarna alongside other payment methods.

PRESELECT_KLARNA

Show 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_KLARNA

Show 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:

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. Icon
  2. Badge
  3. Header
  4. Subheader
  5. Message
  6. Terms
  7. Button

Mount the Klarna payment option components within your designated Klarna payment method container to render them dynamically in the payment form. 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

id

Sets a custom DOM ID on the rendered button. Useful for testing or styling.

shape

Defines the button’s shape. Possible values are:default, pill, rect

theme

Sets the visual theme of the button. Possible values are: default, light, dark, outlined

locale

Sets 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.

disabled

Disables the button when set to true. Useful during form validation or async operations.

loading

Forces the button into a loading state. Useful when awaiting async setup or validation.

intents

Sets the purpose of the payment. Used to personalize the button and flow if not set when creating the PaymentPresentation instance.

initiate

Function that returns a Promise resolving to either a PaymentRequestData, a paymentRequestId, or a returnUrl. This will be handled differently depending on the integration path.

initiationMode

Defines 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. Capturing the customer’s action when they click the Klarna button.
  2. Forward the payment context to the backend.
  3. Creating a Payment Request through Klarna’s APIs.
  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

{{#lst:Klarna Docs - Payment Request - Content Source|payment request: create: request: tokenization: api table}}

Configure customer token scopes

To enable tokenized payments, include the required scope parameter when calling the Payment Request APIKlarna Icon. 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_present

Enables 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_present

Enables 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:

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 APIKlarna Icon.
  • 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

Payment RequestKlarna Icon
POST:/v2/accounts/{partner_account_id}/payment/requests
Show recommended
ParameterRequiredDescription
state
Yes

The current state of the Payment Request.

  • SUBMITTED - The payment request has been submitted to Klarna.
  • IN_PROGRESS - The customer is actively in the payment flow.
  • COMPLETED - The customer has approved the request. In case of o...
payment_request_id
Yes

The unique identifier for the payment request. This is the identifier you will use to reference the payment request in subsequent API calls.

You should not make any assumption about the format of this identifier, you should treat it as an...

expires_at
Yes

The expiry time of the payment request.

After this timestamp the payment request will be canceled and deleted.

currency
Yes

Currency in ISO 4217 format.

amount
No

Total amount of a one-off purchase, including tax and any available discounts. The value should be in non-negative minor units. Eg: 25 Dollars should be 2500. This is the amount that Klarna will charge the customer for a one-off purchase. S...

Here you can find all required parameters for this operation createPaymentRequestKlarna Icon
initiationModeDescription

DEVICE_BEST

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.
  • Native webview: Always redirect

Note: for this initiationMode, a return_url is required in the customer_interaction_config object.

ON_PAGE

The 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.

REDIRECT

The 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 APIKlarna Icon.

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 Worldline. 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 Worldline, Klarna may reject and ask the customer to approve the purchase again.