Build checkout form with Klarna WebSDK

Integrate Klarna’s Web SDK to deliver a seamless, optimized checkout experience on your site. Initialize the SDK, present Klarna in the payment selector, and finalize the flow with Klarna’s payment button.

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

  1. Ensure that you have Klarna enabled with your Acquiring Partner.
  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.

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

  1. Present Klarna as a payment option in the payment form.
  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.
  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 an interoperability_token via webhook.
  6. You create an authorization request with your Acquiring Partner and share the required interoperability data points.
  7. Acquiring Partner 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 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: 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

This guideline describes how Klarna should be presented in the payment form initially as well as when it's selected by the customer. The expected outcomes are as followed:

Initial presentationWhen Klarna is selected

It's crucial that Klarna payment presentation is dynamic and not hardcoded on your server to deliver the best conversion outcome.

Klarna's 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 Klarna 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

clientId

requiredA credential that identifies the Partner (obtained via Klarna Portal).

products

optionalArray to specify which products to load for optimal performance.
This reduces the amount of data needed to download. For example, only loading PAYMENT will exclude the CUSTOMER product.

locale

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

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

Use PAYMENT product for all interactions with Klarna.Payment.

Important implementation details

  • Always load the Web SDK from https://js.klarna.com/web-sdk/v2/klarna.mjs to remain compliant. Don’t include the script in a bundle or host it yourself.
  • The script should always be loaded on the 1st-party context, never inside an iframe, to ensure the purchase flows work as expected.
  • Ensure the products are properly specified while initializing for the best performance outcome.

Legal notice

When using the Klarna Web SDK, you are responsible for informing your users about the tracking technologies it uses. Learn more about how to disclose this on your site.

Klarna payment presentation request

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

requiredThe transaction amount in minor units (e.g., $118.00 = 11800).

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.
Default value is PAY.

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

Sample code

JAVASCRIPT
var paymentPresentation = await klarna.Payment.presentation({
  amount: 11800,
  currency: "USD",
  locale: "en-US",
  intents: ["PAY"], // optional, other values: "SUBSCRIBE" ||"SIGNUP" || "SIGNIN" || "DONATE" 
});

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.

Klarna payment presentation response

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

AttributePurpose

instruction

Specifies how Klarna as a payment method 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.

icon

Klarna badge/logo suitable for checkout forms.

header

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

subheader

The 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

Enriched tailored description with link

paymentButton

Payment button for the customer to start the Klarna purchase Journey

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

Follow Klarna payment presentation instruction

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.

Klarna’s payment presentation instructions indicate whether a customer is ready to check out with a prepared payment via Klarna—for example, when Klarna Express Checkout or other Conversion Boost features are integrated. Partners are required to adhere to Klarna’s payment presentation instruction to achieve the best-in-class user experience.

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 the customer has logged in using the Sign in with Klarna feature.

SHOW_ONLY_KLARNA

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

Here are the expected outcomes of the payment selector depending on the value of the payment presentation instruction:

Show KlarnaPreselect KlarnaShow only Klarna

The presentation instructions are derived from possible customer purchase journeys described in the following article.

Sample code:

JAVASCRIPT
if (paymentPresentation) {
  switch (paymentPresentation.instruction) {
    case "SHOW_KLARNA":
      console.log("Showing Klarna alongside other payment methods.");
      renderKlarnaOption(paymentPresentation);
      break;
    case "PRESELECT_KLARNA":
      console.log("Showing Klarna preselected alongside other payment methods.");
      renderKlarnaOption(paymentPresentation);
      break;

Display Klarna in the payment selector

Once an instance of PaymentPresentation is created, the Partner must dynamically render Klarna payment option in the payment selector according to Klarna’s presentation guidelines.

The following attributes from PaymentPresentation instance will be used when loading the payment selector initially:

  1. Icon
  2. Header
  3. Subheader

Mount Klarna payment presentation icon, header and subheader to your Klarna payment method container to render the elements dynamically in your payment form.

JAVASCRIPT
function renderKlarnaOption(paymentPresentation) {
  const klarnaContainer = document.getElementById("klarna-option");

  if (!klarnaContainer) {
    console.error("Klarna container missing.");
    return;
  }

  // Clear the container first
  klarnaContainer.innerHTML = `

Handle Klarna payment method selection

After the customer selects Klarna in the payment selector (or if Klarna was pre-selected according to presentation instructions), the next step is to show:

  • The Placement (more detailed messaging tailored to the customer and transaction).
  • The Payment Button (to trigger Klarna’s Purchase Journey).

This step finalizes the presentation of Klarna's payment method before the customer proceeds to payment authorization.

  1. Icon
  2. Header
  3. Subheader
  4. Message
  5. Payment Button

Display additional messaging

JS
paymentPresentation
  .message
  .component()
  .mount("#klarna-message-container");

Display Klarna payment button

The payment presentation instance allows you to either mount the prebuilt button component or retrieve the button text asset. 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.

Mount 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
paymentPresentation
  .paymentButton
  .component({
    id: "klarna-payment-button",       // unique button/component ID
    shape: "pill",                     // "pill", "default", or "rect"
    theme: "default",                  // "default", "dark", "light", or "outlined"
    intents: ["PAY"],                  // defines payment intent, e.g., "PAY"
    initiationMode: "DEVICE_BEST",     // "DEVICE_BEST", "ON_PAGE", or "REDIRECT"
    initiate: () => {
      /** 

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

Initiate the purchase journey

In order to launch the purchase flow, you need to implement the initiate callback on the Klarna payment button interface. The initiate callback is triggered when the customer clicks on the Klarna payment button, upon which, the payment request data such as amount and currency must be submitted to Klarna server.

ParameterPresence

currency

required
Currency in ISO 4217 format.
Supported currencies: AUD, EUR, CAD, CZK, DKK, HUF, MXN, NZD, NOK, PLN, RON, SEK, CHF, GBP, USD.

amount

required
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. Should not include any amounts for subscriptions.

supplementaryPurchaseData

optional
Additional details about the transaction can help reduce the risk of fraud and enhance transparency.
  • purchase_reference

  • customer

  • shipping

  • line_items

  • customer.customer_accounts

    / customer.customer_device
  • travel_reservations

  • lodging_reservations

  • insurances

  • vouchers

  • event_reservation

  • ondemand_service

  • subscription

  • in_store_service

  • marketplace_seller_details

For the full API specifications, refer to the API referenceAPI.

Create Klarna payment request on the server side and initiate the purchase flow using Klarna Web SDK

Create a payment request on the server side is the recommended approach to create the payment request, then share the payment request ID as response to the initiate callback.

Client code

JAVASCRIPT
const klarnaPaymentButton = klarna.Payment.button({
  initiate: async () => {
    const resp = await fetch('/create-klarna-payment-request', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ /* Your data here */ })
    });
    const data = await resp.json();
    return { paymentRequestId: data.paymentRequestId };
  }

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

Server code

JAVASCRIPT
// Server.js
// Simplified backend example for creating a Klarna payment request

const axios = require('axios');

// Klarna credentials and base URL (replace with your keys and consider loading from environment variables)
const KLARNA_API_KEY = 'YOUR_API_KEY';
const KLARNA_BASE_URL = 'https://global-api.klarna.com'; // According to docs

// Function to create a Klarna payment request

For the full API specifications, refer to the API referenceAPI.

Create a new payment request on every button click instead of reusing payment requests.

Once the customer approves the request, the payment request will enter the COMPLETED state and you’ll receive an interoperability_token which can be used to authorize the payment and complete the process. There are different ways to obtain the interoperability_token. The recommended approach is to listen to Klarna Webhook payment.request.state-change.completed events.

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

The field stateContext in the webhook payload will be available in a future release.

Webhook payload sample

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-a2c1-103dba3fc918",

Make sure to add the interoperability_token received via the webhook and the purchase details within the call to your 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 the Acquiring Partner, Klarna may reject and ask the customer to approve the purchase again.