Klarna Direct

Authorize a customer-initiated payment (Mobile SDK)

Authorize a customer-initiated payment when the Klarna Mobile SDK is embedded in a native iOS, Android, or React Native app. The SDK presents Klarna and orchestrates the Klarna Purchase Journey; the Partner authorizes the payment directly with Klarna using the Klarna Network Session Token.
435 min read

Overview

Use this guide when the Klarna Mobile SDK is embedded in a native iOS (Swift), Android (Kotlin), or React Native app and the Partner wants to present Klarna in the payment form and launch the Klarna Purchase Journey from the Klarna payment button.
The Mobile SDK renders Klarna's UI components and drives the customer-facing Klarna Purchase Journey, while the Partner's backend creates the Payment Request and finalizes the authorization with Klarna.
The underlying API calls mirror the server-side flow and the Web SDK flow: createPaymentRequestAPI, retrieve the klarna_network_session_token, then authorizePaymentAPI. What differs is the orchestration: the Mobile SDK presents Klarna and launches the Klarna Purchase Journey natively, and the Partner authorizes the payment directly with Klarna.
This guide covers iOS (Swift), Android (Kotlin), and React Native integrations.

Prerequisites

Before you integrate, check that you meet the following prerequisites:
  1. 1.
    A valid Klarna Partner account with API credentials, obtained through your direct agreement with Klarna.
  2. 2.
    Access to the Klarna Partner Portal.
  3. 3.
    Inside the Klarna Partner Portal:
    1. 3.1.
      A client identifier has been generated.
    2. 3.2.
      An API key has been generated.
  4. 4.
    Backend capability to receive and process Klarna webhooks, with a subscription to the payment.request.state-change.completed event. See Setup your webhooks.
  5. 5.
    Terms and Conditions for client-side SDK usage are accepted as required by your Klarna agreement.

Integration overview

Here's an overview of all the steps to process a payment with Klarna via the Mobile SDK as a Partner:
  1. 1.
    Present Klarna as a payment method in the payment form.
  2. 2.
    The customer taps the Klarna payment button in your checkout.
  3. 3.
    You create the payment request — either client-side using the Klarna Mobile SDK, or server-side by calling the Klarna Payment Request API — sharing all available interoperability data points.
  4. 4.
    If customer interaction is required:
    • 4.1.
      The Klarna Purchase Journey is launched.
    • 4.2.
      The customer completes the Klarna Purchase Journey.
  5. 5.
    Klarna returns a klarna_network_session_token via the payment.request.state-change.completed webhook.
  6. 6.
    You authorize the payment directly with Klarna by calling authorizePaymentAPI with the Klarna-Network-Session-Token header.
  7. 7.
    Klarna responds with the authorization result and creates the Payment Transaction.
  8. 8.
    The customer is returned to your confirmation page.
sequenceDiagram participant C as Customer participant FE as Partner app (Mobile SDK) participant BE as Partner backend participant K as Klarna C->>FE: Open checkout screen FE->>K: Initialize Klarna Mobile SDK FE->>K: Request payment presentation K->>FE: Return assets and instructions FE->>FE: Render payment selector<br>Show Klarna payment button C->>FE: Tap Klarna payment button Note over FE,BE: Handle the "Pay with Klarna" button tap alt Client-side payment request initiation FE->>K: Create and initiate payment request else Server-side payment request initiation FE->>BE: Request payment request BE->>K: Create payment request K->>BE: Return payment_request_id BE->>FE: Return payment_request_id FE->>K: Initiate with payment request ID end K->>C: Start Klarna Purchase Journey C->>K: Complete Klarna Purchase Journey K-->>BE: Webhook payment.request.state-change.completed Note over K,BE: klarna_network_session_token BE->>K: authorizePayment with Klarna-Network-Session-Token header K->>BE: APPROVED, payment_transaction BE->>FE: Confirmation FE->>C: Return to confirmation page

Integration details

Present Klarna in the payment form

Integrate the Klarna Mobile SDK to display Klarna as a payment method within your own payment form. This approach lets you fully control the checkout experience while using Klarna's ready-made UI components for secure payment handling.
This guide explains how to present Klarna in your payment form, both during the initial load and after the customer selects Klarna. By following these steps, you'll ensure the payment flow meets Klarna's design and functionality standards:
undefined
undefined
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 method, please apply the following recommendations:
  • Present Klarna dynamically alongside other payment methods in your payment form.
  • Embed Klarna's UI elements directly in your frontend for a consistent and responsive design.

Import the Mobile SDK

Choosing Mobile SDK products
The Klarna Mobile SDK is split into several products (and packages) so your integration stays modular. Each capability is delivered as its own product, so you add only the frameworks your use case requires and keep your app's binary size and dependency footprint to a minimum.
For Klarna Network (KN) integrations, add only the KlarnaNetwork* products your use case requires:
ProductPurpose
KlarnaNetworkPaymentPayment presentation and the payment request and authorization flow. Required for this guide.
KlarnaNetworkPaymentButtonThe Klarna payment button UI component.
KlarnaNetworkMessagingOn-site messaging and pre-qualification placements.
KlarnaNetworkIdentitySign in with Klarna and identity flows.
Several of these products also ship UI-framework-specific variants — such as Button frameworks with SwiftUI on iOS, and Jetpack Compose on Android — so you can pull in just the UI layer that matches your stack with appropriate product suffixes (SwiftUI or -compose) without adding the rest.
iOS
Swift Package Manager
To add the required dependency, do the following steps:
  1. 1.
    In Xcode, select File → Add Package Dependencies...
  2. 2.
    In the opened window, enter https://github.com/klarna/klarna-mobile-sdk-ios in the search bar.
  3. 3.
    For Dependency Rule, select Up to Next Major Version and leave the default version as is.
  4. 4.
    For Add to Project, select your project.
  5. 5.
    Click Add Package.
  6. 6.
    In the new window that opens, add KlarnaNetworkPayment and the button product that matches your UI framework — either KlarnaNetworkPaymentButton for UIKit or KlarnaNetworkPaymentButtonSwiftUI for SwiftUI — to your desired target.
Add only one of the two button products. KlarnaNetworkPaymentButtonSwiftUI is layered on top of KlarnaNetworkPaymentButton and depends on it, so the UIKit module comes along automatically and does not need to be added separately.
Neither button module transitively includes KlarnaNetworkPayment — neither the Swift Package Manager product nor the CocoaPods subspec — so you must always add KlarnaNetworkPayment alongside your chosen button module (or use the full KlarnaMobileSDK). The button modules import KlarnaNetworkPayment types, so omitting it results in a missing-module error.
Cocoapods
First, add the Klarna Mobile SDK's Payment module and the Payment Button module for your UI framework to your Podfile:
SH
1 2 3
pod "KlarnaMobileSDK/KlarnaNetworkPayment" pod "KlarnaMobileSDK/KlarnaNetworkPaymentButton"
Or, for example, if you're building the button with SwiftUI, use the KlarnaNetworkPaymentButtonSwiftUI subspec instead:
SH
1 2 3
pod "KlarnaMobileSDK/KlarnaNetworkPayment" pod "KlarnaMobileSDK/KlarnaNetworkPaymentButtonSwiftUI"
Next, run the command below and then you should be able to import KlarnaMobileSDK module in your workspace and start using it.
SH
1 2
pod install
Android
Add only one of the two button modules — klarna-network-payment-button-compose transitively includes klarna-network-payment-button.
Kotlin
First, add the Klarna Mobile SDK Maven repository:
KOTLIN
1 2 3 4
repositories { maven("https://x.klarnacdn.net/mobile-sdk/") }
Next, add the Klarna Mobile SDK's Payment library and the Payment Button library for your UI framework as dependencies to your application:
KOTLIN
1 2 3 4 5
dependencies { implementation("com.klarna.mobile.sdk:klarna-network-payment:<LATEST_VERSION>") implementation("com.klarna.mobile.sdk:klarna-network-payment-button:<LATEST_VERSION>") }
Or, for example, if you're building the button with Jetpack Compose, use the klarna-network-payment-button-compose module instead:
KOTLIN
1 2 3 4 5
dependencies { implementation("com.klarna.mobile.sdk:klarna-network-payment:<LATEST_VERSION>") implementation("com.klarna.mobile.sdk:klarna-network-payment-button-compose:<LATEST_VERSION>") }
To find the latest version you can always refer to this link.
Groovy
First, add the Klarna Mobile SDK Maven repository:
GROOVY
1 2 3 4 5 6
repositories { maven { url 'https://x.klarnacdn.net/mobile-sdk/' } }
Next, add the Klarna Mobile SDK's Payment library and the Payment Button library for your UI framework as dependencies to your application:
GROOVY
1 2 3 4 5
dependencies { implementation 'com.klarna.mobile.sdk:klarna-network-payment:<LATEST_VERSION>' implementation 'com.klarna.mobile.sdk:klarna-network-payment-button:<LATEST_VERSION>' }
Or, for example, if you're building the button with Jetpack Compose, use the klarna-network-payment-button-compose module instead:
GROOVY
1 2 3 4 5
dependencies { implementation 'com.klarna.mobile.sdk:klarna-network-payment:<LATEST_VERSION>' implementation 'com.klarna.mobile.sdk:klarna-network-payment-button-compose:<LATEST_VERSION>' }
To find the latest version you can always refer to this link.
React Native
The React Native packages require React Native 0.76.0 or later with the New Architecture (TurboModules) enabled, iOS 13+, and Android API 21+.
First, add the core package and the payment package as dependencies:
SH
1 2
yarn add @klarna/react-native-klarna-network-core @klarna/react-native-klarna-network-payment
Then import the payment package once at app startup (for example in your root index.js) to activate the payment property on Klarna:
TS
1 2
import '@klarna/react-native-klarna-network-payment';
Source and package details are available on this link.

Initialize the Mobile SDK

The first step to add Klarna Payment to your application is to initialize the Klarna SDK:
SWIFT
1 2 3 4 5 6 7 8 9 10
// Create an instance of KlarnaConfiguration let configuration = KlarnaConfiguration( clientId: <CLIENT_ID>, locale: <LOCALE>, appReturnUrl: <APP_RETURN_URL>, klarnaNetworkSessionToken: <KLARNA_NETWORK_SESSION_TOKEN> ) // Initialize Klarna let klarnaResult = Klarna.initialize(configuration: configuration)
The following table lists the properties of KlarnaConfiguration.
NameTypePresenceDescription
clientIdStringrequiredThe client ID of the Partner account that is integrating the Mobile SDK.
appReturnUrlStringrequired on iOS and React NativeThe URL that Klarna uses to return the customer to your app after the Klarna Purchase Journey. Not available on Android.
localeStringoptionalThe default locale (ISO 3166-1 alpha-2) that will be used by the SDK. If not set, the locale of the device will be used.
klarnaNetworkSessionTokenStringoptionalThe klarna network session token allows the SDK to be initialized with an existing session.
You set the app return URL once, when you initialize the SDK. On iOS and React Native, appReturnUrl is a required property of KlarnaConfiguration, and the SDK sends it as app_return_url on the payment requests it creates on your behalf. On Android the property does not exist — the SDK derives the return URL from your app's package name and handles the hand-back itself, so there is nothing for you to configure.

Klarna payment presentation request

Klarna payment presentation provides all the visual assets, localized texts, and instructions needed to correctly display Klarna in your checkout screen. To fetch the payment presentation, you need to call the KlarnaPaymentPresentation.fetch() method like below:
SWIFT
1 2 3 4 5 6 7 8 9 10
// Create an instance of KlarnaPaymentPresentationData let paymentPresentationData = KlarnaPaymentPresentationData( amount: <AMOUNT>, currency: <CURRENCY>, intent: <INTENT>, paymentProgramEnablementCodes: <PAYMENT_PROGRAM_ENABLEMENT_CODES>, subscriptionBillingInterval: <SUBSCRIPTION_BILLING_INTERVAL>, subscriptionBillingIntervalFrequency: <SUBSCRIPTION_BILLING_INTERVAL_FREQUENCY> )
The following table lists the parameters of KlarnaPaymentPresentation.fetch() method.
NameTypePresenceDescription
dataKlarnaPaymentPresentationDatarequiredSpecifies the data that is used to tailor the payment presentation content.
callbackKlarnaPaymentPresentationCallbackrequiredThe callback to get notified of the result of payment presentation fetch.
The table below lists the properties of KlarnaPaymentPresentationData:
NameTypePresenceDescription
amountLong (Android), Int64 (iOS)requiredThe transaction amount in minor units following ISO 4217 exponents (e.g., $118.00 = 11800, ¥1400 = 1400).
currencyStringrequiredThree-letter ISO 4217 currency code (e.g. USD, EUR).
intentKlarnaPaymentPresentationIntentoptionalSpecifies the intent of the payment presentation content for your use case. It can be used when you need presentation elements tailored to specific payment scenarios.
subscriptionBillingIntervalKlarnaIntervaloptionalSpecifies the interval of which the customer is charged for the subscription.
subscriptionBillingIntervalFrequencyIntrequired if the interval is setDefines the subscription interval frequency.
The intent property is of type KlarnaPaymentPresentationIntent and can have the following possible values. If not set, PAY is used.
SwiftKotlin and React NativeDescription
payPAYStandard payment transaction. Requires amount.
subscribeSUBSCRIBESubscription-based payment. Requires amount, subscriptionBillingInterval, and subscriptionBillingIntervalFrequency.
addToWalletADD_TO_WALLETAdd Klarna to the customer's wallet for later use.
The subscriptionBillingInterval property is of type KlarnaInterval and can have the following possible values.
SwiftKotlin and React NativeDescription
dayDAYThe customer is charged daily.
weekWEEKThe customer is charged weekly.
monthMONTHThe customer is charged monthly.
yearYEARThe customer is charged yearly.
On iOS these are Swift enum cases written in lower camel case, for example addToWallet. On Android and React Native the same values are written in upper snake case, for example ADD_TO_WALLET.

Klarna payment presentation response

After a successful payment presentation fetch, you will get an instance of KlarnaPaymentPresentationContent containing the full Klarna branding package and instructions that can be used to present Klarna as a payment method.

Follow Klarna payment presentation instruction

This section explains how to handle Klarna's payment presentation instructions, which define how Klarna should appear within the checkout form. Adhering to these instructions is essential to maintain a consistent and optimized user experience—whether Klarna is displayed alongside other payment methods, preselected, or shown as the only available option.
Compliance with Klarna's presentation instructions is especially important when integrating Conversion features, such as Express checkout or Sign in with Klarna, to ensure a seamless and unified customer experience.
The instruction property available in KlarnaPaymentPresentationContent can have the following possible values:
NameDescription
SHOW_KLARNAShow Klarna alongside other payment methods.
PRESELECT_KLARNAShow Klarna pre-selected but still alongside other payment methods. This is returned when using the customer_token issued from the Sign in with Klarna feature or the tokenization flow.
SHOW_ONLY_KLARNAShow Klarna as the only payment method. This is returned when the customer has finished the first step of multi-step Express checkout.
Skip this section if you don't use any Conversion features such as Express checkout, Sign in with Klarna, Klarna Messaging or Klarna Prequalification.
Here are example outcomes illustrating how Klarna should be displayed for each instruction:
undefined
undefined
undefined
Show KlarnaPreselect KlarnaShow only Klarna
The presentation instructions are derived from possible customer purchase journeys described in Present Klarna in your checkout.
The following code snippet shows an example of how instruction can be used to decide how to present Klarna as a payment method.
SWIFT
1 2 3 4 5 6 7 8 9 10
private func renderKlarnaPresentation(content: KlarnaPaymentPresentationContent) { let instruction: KlarnaPaymentPresentationInstruction = content.instruction switch instruction { case .showKlarna: // Show Klarna alongside other payment options case .preselectKlarna: // Preselect Klarna as the default payment option case .showOnlyKlarna: // Show only Klarna as the payment option }
Mount Klarna payment option components
After fetching the payment presentation, you have access to an instance of KlarnaPaymentPresentationContent. It can be used to present Klarna as a payment method. The Klarna payment option must be rendered in the payment selector according to Klarna's presentation guidelines.
The following table lists the properties of KlarnaPaymentPresentationContent.
NameTypePresenceDescription
instructionKlarnaPaymentPresentationInstructionrequiredSpecifies how Klarna should be displayed as a payment option (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.
paymentOptionKlarnaPaymentPresentationPaymentOptionoptionalSpecifies the default payment option applicable to all purchase types. It includes the visual elements required to represent Klarna during checkout.
paymentStatusKlarnaPaymentPresentationPaymentStatusoptionalSpecifies the payment status of the presentation.
The KlarnaPaymentPresentationPaymentOption type has the following properties:
NamePresenceDescription
paymentOptionIdrequiredThe identifier of the payment option. This value is required to be sent to the Payment Authorize API or the Payment Request API when initiating the payment.
headeroptionalThe main descriptor that introduces Klarna in the payment form. The value will be dynamically adjusted based on the locale provided when you initialized the Klarna SDK.
subheaderoptionalThe sub-header descriptor that must be loaded inline below the main descriptor header. It's a short and enriched descriptive text that provides transparency on available options like installments, pay later, etc.
messageoptionalEnriched tailored description with link.
badgeoptionalBadge used for saved options or promotions.
termsoptionalDefines terms/disclosures potentially with links.
  1. 1.
    icon
  2. 2.
    badge
  3. 3.
    header
  4. 4.
    subheader
  5. 5.
    message
  6. 6.
    terms
  7. 7.
    button
Present the Klarna payment option elements within your Klarna payment method view to render them in the payment form. The code snippet below shows a very basic sample of how you can do so:
SWIFT
1 2 3 4 5 6 7 8 9 10
private func renderKlarnaPresentation(content: KlarnaPaymentPresentationContent) { if let headerText = content.paymentOption?.header, case .plainText(let text) = headerText { // Show the header text in the UI (for example in a UITextView) } if let subheaderText = content.paymentOption?.subheader, case .plainText(let text) = subheaderText { // Show the subheader text in the UI (for example in a UITextView) } if let badgeText = content.paymentOption?.badge, case .plainText(let text) = badgeText { // Show the badge text in the UI (for example in a UITextView) }

Handle Klarna payment option selection and deselection

When a Klarna payment option is selected/deselected, ensure the additional visual components are shown/hidden properly.
SWIFT
1 2 3 4 5 6 7 8 9 10
// UIKit approach func toggleKlarnaPaymentOptionSelection(isSelected: Bool) { // In this example, klarnaPresentationContainer is a view containing // presentation message, terms and button klarnaPresentationContainer.isHidden = !isSelected } // SwiftUI approach struct KlarnaPaymentOption: View { @State var isSelected: Bool
The message contained within the payment object contains two different classifications of links as set forth by the context value.
Context ValuePurpose
infoThis indicates that the content of the URL is purely informational.
authThis value indicates that the content of the URL requires customer authentication.
Due to the authentication requirements associated with the auth context, it is necessary for the link to be opened in a non-ephemeral ASWebAuthenticationSession on iOS and a CustomTab on Android. By contrast, info context links can be opened in any WebView. To simplify the requirements associated with properly handling these links, we have created the following method for you to call.
SWIFT
1 2 3 4 5 6 7 8 9 10
// Handle the presentation link klarna.payment.presentation.handleLink( content: <PAYMENT_PRESENTATION_CONTENT>, url: <URL>) { (result: Result<KlarnaPaymentPresentationContent, KlarnaSDKError>) in switch result { case .success(let paymentPresentationContent): // Payment presentation link handling was successful. paymentPresentationContent contains // the latest payment presentation information. print("Payment presentation link handling succeeded.")
The following table lists the parameters of KlarnaPaymentPresentation.handleLink() method.
NameTypePresenceDescription
activityActivityrequired for Android onlyThe Activity instance of your app.
contentKlarnaPaymentPresentationContentrequiredThe presentation content that you've already fetched using the KlarnaPaymentPresentation.fetch() method.
urlStringrequiredThe URL to handle.
callbackKlarnaPaymentPresentationCallbackrequiredThe callback to get notified of the result of payment presentation link handling.

Rendering the Klarna payment button

The Mobile SDK provides a native UI view called KlarnaPaymentButton that follows Klarna's visual identity.
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.
Creating Klarna payment button
To add the Klarna payment button to your app you can do something like below:
SWIFT
1 2 3 4 5 6 7 8 9 10
// Create an instance of KlarnaPaymentButtonConfiguration let paymentButtonConfiguration = KlarnaPaymentButtonConfiguration( state: .default, intent: .pay, shape: .pill, style: .outlined, theme: .light ) // Create the payment button
The table below lists the properties of KlarnaPaymentButtonConfiguration:
NameTypePresenceDescription
stateKlarnaButtonStateoptionalSets the initial state of the button. If not set, "default" will be used.
shapeKlarnaButtonShapeoptionalDefines the shape of the button. If not set, "rounded rect" will be used.
styleKlarnaButtonStyleoptionalDefines the style of the button. If not set, "filled" will be used.
themeKlarnaThemeoptionalDefines the theme of the button. If not set, "dark" will be used.
intentKlarnaPaymentButtonIntentoptionalDefines the intent that the payment button will be used for. Possible values: pay, subscribe, addToWallet.

Handle payment button tap

When the payment button is tapped, you should initiate the payment request process. This is done by calling the KlarnaPayment.initiate() method. There are two options for initiating the payment request using the initiate() method:
  • Client-side, sharing the details of customer's checkout session (paymentRequestData) when calling the initiate() method.
  • Using the Klarna payment_request_id associated with the customer's checkout session that was generated server-side by calling the Klarna Payment Request API.

Client-side payment request initiation

In client-side payment request initiation, you pass all the data needed to create and initiate a payment request to the Mobile SDK and the Mobile SDK takes care of creating and initiating the payment request. The following table lists the parameters of KlarnaPayment.initiate() method.
NameTypePresenceDescription
activityActivityrequired for Android onlyThe Activity instance of your app.
dataKlarnaPaymentRequestDatarequiredThe data needed to create and initiate the payment request.
callbackKlarnaPaymentRequestCallbackrequiredThe callback to get notified of the result of payment request initiation.
The table below lists all the properties of KlarnaPaymentRequestData.
ParameterPresenceDescription
currencyrequiredThree-letter ISO 4217 currency code (e.g., USD, EUR).
amountrequiredTotal 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.
paymentRequestReferenceoptionalReference to the payment session or equivalent resource created on the integrator's side.
supplementaryPurchaseDataoptionalProvides additional details about the transaction to help reduce fraud risk and enhance transparency. See Sharing supplementary purchase data.
shippingConfigoptionalConfigure how the shipping collection form will behave in the purchase flow. Without the shipping config, no shipping collection form will be displayed.
requestCustomerTokenoptionalObject to request customer account linking to be set up, effectively returning a token called customer_token on successful confirmation of the payment request.
SWIFT
1 2 3 4 5 6 7 8 9 10
// Create an instance of KlarnaPaymentRequestData let paymentRequestData = KlarnaPaymentRequestData( amount: <AMOUNT>, currency: <CURRENCY>, paymentRequestReference: <PAYMENT_REQUEST_REFERENCE>, requestCustomerToken: <REQUEST_CUSTOMER_TOKEN>, shippingConfig: <SHIPPING_CONFIG>, collectCustomerProfile: <COLLECT_CUSTOMER_PROFILE>, supplementaryPurchaseData: <SUPPLEMENTARY_PURCHASE_DATA> )

Server-side payment request initiation

Call the Klarna Payment Request API to initiate a transaction from your backend. 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.
For the full resource model and the states a Payment Request can transition through, see Payment Request.
Request
Call createPaymentRequestAPI with the payment context and a customer_interaction_config. For Mobile SDK integrations, set method to HANDOVER and provide both return URLs. return_url is required by the API and is used whenever the Klarna Purchase Journey ends in a browser, including a WebView inside your app. app_return_url is what returns the customer to your native app, so set it for any app integration.
Configure customer interaction parameters:
When integrating Klarna's purchase flow, it's essential to define how the customer should be redirected after completing or exiting the Klarna experience. Depending on whether the flow runs in a web or mobile app environment, Klarna uses one or both return URLs to ensure a seamless handoff back to the Partner's experience.
Parameter namePresenceDescription
return_urlrequired when method is HANDOVERIf the Klarna purchase flow is launched in a web environment, Klarna will redirect the customer to this URL after the customer finishes their interaction with Klarna, either by approving or aborting the purchase flow. This is a URL collected from the Partner.
app_return_urlrecommended for app integrationsThe customer may be redirected to a third party app (bank app) or the Klarna app during the Klarna Purchase Journey on mobile environments. This URL enables Klarna to return the customer back to the Partner's mobile app. Ensure the app_return_url is set up to register a URL scheme (e.g., partnerapp://klarna) that resumes the payment flow. The Partner is expected to open the integrating mobile application in its last state (no state changes or deeplink navigations).
Visual representations for Web flow and App handover flow:
undefined
undefined
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 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 2: 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.
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. See Sharing supplementary purchase data.
Data requirements
Depending on the business type, certain supplementary_purchase_data fields are required under the Klarna Network Rules. However, purchase_reference, line_items, customer and shipping whenever available must always be submitted, as they enable transaction-level traceability, power Klarna's fraud prevention and underwriting models, dispute handling, and ensure a consistent customer experience across Klarna's ecosystem.
Sample request
SHELL
1 2 3 4 5 6 7 8 9 10
curl https://api-global.test.klarna.com/v2/payment/requests \ -H 'Authorization: Basic <API key>' \ -H 'Content-Type: application/json' \ -d '{ "currency": "USD", "amount": 11800, "payment_request_reference": "partner-request-reference-1234", "customer_interaction_config": { "method": "HANDOVER", "return_url": "https://partner.example/klarna-redirect?id={klarna.payment_request.id}",
Response
When the request succeeds, Klarna returns a Payment Request in the SUBMITTED state.
The response includes:
  1. 1.
    payment_request_id — a unique identifier for the Payment Request.
  2. 2.
    payment_request_url — the URL used to initiate the customer's Klarna Purchase Journey.
Sample payload
JSON
1 2 3 4 5 6 7 8 9 10
{ "payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-aacb-41d55fafbdb4", "state": "SUBMITTED", "state_context": { "customer_interaction": { "method": "HANDOVER", "payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-aacb-41d55fafbdb4", "payment_request_url": "https://pay.test.klarna.com/na/requests/6bbf6775-[...]/start" } },
Once you have created the Payment Request, take the payment_request_id from the server-side response and provide it in the Mobile SDK initiate method as highlighted in the code below.
NameTypePresenceDescription
activityActivityrequired for Android onlyThe Activity instance of your app.
paymentRequestIdStringrequiredThe ID of the payment request that has been created server-side.
callbackKlarnaPaymentRequestCallbackrequiredThe callback to get notified of the result of payment request initiation.
SWIFT
1 2 3 4 5 6 7 8 9 10
@objc func didTapPaymentButton() { // Initiate the payment request klarna.payment.initiate(paymentRequestId: <PAYMENT_REQUEST_ID>) { (result: Result<KlarnaPaymentRequest, KlarnaSDKError>) in switch result { case .success(let paymentRequest): // Payment request initiation was successful. paymentRequest contains the // information about the payment request. print("Payment request initiation succeeded.") case .failure(let error): // Payment request initiation failed. More information about the failure

Receive the klarna_network_session_token

Once the customer completes the Klarna Purchase Journey, Klarna issues a klarna_network_session_token and the Payment Request transitions to COMPLETED. This token is used in the next step to finalize the authorization directly with Klarna.
Klarna provides multiple methods to retrieve the token. Subscribing to the webhook event is required and may be combined with reading the Payment Request as a fallback for resilience.
The klarna_network_session_token is valid for only 1 hour and must be used within this time frame to finalize the authorization. See Klarna Network Session Token — Expiration for the expiration model and where to read the expiration timestamp.

Method: Subscribe to the payment.request.state-change.completed webhook (required)

Klarna sends this event when the Payment Request reaches the COMPLETED state, indicating that the customer has approved the purchase and the authorization can be finalized. Subscribe via the Setup your webhooks guide.
Sample payload
JSON
1 2 3 4 5 6 7 8 9 10
{ "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:test:HGBY07TR", "recipient_account_id": "krn:partner:global:account:test:LWT2XJSE", "product_instance_id": "krn:partner:product:payment:ad71bc48-8a07-4919-[...]",
Never use Mobile SDK events to trigger Payment Authorization. Always rely on Klarna webhooks to receive the klarna_network_session_token and finalize the payment after the customer completes the purchase.

Method: Read the Payment Request (optional fallback)

As a fallback (for example, when the webhook is delayed or the handler missed it) retrieve the token by calling readPaymentRequestAPI. Once the Payment Request reaches the COMPLETED state, the token is available in state_context.klarna_network_session_token.

Authorize the payment

Finalize the payment by calling authorizePaymentAPI from your backend with the klarna_network_session_token in the Klarna-Network-Session-Token request header. Klarna creates the Payment Transaction and returns the result.
The customer's selected payment method is carried by the Klarna Network Session Token. There is no need to send payment_option_id.
Include at minimum:
ParameterRequiredDescription
Klarna-Network-Session-Token (header)YesThe Klarna Network Session Token received in the previous step.
currencyYesSame currency used in the Payment Request.
request_payment_transaction.amountYesSame amount used in the Payment Request.
request_payment_transaction.payment_transaction_referenceRecommendedThe Partner's own reference for the Payment Transaction, used for reconciliation.
supplementary_purchase_dataRecommendedSame supplementary data sent in the Payment Request. Significant differences may cause Klarna to require re-confirmation.
acquiring_configConditionalRoutes the Payment Transaction to a specific Payment Account or Payment Acquiring Account, and optionally requests the currency Klarna uses to settle the transaction. Add settlement_currency (ISO 4217) when a settlement currency that differs from the Payment Transaction currency is required. See Request settlement currency.
step_up_configRecommendedOpts the Partner in to the STEP_UP_REQUIRED outcome. When included, Klarna can request additional customer interaction (returning a new Payment Request) instead of declining cases where it needs more risk signals. Without it, those cases are returned as DECLINED. Set customer_interaction_config.method to HANDOVER and provide return_url, which the API requires, together with app_return_url, which returns the customer to your native app after the step-up Klarna Purchase Journey. See Payment Authorization.

Sample request

SHELL
1 2 3 4 5 6 7 8 9 10
curl https://api-global.test.klarna.com/v2/payment/authorize \ -H 'Authorization: Basic <API key>' \ -H 'Content-Type: application/json' \ -H 'Klarna-Network-Session-Token: krn:network:us1:test:session-token:eyJhbGciOiJIU...' \ -d '{ "currency": "USD", "request_payment_transaction": { "amount": 11800, "payment_transaction_reference": "partner-transaction-reference-1234" },

Handle the authorization result

Klarna returns a payment_transaction_response object. The result field indicates the outcome and determines the next action:
ResultDescriptionNext steps
APPROVEDThe authorization succeeded and a payment_transaction was created.Store the payment_transaction_id and proceed with post-purchase operations (capture, refund, etc.). Return the customer to a confirmation page.
DECLINEDThe authorization was not approved. No transaction is created. Common causes include an expired Klarna Network Session Token, significant discrepancies between the Payment Request and the authorize call, or risk evaluation requiring additional customer interaction when step_up_config was not included in the request.Show the customer a decline or alternative payment page.
STEP_UP_REQUIREDKlarna requires additional customer interaction before approving. Only returned when step_up_config was included in the authorize request. The response includes a new Payment Request with state_context.customer_interaction.payment_request_url.Pass the new Payment Request to the Mobile SDK so it can launch the step-up Klarna Purchase Journey. When the customer completes it, a new Klarna Network Session Token arrives via webhook. Call authorizePaymentAPI again with the new token.
Without step_up_config in the authorize request, Klarna cannot return STEP_UP_REQUIRED. It returns DECLINED instead in cases where additional customer interaction would have been needed. Klarna recommends including step_up_config by default to recover those cases.
JSON
1 2 3 4 5 6 7 8 9 10
{ "payment_transaction_response": { "result": "APPROVED", "payment_transaction": { "payment_transaction_id": "krn:payment:us1:transaction:6debe89e-98c0-[...]", "payment_transaction_reference": "partner-transaction-reference-1234", "amount": 11800, "currency": "USD", "payment_pricing": {...}, "payment_funding": {

Handle STEP_UP_REQUIRED

When authorizePayment returns STEP_UP_REQUIRED, Klarna creates a new Payment Request that drives the customer through an additional Klarna Purchase Journey to gather the missing risk signals. The integration loops once more through initiating the new Payment Request with the Mobile SDK, receiving the new klarna_network_session_token, and authorizing again — ending with a second authorizePayment call that returns APPROVED or DECLINED.

Launch the step-up Klarna Purchase Journey

Extract payment_request.payment_request_id from the STEP_UP_REQUIRED response and pass it to the Mobile SDK by calling KlarnaPayment.initiate(paymentRequestId:). The SDK launches the step-up Klarna Purchase Journey — no additional data is needed. The customer completes the additional verification, and the new Payment Request transitions to COMPLETED.

Receive the new Klarna Network Session Token

A second payment.request.state-change.completed webhook is delivered, carrying a fresh klarna_network_session_token for the new Payment Request. Handle it with the same webhook handler used earlier.

Retry authorizePayment with the new token

Call authorizePaymentAPI again, using the new klarna_network_session_token in the Klarna-Network-Session-Token header. Send the same currency, request_payment_transaction.amount, acquiring_config, and supplementary_purchase_data used in the original authorize call. Klarna returns APPROVED or DECLINEDSTEP_UP_REQUIRED is not returned a second time once the customer has gone through the step-up Klarna Purchase Journey.
Treat the step-up loop as a single recoverable detour, not a full restart. Reuse the Payment Transaction reference, supplementary data, and routing from the first authorize call — only the Klarna Network Session Token changes between the two requests.

Optional functionality available via the Mobile SDK

Klarna payment request fetching

To get the information associated with a payment request, you can use the KlarnaPayment.fetch() method. The following code shows a sample implementation:
SWIFT
1 2 3 4 5 6 7 8 9 10
// Fetch the payment request klarna.payment.fetch(paymentRequestId: <PAYMENT_REQUEST_ID>) { (result: Result<KlarnaPaymentRequest, KlarnaSDKError>) in switch result { case .success(let paymentRequest): // Payment request fetch was successful. paymentRequest contains the // information about the payment request. print("Payment request fetch succeeded.") case .failure(let error): // Payment request fetch failed. More information about the failure // is available in the error object.
The following table lists the parameters of KlarnaPayment.fetch() method.
NameTypePresenceDescription
paymentRequestIdStringrequiredThe ID of the payment request to fetch.
callbackKlarnaPaymentRequestCallbackrequiredThe callback to get notified of the result of payment request fetch.

Klarna payment request cancelation

To cancel a payment request, you can use the KlarnaPayment.cancel() method. The following code shows a sample implementation:
SWIFT
1 2 3 4 5 6 7 8 9 10
// Cancel the payment request klarna.payment.cancel(paymentRequestId: <PAYMENT_REQUEST_ID>) { (result: Result<KlarnaPaymentRequest, KlarnaSDKError>) in switch result { case .success(let paymentRequest): // Payment request cancelation was successful. paymentRequest contains the // information about the canceled payment request. print("Payment request cancelation succeeded.") case .failure(let error): // Payment request cancelation failed. More information about the failure // is available in the error object.
The following table lists the parameters of KlarnaPayment.cancel() method.
NameTypePresenceDescription
paymentRequestIdStringrequiredThe ID of the payment request to cancel.
callbackKlarnaPaymentRequestCallbackrequiredThe callback to get notified of the result of payment request cancelation.
Related articles
Authorize a customer-initiated payment (server-side)
Authorize a customer-initiated payment (Web SDK)
Set up your webhooks
Present Klarna in your checkout
Klarna Buttons Styling