Payment Presentation for Hosted Checkout integration

This guide shows you how to build the payment form for Klarna's Hosted Checkout integration. You'll learn to display Klarna payment methods dynamically, handle customer interactions, and implement the payment button with proper callbacks for seamless customer-initiated Payment Authorization.

Overview

Display one or multiple Klarna payment methods in your checkout and let customers select one to complete their purchase. This guide shows you how to integrate Klarna payment methods using the Klarna web SDK.

What you'll build:

  • A payment form that dynamically displays Klarna payment methods
  • Integration with Klarna web SDK for seamless customer experience
  • Support for fast-track payments when the customer has authorized a transaction

Prerequisites

Before building the payment form, ensure you have:

  • A Partner Account onboarded with Klarna
  • An API Key and a Client ID associated with your Partner Account
  • Registered the domains your integration will use to load Klarna's web SDK
  • A Partner-facing API allowing Partners to start a hosted checkout flow

Integration overview

The integration process consists of the following key steps:

  1. 1.
    Gather and forward payment context data: Collect Klarna-specific parameters from Partners
  2. 2.
    Fast-track Klarna Payment Authorization when applicable: Check if Payment Authorization should be auto-approved
  3. 3.
    Initialize the Web SDK: Set up Klarna web SDK with proper configuration
  4. 4.
    Present Klarna in the payment form: Display Klarna options dynamically using the SDK
sequenceDiagram autonumber participant Partner participant APBackend as Acquiring Partner (Backend) participant APFrontend as Acquiring Partner (Frontend) participant KlarnaAPI as Klarna Payment Presentation API participant WebSDK as Klarna Web SDK participant Customer Partner->>APBackend: Send payment context + klarna_network_session_token Note over APBackend,KlarnaAPI: Step 2 - Fast-track check APBackend->>KlarnaAPI: Retrieve Payment Presentation (with session token) KlarnaAPI-->>APBackend: PaymentPresentation response (payment_status) alt payment_status: PENDING_PARTNER_AUTHORIZATION Note over APBackend: Fast-track - Authorize immediately APBackend-->>Partner: Return authorization result else payment_status: REQUIRES_CUSTOMER_ACTION Note over APFrontend,Customer: Step 3 and 4 - Present payment form APBackend->>APFrontend: Forward session token APFrontend->>Customer: Render checkout page APFrontend->>WebSDK: Initialize Klarna SDK APFrontend->>WebSDK: Call Payment Presentation method WebSDK->>APFrontend: Return payment methods and instruction APFrontend->>Customer: Display Klarna payment methods Customer->>APFrontend: Select Klarna Customer->>WebSDK: Click payment button WebSDK->>APFrontend: Trigger initiate callback Note over APFrontend,APBackend: Authorization flow continues in backend end

Integration details

Step 1: Collect payment context from the Partner

Update the Partner-facing API to collect the following data points from the Partner for customer-initiated payment scenarios:

ParameterRequired (Acquiring Partner)Required (Partner)Description
amountYesYesTotal amount of the authorization, including tax and any available discounts.
currencyYesYesCurrency in ISO 4217 format.
supplementary_purchase_dataYesRecommendedAdditional details about the transaction to help reduce fraud risk and enhance transparency. Include this data to improve underwriting, fraud detection, and customer communication. Klarna processes and uses this data for fraud assessment and customer experience optimization.
supplementary_purchase_data.purchase_referenceYesRecommendedCustomer-facing payment number displayed to customers on the Klarna app and other communications. Also included in settlement reports for reconciliation purposes. If you are an Acquiring Partner, this is the reference your Partner generated for their customer payment.
supplementary_purchase_data.line_itemsYesRecommendedDetailed line item information of the purchase.
supplementary_purchase_data.customerYesRecommendedInformation about the customer which can be shared by the Partner. These data points may be used by Klarna to simplify sign-up and during fraud assessment, as well as for underwriting purposes to provide an enhanced experience to returning customers.
supplementary_purchase_data.shippingYesRecommendedShipping information for the purchase. If the purchase contains multiple shipments with different recipients, provide one shipping object per shipment.
klarna_network_session_tokenYesConditionalEncodes Klarna Network Session Token context (prequalification, sign-in state, or approval). Required for finalization after customer authorization; optional on initial request.
klarna_network_dataYesRecommendedAdditional data to enable custom features or data exchange supported by your Integrating Partner. Klarna accepts this passthrough field in a structured JSON format and forwards it to relevant systems for interoperability. Data shared in this field may complement structured datapoints provided in supplementary_purchase_data. Treat this value as an opaque string; do not validate or infer its structure.
return_urlYesConditionalPayment flow redirection URL. The customer will always be redirected to this URL on successful authorization. For web SDK with REDIRECT mode, the customer will also be redirected to this URL on failed authorization. Recommended for web flows.
app_return_urlYesConditionalMobile application return URL (app scheme with no action deeplink). The customer will be redirected to this URL after third-party redirects or redirects to the Klarna Application. It is expected to open the integrating mobile application in its last state (no state changes or deeplink navigations). Recommended for mobile app flows.

Requirements

  • Use exact parameter names klarna_network_session_token and klarna_network_data in the Partner-facing API to ensure Partners can easily identify and use them.
  • Forward all parameters unmodified to Klarna.
  • Parameter validation must not be more restrictive than Klarna's authorizePaymentAPI.
  • Support all printable UTF-8 characters.
  • Supplementary purchase data handling:
    • Map your existing Partner-facing fields (line items, customer billing address, shipping, payment reference) into supplementary_purchase_data when calling Klarna
    • Don't add new Partner-facing fields "just for Klarna" if you already have equivalent fields in your existing schema. Avoid forcing Partners to submit the same data twice using parallel structures
Do

Map your existing Partner-facing fields into supplementary_purchase_data when calling Klarna:

  • Line items: supplementary_purchase_data.line_items

  • Customer details: supplementary_purchase_data.customer

  • Shipping information: supplementary_purchase_data.shipping

  • Payment reference: supplementary_purchase_data.purchase_reference

Don't

Add new Partner-facing fields "just for Klarna" if you already have equivalents:

  • Don't introduce parallel structures like items and klarna_line_items

  • Don't force Partners to submit the same data twice

  • The two structures will diverge over time, causing maintenance issues

Supplementary purchase data scenarios

Acquiring Partners may receive supplementary purchase data (including line items, L2/L3 data for Card Network optimization, and payment context) in one or both of the following ways:

  • Embedded in klarna_network_data: Forward as received without parsing or mapping
  • Provided as individual API fields: Map to the supplementary_purchase_data object when calling authorizePaymentAPI
flowchart LR Partner[Partner]:::tertiaryEntity LineItems[Line items,\nL2/L3 data,\netc]:::secondaryEntity KlarnaNetLeft[Klarna Network Data]:::secondaryEntity AP[Acquiring Partner's API]:::primaryEntity Supplementary[Supplementary\nPurchase Data]:::secondaryEntity KlarnaNetRight[Klarna Network Data]:::secondaryEntity Auth[Payment Authorization]:::primaryEntity %% Main flows Partner --> LineItems --> AP --> Supplementary --> Auth Partner --> KlarnaNetLeft --> AP --> KlarnaNetRight --> Auth

Step 2: Fast-track Klarna Payment Authorization when applicable (Backend)

Before presenting the payment form, if a Klarna Network Session Token (klarna_network_session_token) was shared by the Partner, the Acquiring Partner must check if Klarna Payment Authorization can be fast-tracked. This typically happens when the Partner implements Klarna Conversion features such as Klarna Express Checkout and the customer has authorized the transaction.

Payment Presentation request

Acquiring configuration for multi-payment-account Partners

If you are an Acquiring Partner with multiple Payment Accounts, include the acquiring_config query parameter to specify which Payment Account to use. For Partners with a single Payment Account, omitting acquiring_config is allowed — Klarna automatically uses the only available Payment Account.

Provide one of the following combinations — not both:

  • Payment Account Reference: acquiring_config[payment_acquiring_account_id] + acquiring_config[payment_account_reference]
  • Payment Account ID: acquiring_config[payment_account_id]
BASH
curl -G 'https://api-global.test.klarna.com/v2/accounts/{partner_account_id}/payment/presentation' \
--header 'Authorization: Basic <API key>' \
--data-urlencode 'locale=en-US' \
--header 'Klarna-Network-Session-Token: krn:network:us1:test:session-token:eyJhbGciOiJIU[...]' \
--data-urlencode 'amount=11836' \
--data-urlencode 'currency=USD' \
--data-urlencode 'intent=PAY'

Payment Presentation response

The PaymentPresentation interface provides the full Klarna branding package and instructions tailored to the customer's purchase. However, at this step, the only relevant information is payment_status.

Payment statusDescriptionNext step
REQUIRES_CUSTOMER_ACTIONFurther customer interaction is required, the payment selector should be displayed.Continue to Step 3 to initialize the Web SDK and build the payment form.
PENDING_PARTNER_AUTHORIZATIONKlarna recommends Acquiring Partners to authorize the Payment Transaction immediately by calling the Payment Authorize API and redirect the customer to the payment confirmation page. If such fast-track scenario is not technically supported by the Acquiring Partner, the payment selector should instead be displayed.For detailed implementation guidance, see the Payment Authorization Guidelines. If authorization succeeds, redirect the customer to the confirmation page. If authorization fails, continue to Step 3 to display the payment form and allow the customer to complete the payment.
JSON
{
  ...
  "payment_status": "PENDING_PARTNER_AUTHORIZATION",
  ...
}

Step 3: Initialize the Klarna Web SDK (Frontend)

When Klarna Payment Authorization was not fast-tracked, forward the Klarna Network Session Token (klarna_network_session_token) to the frontend and initialize the Klarna web SDK to display Klarna payment methods in your checkout.

Exchange Customer Token for Klarna Network Session Token

This step is only applicable if you have a Customer Token (customer_token) acquired through the Payment Tokenization process.

Call [ generateKlarnaNetworkSessionToken] with the Customer Token in the Klarna-Customer-Token header. If the Partner has already provided a Klarna Network Session Token (for example, from an earlier browsing session), include it in the Klarna-Network-Session-Token header as well. When both headers are provided, Klarna attaches the customer token to the existing session instead of creating a new one, enabling a seamless transition from anonymous to authenticated context within the same shopping session.

Pass the returned Klarna Network Session Token to the Web SDK during initialization.

BASH
curl -X POST https://api-global.test.klarna.com/v2/accounts/{partner_account_id}/network/session/tokens \
-H 'Authorization: Basic <API key>' \
-H 'Klarna-Customer-Token: krn:partner:us1:test:identity:customer-token:vVQGmYzlfsQ16dko3[...]' \
-H 'Klarna-Network-Session-Token: krn:network:us1:test:session-token:eyJhbGciOiJIU[...]' # optional, include if available
JSON
{
  "klarna_network_session_token": "krn:network:us1:test:session-token:eyJhbGciOiJIU[...]"
}

For tokenization scenarios, use the klarna_network_session_token generated via generateKlarnaNetworkSessionTokenAPI to initialize the web SDK on the next step instead of the network session token provided by the Partner.

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.

ParameterDescription
clientIdA credential that identifies the Acquiring Partner (obtained via Klarna's Credentials API). It is shared across all integrated Partners. To ensure the credential functions properly, make sure to register all domains where the Web SDK will be used.
productsAn 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.
partnerAccountIdA unique identifier for the specific Partner onboarding under the Acquiring Partner.
klarnaNetworkSessionTokenThe Klarna Network Session Token (klarna_network_session_token) that enables restoring the customer's state securely on the client. Pass this token directly when initializing the SDK.
localeOptional, language and region code (for example, en-US). If omitted, Klarna may default based on the customer's browser settings.

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

JAVASCRIPT
<script type="module">
  try {
    const {
      KlarnaSDK
    } = await import("https://js.klarna.com/web-sdk/v2/klarna.mjs")
    const klarna = await KlarnaSDK({
      clientId: "klarna_test_client_***",
      products: ["PAYMENT"],
      partnerAccountId: "krn:partner:global:account:test:***",
      klarnaNetworkSessionToken: "[klarna_network_session_token]", // retrieved from server or received from Partner
      locale: "en-US" // optional but recommended
    });

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 in your site's notices. 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.

Step 4: Present Klarna in the payment form (Frontend)

After initializing the Web SDK, request Klarna's Payment Presentation to retrieve the visual assets, localized text, and display instructions needed to render Klarna as a payment method. The Web SDK dynamically adapts the presentation based on the customer's context, ensuring a consistent experience across different checkout states.

The process involves:

  1. 1.
    Request Klarna's Payment Presentation using the initialized Web SDK
  2. 2.
    Mount Klarna payment method components dynamically in your payment form
  3. 3.
    Handle customer interactions (selection, deselection)
  4. 4.
    Configure and display the payment button
  5. 5.
    Implement the initiate callback to authorize the Payment Transaction when the customer clicks the button
Klarna payment method without preselection
Klarna payment method selected
Saved payment method preselected
Pick Plan option selected
One payment method without preselectionOne payment method selectedSaved payment method available and selectedPick Plan option selected

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:

ParameterRequiredDescription
amountYesThe transaction amount in minor units following ISO 4217 exponents (for example, $118.00 = 11800, 1400 = 1400). This field is required if the intent is set to PAY, SUBSCRIBE, or DONATE; otherwise, it is optional.
currencyYesThree-letter ISO 4217 currency code (for example, USD, EUR).
localeNoLocale code to localize texts and formats (for example, 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.
intentNoSpecify the intent of the checkout flow: PAY, SUBSCRIBE, SIGNUP, SIGNIN, DONATE, ADD_TO_WALLET. If omitted, intent 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.

Refresh Payment Presentation when the total amount changes. The assets returned by klarna.Payment.presentation() (instalment amounts, messaging, and links) are tied to the amount you pass in the call. If the customer changes the basket or final amount after Klarna is already displayed you must call klarna.Payment.presentation() again with the updated amount and re-render the Klarna payment method with the new response. Displaying presentation from an older total can show incorrect instalment amounts and mislead customers.

Sample code

JAVASCRIPT
const paymentPresentation = await klarna.Payment.presentation({
  amount: 11800,
  currency: "USD",
  locale: "en-US",
  intent: "PAY"
});

Klarna Payment Presentation response

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

ParameterRequiredPurpose
instructionYesSpecifies how Klarna as a payment option(s) should be displayed (for example, 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.
paymentOptionNoDefines the default payment option applicable to all purchase types. This object includes the visual elements required to represent Klarna during checkout.
savedPaymentOptionNoDefines the customer's saved payment option, available when a Customer Token (customer_token) is used. This object includes the same visual elements as paymentOption for displaying Klarna. When present, prioritize displaying this option to provide the best customer experience.

paymentOption and savedPaymentOption share a similar object structure:

ParameterRequiredDescription
paymentOptionIdYesThe 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.
iconYesKlarna badge/logo suitable for checkout forms.
headerYesThe main descriptor that introduces Klarna in the payment form. The value will be dynamically adjusted based on the locale provided.
subheaderYesThe 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.
messageNoEnriched tailored description with link.
badgeNoBadge used for saved options or promotions.
termsNoDefines terms/disclosures potentially with links.
paymentButtonYesPayment button that starts the Klarna Purchase Journey.

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

Follow Klarna Payment Presentation instruction

Apply Klarna's Payment Presentation instructions to control how Klarna appears in your checkout. Following these instructions ensures consistent customer experiences and enables features like Klarna Express Checkout and Sign in with Klarna.

Your implementation must handle both paymentOption (default) and savedPaymentOption (customer-specific). Prioritize savedPaymentOption when both are present.

The instruction attribute indicates how Klarna should be displayed:

InstructionDescription
SHOW_KLARNADisplay Klarna alongside other payment methods.
PRESELECT_KLARNADisplay Klarna pre-selected alongside other payment methods. Returned when the customer has signed in with Klarna or has a saved payment option.
SHOW_ONLY_KLARNADisplay Klarna as the only payment method. Returned after the customer completes the first step of Klarna Express Checkout.
HIDE_KLARNAHide Klarna from payment methods. Returned when the Partner's access has been revoked.

For full API specifications, see Klarna web SDK.

The following examples show how to apply each instruction. Your implementation must prioritize savedPaymentOption over paymentOption when both are available:

Show KlarnaPreselect KlarnaShow only KlarnaHide Klarna
Without saved payment method
Show Klarna without saved payment method
Preselect Klarna without saved payment method
Show only Klarna without saved payment method
Hide Klarna without saved payment method
With saved payment method
Show Klarna with saved payment method
Preselect Klarna with saved payment method
Show only Klarna with saved payment method
Hide Klarna with saved payment method

The presentation instructions are derived from possible customer Purchase Journeys described in the following 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;
  }

  // Create containers for both saved and default payment options
  root.innerHTML = `     <div id="klarna-option-saved" class="klarna-option saved" style="display:none;">
</div>

Mount Klarna payment method components

Once an instance of PaymentPresentation is created, the Klarna payment method(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 method 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 Klarna payment method selection and deselection

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

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

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

Handle Klarna payment button styling and initiate callback

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. 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 customer engagement. More details on the button styling can be found here.

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

ParameterRequiredDescription
idNoSets a custom DOM ID on the rendered button. Useful for testing or styling.
shapeNoDefines the button's shape. Possible values are:default, pill, rect
themeNoSets the visual theme of the button. Possible values are: default, light, dark, outlined
localeNoSets the language and region (for example, 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.
disabledNoDisables the button when set to true. Useful during form validation or async actions.
loadingNoForces the button into a loading state. Useful when awaiting async setup or validation.
intentsNoSets the purpose of the payment. Used to personalize the button and flow if not set when creating the PaymentPresentation instance.
initiateYesFunction that returns a Promise resolving to either a PaymentRequestData, a paymentRequestId, or a returnUrl. This will be handled differently depending on the integration path.
initiationModeNoDefines 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"
    intent: "PAY",
    initiationMode: "DEVICE_BEST", // "DEVICE_BEST" | "ON_PAGE" | "REDIRECT"
    initiate: (klarnaNetworkSessionToken, paymentOptionId) =>
      initiateKlarnaPayment(klarnaNetworkSessionToken, paymentOptionId)
  })
  .mount(`#${containerId}-payment-button`);

The button will automatically handle customer interaction and trigger the Klarna Purchase Journey via the initiate function.

Implement initiate callback

When using the Payment Authorize API, the Partner frontend implements the initiate callback to send the payment context to the Partner backend. The Partner backend then calls Klarna's authorizePaymentAPI action and returns the result.

The initiate callback receives two parameters from the Klarna web SDK:

  • klarnaNetworkSessionToken — represents payment context, including the customer's authentication and consent state. Forward this to the Partner backend and include it in the Klarna-Network-Session-Token header when calling the Payment Authorize API.
  • paymentOptionId — identifies which payment option the customer selected. Forward this to the Partner backend and include it as the payment_option_id field in the request body when calling the Payment Authorize API.

The callback must return a Promise that resolves to a returnUrl when Klarna returns STEP_UP_REQUIRED, or null if the authorization completes immediately (APPROVED or DECLINED).

Sample code

JAVASCRIPT
async function initiateKlarnaPayment(klarnaNetworkSessionToken, paymentOptionId) {
  // Partner-implemented backend endpoint that calls Klarna's authorizePayment
  const response = await fetch("/api/authorize-payment", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      klarnaNetworkSessionToken,
      paymentOptionId,
      amount: 11800,
      currency: "USD"

Next steps

After building the payment form, complete your integration:

Related articles

Partner Accounts

Manage your API credentials

Klarna Network Session Token

Sharing supplementary purchase data

Payment Authorization

API & SDK references

API