Learn how to integrate Klarna Express Checkout with Worldline in your store.
Offer Klarna Express Checkout by displaying the Klarna payment button on your product or cart page.
![]() | ![]() | ![]() |
Klarna payment button featured in the Product detail page | Consumer confirms their payment and shipping details in one step | Consumer is redirected to merchant confirmation page after successful payment |
This integration guide is only for implementation one-click purchase flow, which ensures the lowest friction to customers.
Support for multi-step checkout will be added in a future release.
Before you integrate Express checkout, check that you meet the following prerequisites:
payment.request.state-change.completed
events following Webhooks guidelines.Subscribing to webhooks in the Klarna Portal will be available in a future release.
For a comprehensive, step-by-step walkthrough of these prerequisites, refer to the detailed integration guide.
Here's an overview of all the steps to add Klarna Express Checkout into your website:
https://js.klarna.com/web-sdk/v2/klarna.mjs
.initiate
callback to submit payment request data.shippingConfig
and handle shipping events (shippingaddresschange
, shippingoptionselect
).interoperability_token
.interoperability_token
and purchase details.The following diagram outlines the interactions among different components:
The Klarna Web SDK (klarna.mjs) follows 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. 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.
Use your clientId
to initialize the SDK.
<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
Parameter | Presence | Description |
---|---|---|
| required | A credential that identifies the Partner, acquired through Partner Portal. |
| optional | Array 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. |
| optional | Language 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.
Important implementation details
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.
Display Klarna payment button early in the shopping journey and provide customers with the option to skip ahead when they’re ready to purchase. High impact placements include the product detail page, cart page and checkout page.
![]() | ![]() | ![]() |
Klarna payment button in product detail page | Klarna payment button in cart | Klarna payment button in checkout |
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.
The button()
method can be configured with the following set of parameters:
Parameter | Presence |
---|---|
| required Currency in ISO 4217 format. Supported currencies: AUD, EUR, CAD, CZK, DKK, HUF, MXN, NZD, NOK, PLN, RON, SEK, CHF, GBP, USD. |
| 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. |
| optional Additional details about the transaction can help reduce the risk of fraud and enhance transparency. Client side availability:
Server side availability:
|
For the full API specifications, refer to 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
const klarnaPaymentButton = klarna.Payment.button({
initiate: () => {
// Collect any data you want to send to your server here:
// const postData = { ... };
// const resp = await fetch('/create-klarna-payment-request', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(postData)
// });
// const data = await resp.json();
For the full API specifications, refer to Klarna Web SDK.
Server code
// server.js
const express = require('express');
const axios = require('axios');
const bodyParser = require('body-parser');
// Klarna credentials (replace with your own, preferably load from env!)
const KLARNA_API_KEY = 'YOUR_API_KEY';
const KLARNA_BASE_URL = 'https://global-api.klarna.com'; // According to docs
const app = express();
For the full API specifications, refer to the API referenceAPI.
Create a new payment request on every button click instead of reusing payment requests.
This approach allows you to conveniently send data to Klarna directly from the client. Return the payment request payload as follows:
const klarnaPaymentButton = klarna.Payment.button({
initiate: () => {
return {
currency: "USD",
amount: 1000,
paymentRequestReference: "pay-ref-123",
supplementaryPurchaseData: {
purchaseReference: "pay-ref-123",
lineItems: [],
shipping: [],
For the full API specifications, refer to Klarna Web SDK.
If you're selling digital goods, you can ignore this section.
Klarna Express Checkout allows customers to complete their purchase within Klarna’s interface, where they can select a payment method, enter their shipping address, and choose from available shipping options. This reduces the need for address collection on the merchant’s side and enables a more streamlined checkout experience, especially on mobile. Shipping methods can be dynamically calculated and returned based on the customer’s input, allowing for flexibility in delivery pricing and timing. This setup helps simplify integration while improving the overall user flow.
![]() | ![]() |
Display shipping banner | Display shipping options |
To enable the shipping banner and collect shipping details, include "shipping_config": { "mode": "EDITABLE" }
in the payment request. The collected shipping details will be available under state_context.shipping
after the customer approves the purchase.
If you need to restrict the countries to which you ship, include the supported_countries
attribute with a list of permitted countries. By default, all Klarna-supported countries are available unless specified otherwise.
Update the server code as followed:
async function createKlarnaPaymentRequest(data) {
const url = `${KLARNA_BASE_URL}/v2/payment/requests`;
const payload = {
currency: "USD",
amount: 1000,
payment_request_reference: "pay-ref-123",
supplementary_purchase_data: {
purchase_reference: "pay-ref-123",
line_items: [],
shipping: [],
In case the payment request was created on the client side, update the client code as followed:
const klarnaPaymentButton = klarna.Payment.button({
initiate: () => {
return {
currency: "USD",
amount: 1000,
paymentRequestReference: "pay-ref-123",
supplementaryPurchaseData: {
purchaseReference: "pay-ref-123",
lineItems: [],
shipping: [],
The collected shipping data will be available when the payment request is completed. See Monitor payment status for more information.
Parameter | Presence | Description |
---|---|---|
| required | ("EDITABLE" Values: ("EDITABLE", "READ_ONLY") Configure if the shipping details should be collected from the customer. If mode is set to EDITABLE then the shipping details will be collected from the customer and will be available under stateContext.shipping when the payment request is in state COMPLETED .If mode is set to READ_ONLY (future-release) then the customer can only see the shipping details that are provided in the supplementaryPurchaseData.shipping[0] object without the ability to change them. |
| optional | Partner's supported shipping countries (ISO 3166-1 alpha-2) |
For the full API specifications, refer to Klarna Web SDK.
The READ_ONLY
mode will be supported in a future release.
Customers easily select their shipping address and preferred shipping method directly within the Klarna review page, enabling the customer to checkout with one click.
To enable proper functionality of the shipping options integration, you, as the integrator, need to handle two event callbacks: shippingaddresschange
and shippingoptionselect
. These events allow you to communicate available shipping options after an address is selected, enabling the customer to choose from the provided options.
Handle shipping address change events
Parameter | Presence | Description |
---|---|---|
| required | Total amount of the shipping method selected by the customer. The value should be in non-negative minor units. Eg: 25 Euros should be 2500. |
| required | Description of the type of shipping the customer has selected at the checkout. E.g: "1 - 3 working days", "1 working day". |
| required | The shipping option as selected by the customer at the Partner website. |
| required | Unique reference to this shipping option. Required if the payment request contains multiple shipping objects. This can be any string, and does not have to correspond to a delivery or tracking number. |
| optional | The type of shipping option the customer selected. This can be:
|
When the customer selects a different shipping option, you will receive a shippingoptionselect
event. Here you are supposed to return the updated the amount
and lineItems
properties to reflect the selected shipping cost. In some rare cases, if the shipping option is no longer available, you can reject the selection.
For the full API specifications, refer to Klarna Web SDK.
The shippingoptionselect
event is triggered every time a customer selects a different shipping option. You should return an updated order data here. If nothing was returned in 5 seconds, the purchase flow will end in an error state.
The SDK allows you to request necessary customer profile data to fulfill the purchase transaction such as email and phone number.
Legal notice
Requesting and processing a customer’s identity information is strictly regulated under the General Data Protection Regulation (European Union) as well as other applicable data protection and privacy laws in the jurisdictions where you operate. You must ensure you have a lawful basis for collecting such data, which may only be used for the explicit purpose of fulfilling the current purchase transaction.
Any use of this information beyond what is necessary for order fulfillment—such as creating a customer account, marketing, or profiling—is strictly prohibited and may result in significant legal liabilities, including fines and sanctions, under relevant privacy legislation.
It is your responsibility to fully comply with all applicable data protection and privacy requirements at all times and to safeguard customer information in accordance with the highest legal standards.
</div>
To enable this feature, include the collect_customer_profile
with the list of required customer data values. The table below described the data that will be returned for following parameters:
Parameter | Presence | Description |
---|---|---|
| optional | Customer email address. |
| optional | Full name of the customer. |
| optional | Phone number in E.164 international format. If a local format is received it is assumed to be within the country as specified in the address object. |
| optional | Domicile address of the customer. |
| optional | The locale follows the format of IETF BCP 47. |
Update the server code as followed:
async function createKlarnaPaymentRequest(data) {
const url = `${KLARNA_BASE_URL}/v2/payment/requests`;
const payload = {
currency: "USD",
amount: 1000,
payment_request_reference: "pay-ref-123",
supplementary_purchase_data: {
purchase_reference: "pay-ref-123",
line_items: [],
shipping: [],
In case the payment request was created on the client side, update the client code as followed:
const klarnaPaymentButton = klarna.Payment.button({
initiate: () => {
return {
currency: "USD",
amount: 1000,
paymentRequestReference: "pay-ref-123",
supplementaryPurchaseData: {
purchaseReference: "pay-ref-123",
lineItems: [],
shipping: [],
For the full API specifications, refer to Klarna Web SDK.
The collected customer profile data will be available when the payment request is completed. See next section, Monitor payment status, for more information.
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 subscribe to Klarna Webhooks.
Every successful approval will trigger the payment request to enter the COMPLETED
state. Klarna will then trigger a payment request state change webhook to which you have to subscribe to:
Event name | When |
---|---|
| To track when payment requests get to the COMPLETED state. |
From this request you will be able to retrieve the interoperability_token
which is needed to authorize the payment and complete the Express Checkout flow.
Once your webhooks are set up, you can manage them through API requests. Use these requests to update, delete, or retrieve details about your configurations.
Consult the API referenceAPI for a comprehensive parameter information.
Subscribing to webhooks in the Klarna Portal will be available in a future release.
The field shipping
and klarna_customer
in the webhook payload will be available in a future release.
Webhook payload sample
{
"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",
On the frontend, you can listen for the complete
event. When the customer successfully completes the purchase flow, the payment request’s status will change to COMPLETED
, and y and you can then retrieve the interoperability token.
klarna.Payment.on("complete", async (paymentRequest) => {
// The customer has successfully completed the payment flow and
// the payment request can be confirmed using the interoperability token.
});
Sample paymentRequest callback
{
"paymentRequestId": "krn:payment:eu1:request:64be490f...",
"state": "COMPLETED",
"stateContext": {
"interoperabilityToken": "krn:network:eu1:interoperability-token:e15432a5-ebcc-45bc-934c-e61399db597b",
"shipping": {
"recipient": {
"givenName": "Klara",
"familyName": "Test",
"email": "recipient@email.us",
For the full API specifications, refer to Klarna Web SDK.
Important
Relying on Web SDK events solely will lead to a high number of abandoned payment requests. Always use this approach in combination with the Webhooks to ensure the best conversion rate.
For Global Collect, make sure to add the interoperability_tokenAPI
in the paymentProduct838SpecificInput
field within the payment requestAPI call Global Collect's API.
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.