Build checkout form with Klarna Presentation API (Worldpay orchestrated)
Integrate Klarna without the Web SDK. Fetch the payment presentation server-side from Klarna, render Klarna yourself in the payment selector, and let Worldpay orchestrate the Klarna authorization.
This flow does not use the Klarna Web SDK. You call Klarna's Payment Presentation API server-side, render Klarna in your own payment selector, and delegate the authorization (including step-up handling and webhooks) to Worldpay. You don't need to register webhooks with Klarna or call Klarna's Payment Request API directly.
Here's an overview of all the steps to display Klarna and initiate payments without the Web SDK in the Worldpay-orchestrated flow:
Your server calls Klarna's Payment Presentation API to retrieve assets and display instructions for the current purchase context.
You render Klarna as a payment option in your payment selector using the returned assets.
Customer selects Klarna and clicks the Klarna payment button.
Your server forwards the purchase details to Worldpay to create the payment session.
If customer authentication is required, Worldpay returns a payment_request_url and you redirect the customer's browser to it. The customer then completes the Klarna Purchase Journey on Klarna's hosted page — you don't render or orchestrate anything during this phase.
Worldpay notifies you when the order is completed.
You redirect the customer to your confirmation page.
sequenceDiagram
autonumber
participant C as Customer
participant P as Partner
participant AP as Worldpay
participant K as Klarna
C->>P: Visit checkout page
P->>K: GET payment/presentation
Note over P,K: Klarna-Network-Session-Token header (if applicable)
K-->>P: Return presentation assets and instructions
P->>P: Render Klarna in payment selector
C->>P: Select Klarna
C->>P: Click Klarna payment button
P->>AP: Create payment session
alt If customer authentication is required
AP-->>P: Return payment_request_url
P-->>C: Redirect to Klarna payment URL
C->>K: Complete Klarna purchase journey
end
AP-->>P: Order completed notification
P-->>C: Redirect to confirmation page
Presenting Klarna in the payment form involves retrieving the visual assets, localized texts, and display instructions required to correctly render Klarna as a payment option and display the payment button. In this flow you request the presentation server-side and render the option yourself using the returned assets.
On a high level, the process involves:
1.
Request Klarna's payment presentation for the current payment context from your server.
2.
Render Klarna payment option(s) in the payment form according to the instruction returned.
3.
Allow the customer to select and deselect the Klarna payment option.
4.
Display the Klarna button and start the payment process when clicked.
The expected outcomes are as follows:
Initial presentation
When 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.
Use the assets returned by the Payment Presentation API — do not hard-code Klarna branding, copy, or badges in your checkout.
Call the Klarna Payment Presentation API from your server to obtain the assets and the display instruction for the current purchase context.
Issue a GET request to /v2/accounts/{partner_account_id}/payment/presentation with query-encoded parameters. Authenticate with your API key using Authorization: Basic <API key>.
Basic checkout context parameters must be provided as query parameters:
Parameter
Presence
Description
partner_account_id
required (path)
Your Klarna-issued partner account identifier — the same value used elsewhere when you authenticate against Klarna.
currency
required
Three-letter ISO 4217 currency code (e.g., USD, EUR).
locale
required
Locale code to localize texts and formats (e.g., en-US, de-DE).
amount
conditional
The transaction amount in minor units following ISO 4217 exponents (e.g., $118.00 = 11800, ¥1400 = 1400). Required when intent is PAY or SUBSCRIBE; otherwise optional.
intent
optional
Intent of the checkout flow. Enum: PAY, SUBSCRIBE, ADD_TO_WALLET. Defaults to PAY.
You don't send any acquiring or Payment Account configuration on this call — Payment Account selection is owned by Worldpay, not by you.
When a Klarna Conversion Boost experience (Klarna Express Checkout, Sign in with Klarna, a tokenized flow, Klarna Messaging / Prequalification, etc.) has already produced a session token in a previous step, forward it as an HTTP header so Klarna can restore the customer's context and return a richer presentation (for example PRESELECT_KLARNA or SHOW_ONLY_KLARNA):
Header
Presence
Description
Klarna-Network-Session-Token
conditional
The Klarna network session token obtained from a previous Klarna Conversion Boost interaction. Omit when no prior Klarna context exists.
For the full request schema, consult the API reference.
Performance optimization
Call the Payment Presentation API concurrently with loading the rest of your payment methods. Aim to display Klarna within 100 ms of the other payment options.
The response provides the full Klarna branding package and the instruction tailored to the customer's purchase:
Attribute
Presence
Purpose
instruction
required
Specifies how Klarna as a payment option should be displayed (show, preselect, or show-only). Adhering to these payment presentation instructions ensures customers have the best possible experience and optimizes conversion rates.
payment_status
required
Current state of the underlying payment context, e.g. REQUIRES_CUSTOMER_ACTION.
payment_option
optional
Defines the default payment option applicable to all purchase types. Contains the visual elements and localized texts required to represent Klarna during checkout.
The payment_option object structure is as follows:
Attribute
Presence
Purpose
payment_option_id
required
The identifier of the payment option. Forward this value to Worldpay when creating the payment session.
icon
required
Object containing Klarna badge/logo assets in multiple aspect ratios (badge_image_url, square_image_url, rectangle_image_url) together with an alt text. Pick the variant that matches your checkout layout.
header
required
Localized main descriptor that introduces Klarna in the payment form. Contains a text string.
subheader
required
Localized subheader text to be displayed inline below the main descriptor. Provides transparency on available options (installments, pay later, etc.). Contains a text string.
message
optional
Enriched tailored description. Returned as a parts array of segments where each part is either a plain TEXT segment (optionally with styles like BOLD) or a LINK segment containing a url and context. Render the parts in order.
badge
optional
Badge text/asset used for saved options or promotions.
terms
optional
Localized terms/disclosures. Same parts structure as message — supports text and link segments.
payment_button
required
Label and icon for the Klarna payment button: text (button label), image_url (badge image to render next to the label), and image_alignment (LEFT or RIGHT).
For the full response schema, consult the API reference.
All localized texts and asset URLs are returned ready to use. You are expected to render them as-is in your own HTML — do not translate, relabel, or substitute Klarna imagery.
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:
Instruction
Description
Example
SHOW_KLARNA
Show Klarna alongside other payment methods.
PRESELECT_KLARNA
Show Klarna pre-selected but still alongside others. This is returned when the customer's context (for example a customer_token from Sign in with Klarna or a tokenization flow) has been forwarded via the Klarna-Network-Session-Token header.
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.
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.
Use the assets and localized strings from payment_option to render Klarna directly in your payment selector. The following diagram displays the visual components and how they are laid out:
1.
Icon
2.
Badge
3.
Header
4.
Subheader
5.
Message
6.
Terms
7.
Button
Ensure that all components — including those not immediately visible — are present in the DOM, and manage their visibility through your own logic or UI controls.
The message and terms objects return a parts array rather than pre-rendered HTML. Render the segments in order, applying any styles flags and turning LINK parts into anchors. Use the rendering approach that fits your stack — the example below shows a minimal string-builder version:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
functionrenderParts(parts) {
let html = "";
for (const part of parts) {
if (part.type === "LINK") {
html += `<a href="${part.url}" target="_blank" rel="noopener noreferrer">${part.text}</a>`;
} else {
const cls = part.styles?.includes("BOLD") ? "bold" : "";
html += `<span class="${cls}">${part.text}</span>`;
}
}
Do
Don't
Use the icon URL, label, and texts returned by the Payment Presentation API verbatim, including any links.
Hard-code the Klarna logo, badge, or copy, or strip links from the returned texts.
Render the message and terms blocks when Klarna is selected.
Hide or omit the message and terms blocks.
Request a fresh presentation on every checkout load (amount/currency/locale can change between sessions).
When the Klarna payment option is selected, reveal the supporting components (message, terms, payment_button); hide them again on deselection. Use whatever UI pattern your checkout already follows for other payment methods — there's nothing Klarna-specific here.
When the customer clicks the Klarna payment button, your server hands the purchase off to Worldpay — Worldpay then calls Klarna's Payment Authorize API on your behalf. The full request/response contract is owned by Worldpay; only the Klarna-specific identifier you must include is documented here.
Identifier
Where it comes from
Why Worldpay needs it
payment_option_id
The payment_option_id returned by the Klarna Payment Presentation API for the option the customer selected.
Tells Worldpay which Klarna option to authorize so the journey it presents matches what the customer just saw.
Refer to Worldpay's API reference for the full request shape (amount, currency, customer, shipping, line items, supplementary purchase data, response codes, etc.).
Create a new payment session on every Klarna button click — do not reuse a previous payment_request_url.
If Worldpay returns STEP_UP_REQUIRED with a payment_request_url, perform a full-page HTTP 302 redirect to that URL. The customer completes the Klarna Purchase Journey on Klarna's hosted page, and Worldpay takes care of finalizing the authorization and notifying you of the outcome.
You don't need to subscribe to Klarna webhooks, monitor the Klarna payment request lifecycle, or handle the klarna_network_session_token yourself — Worldpay handles these on your behalf.
The final order-completed notification is delivered by Worldpay according to their own callback/webhook contract. Use it as the signal to display the confirmation page to the customer.
Once the payment is authorized — either directly or after a successful step-up — Worldpay notifies you that the order is completed. Redirect the customer to your confirmation page based on Worldpay's notification.
In rare cases where there's a discrepancy between the amount and purchase details submitted to Worldpay and the information Klarna sees during step-up, the authorization may be rejected and the customer asked to approve the purchase again through the step-up journey.