Authorize a customer-initiated payment (Mobile SDK)

Authorize a customer-initiated payment when the Klarna Mobile SDK is integrated as a dependency within an Acquiring Partner Mobile SDK. The Acquiring Partner backend authorizes the payment directly with Klarna, and the Mobile SDK launches the Klarna Purchase Journey when step-up is required.
150 min read

Overview

Use this guide when you are an Acquiring Partner building and distributing your own Mobile SDK (e.g., a unified payment sheet, drop-in UI, or custom component library) for your Partners and you embed the Klarna Mobile SDK as an internal dependency to process Klarna payments.
Your backend authorizes the payment directly with Klarna. The Partner Account identifier goes in the request path, and acquiring_config.payment_account_id identifies the Payment Account. When Klarna requires customer interaction (STEP_UP_REQUIRED), your Mobile SDK receives the payment_request_id and launches the Klarna Purchase Journey natively inside the Partner's app.
Where this fits in the integration flow:
  • Payment Presentation — Your Mobile SDK presents Klarna and collects the customer's selection (previous step)
  • Authorize the payment — Your backend calls the Payment Authorize API and your Mobile SDK handles step-up (this step)
  • Manage payment transactions — Capture, refund, or cancel authorized payments (next step)
The underlying API calls mirror the server-side flow and the hosted checkout flow: your backend calls authorizePaymentAPI with step_up_config. What differs is client-side orchestration of the step-up.
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 working Payment Presentation implementation in your Mobile SDK — the Klarna Mobile SDK is imported and initialized, and your payment sheet presents Klarna.
  2. 2.
    An API key generated in the Klarna Partner Portal for backend API operations.
  3. 3.
    A Partner Account identifier (partner_account_id) for the authorize request path, and a Payment Account identifier (payment_account_id) for acquiring_config, so transactions can be routed and settled correctly.
  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.

Integration overview

Here's an overview of the steps to authorize a payment with Klarna when your Mobile SDK embeds the Klarna Mobile SDK as a dependency:
  1. 1.
    The customer selects Klarna and taps your payment button, and your Mobile SDK requests payment processing from your backend.
  2. 2.
    Your backend calls authorizePaymentAPI at /accounts/{partner_account_id}/payment/authorize with step_up_config (customer_interaction_config.method = "HANDOVER", return_url, and app_return_url) and acquiring_config.payment_account_id.
  3. 3.
    Klarna evaluates the authorization:
    • 3.1.
      APPROVED: The payment is immediately authorized. Your backend confirms success to your Mobile SDK, and the Partner app displays the confirmation screen.
    • 3.2.
      DECLINED: The authorization is declined. Your Mobile SDK prompts the customer for an alternative payment method.
    • 3.3.
      STEP_UP_REQUIRED: Klarna creates a Payment Request and returns payment_request.payment_request_id.
  4. 4.
    When STEP_UP_REQUIRED is returned:
    1. 4.1.
      Your backend passes payment_request_id to your Mobile SDK.
    2. 4.2.
      Your Mobile SDK calls KlarnaPayment.initiate(paymentRequestId:) to launch the Klarna Purchase Journey.
    3. 4.3.
      The customer completes authentication and approval in Klarna, and Klarna returns the customer to the Partner app via app_return_url.
    4. 4.4.
      Klarna delivers the klarna_network_session_token to your backend via the payment.request.state-change.completed webhook.
    5. 4.5.
      Your backend finalizes the authorization by calling authorizePaymentAPI at the same path with the Klarna-Network-Session-Token header and acquiring_config.payment_account_id.
    6. 4.6.
      Klarna returns APPROVED, and your backend confirms success to your Mobile SDK, which notifies the Partner app to display the confirmation screen.
sequenceDiagram autonumber participant C as Customer participant MA as Partner app participant APSDK as Acquiring Partner SDK (with Klarna SDK) participant APBE as Acquiring Partner backend participant K as Klarna Note over C,K: Payment Presentation integration (previous step) C->>APSDK: Select Klarna and tap pay APSDK->>APBE: Process payment APBE->>K: authorizePayment with path partner_account_id, step_up_config, and payment_account_id K->>APBE: Authorization result alt result: APPROVED APBE->>APSDK: Authorization confirmed APSDK->>MA: Payment complete callback MA->>C: Display confirmation screen else result: DECLINED APBE->>APSDK: Authorization declined APSDK->>MA: Display error / prompt alternative payment method else result: STEP_UP_REQUIRED APBE->>APSDK: Return payment_request_id APSDK->>K: initiate(paymentRequestId) alt In-App Browser K->>C: Launch Klarna Purchase Journey C->>K: Complete authentication & approval else App Handover to Klarna App K->>C: Launch Klarna App for Purchase Journey C->>K: Complete authentication & approval K->>MA: Return to Partner app via app_return_url end K-->>APBE: Webhook payment.request.state-change.completed Note over K,APBE: Delivers klarna_network_session_token APBE->>K: Finalize authorizePayment with Klarna-Network-Session-Token K->>APBE: APPROVED, payment_transaction APBE->>APSDK: Authorization confirmed APSDK->>MA: Payment complete callback MA->>C: Display confirmation screen end

Integration details

Authorize the payment

When the customer taps the payment button, your Mobile SDK sends the payment request to your backend. Your backend initiates the Payment Authorization with Klarna by calling authorizePaymentAPI.
In an Acquiring Partner integration, you must:
  • Pass the Partner Account identifier in the request path as partner_account_id.
  • Identify the Payment Account with acquiring_config.payment_account_id.
  • Include step_up_config with customer_interaction_config.method = "HANDOVER", providing both return_url (web fallback) and app_return_url (the Partner app's custom URL scheme). See App return URL in Payment Presentation for how this value relates to the Klarna Mobile SDK configuration on each platform.
  • Supply supplementary_purchase_data (line items, customer details, and shipping address).
  • Pass Klarna-Network-Session-Token in the request header if a session token was previously obtained during payment presentation or pre-qualification.

Sample request

SHELL
1 2 3 4 5 6 7 8 9 10
curl https://api-global.test.klarna.com/v2/accounts/{partner_account_id}/payment/authorize \ -H 'Authorization: Basic <API key>' \ -H 'Content-Type: application/json' \ -d '{ "currency": "USD", "acquiring_config": { "payment_account_id": "krn:partner:global:payment-account:test:3440b9b7-7ca2-44a3-8f62-776caacdaa0b" }, "request_payment_transaction": { "amount": 11800,

Handle the authorization result

Klarna evaluates the payment authorization and returns a payment_transaction_response object:
ResultDescriptionNext steps
APPROVEDThe payment was authorized immediately and a payment_transaction created.Store payment_transaction_id and notify your Mobile SDK to show the confirmation screen.
DECLINEDAuthorization was declined. No transaction created.Notify your Mobile SDK to show the decline screen or prompt for an alternative payment method.
STEP_UP_REQUIREDCustomer interaction is required by Klarna risk evaluation. Only returned when step_up_config was included.Extract payment_request.payment_request_id and pass it to your Mobile SDK to launch the Klarna Purchase Journey.
Step-up config recommendation
Without step_up_config in the authorize request, Klarna returns DECLINED instead of STEP_UP_REQUIRED. Klarna recommends including step_up_config on all authorize requests to maximize authorization success.
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-4318-86d1-443b74312891", "payment_transaction_reference": "acquirer-tx-ref-1234", "amount": 11800, "currency": "USD", "payment_funding": { "type": "GUARANTEED",

Launch the Klarna Purchase Journey when STEP_UP_REQUIRED

When authorizePayment returns STEP_UP_REQUIRED, Klarna creates a Payment Request for customer verification.
  1. 1.
    Pass payment_request_id to your Mobile SDK: Extract payment_request.payment_request_id from the authorize response and return it to your Mobile SDK.
  2. 2.
    Initiate the Klarna Purchase Journey: Your Mobile SDK passes payment_request_id to KlarnaPayment.initiate(paymentRequestId:):
SWIFT
1 2 3 4 5 6 7 8 9 10
// Called when backend returns STEP_UP_REQUIRED with paymentRequestId public func handleStepUp(paymentRequestId: String) { klarna.payment.initiate(paymentRequestId: paymentRequestId) { result in switch result { case .success(let paymentRequest): // Step-up initiated. Klarna handles the customer journey. print("Step-up journey initiated: \(paymentRequest.id)") case .failure(let error): // Step-up initiation failed. print("Step-up initiation failed: \(error.localizedDescription)")
The following table lists the parameters of KlarnaPayment.initiate(paymentRequestId:):
NameTypePresenceDescription
activityActivityrequired for Android onlyThe current Activity instance of your host app.
paymentRequestIdStringrequiredThe identifier of the Payment Request returned in the STEP_UP_REQUIRED authorization response.
callbackKlarnaPaymentRequestCallbackrequiredCallback notified of the initiation outcome.
  1. 1.
    Customer completes verification: Klarna Mobile SDK launches the Klarna Purchase Journey. The customer completes authentication and approval, and Klarna returns the customer to the Partner app using app_return_url.

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.
Integration requirement
Never use client-side Mobile SDK completion events alone to trigger Payment Authorization. Always rely on Klarna webhooks received on your backend to retrieve the klarna_network_session_token and finalize the payment. The token is valid for 1 hour.

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

Klarna delivers this webhook event to your backend when the customer approves the payment.
Sample webhook 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": "2026-10-08T12:00:00Z", "correlation_id": "2d1557e8-17c3-466c-924a-bbc3e91c2a02", "subject_account_id": "krn:partner:global:account:test:ACQUIRER_ACC", "recipient_account_id": "krn:partner:global:account:test:ACQUIRER_ACC" },

Method: Read the Payment Request (optional fallback)

If the webhook is delayed, your backend can call readPaymentRequestAPI using the payment_request_id. Once the Payment Request reaches COMPLETED, the token is available in state_context.klarna_network_session_token.

Finalize the payment authorization

After receiving the klarna_network_session_token via webhook, finalize the transaction by calling authorizePaymentAPI again from your backend. Include the session token in the Klarna-Network-Session-Token header along with the original payment parameters:

Sample finalization request

SHELL
1 2 3 4 5 6 7 8 9 10
curl https://api-global.test.klarna.com/v2/accounts/{partner_account_id}/payment/authorize \ -H 'Authorization: Basic <API key>' \ -H 'Content-Type: application/json' \ -H 'Klarna-Network-Session-Token: krn:network:us1:test:session-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \ -d '{ "currency": "USD", "acquiring_config": { "payment_account_id": "krn:partner:global:payment-account:test:3440b9b7-7ca2-44a3-8f62-776caacdaa0b" }, "request_payment_transaction": {

Finalization response

Klarna returns an APPROVED response containing the final payment_transaction details:
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-4318-86d1-443b74312891", "payment_transaction_reference": "acquirer-tx-ref-1234", "amount": 11800, "currency": "USD", "payment_funding": { "type": "GUARANTEED",
Once finalized, your backend confirms the outcome to your Mobile SDK, which invokes the Partner app's completion callback to display the confirmation screen to the customer.

Optional functionality available via the Mobile SDK

Klarna payment request fetching

To inspect the status of a Payment Request from the client:
SWIFT
1 2 3 4 5 6 7 8
klarna.payment.fetch(paymentRequestId: paymentRequestId) { result in switch result { case .success(let paymentRequest): print("Payment request state: \(paymentRequest.state)") case .failure(let error): print("Fetch failed: \(error.localizedDescription)") } }

Klarna payment request cancellation

To cancel an active Payment Request:
SWIFT
1 2 3 4 5 6 7 8
klarna.payment.cancel(paymentRequestId: paymentRequestId) { result in switch result { case .success(let paymentRequest): print("Payment request cancelled: \(paymentRequest.id)") case .failure(let error): print("Cancellation failed: \(error.localizedDescription)") } }
Related articles
Integrate Payment Presentation
Payment transaction state definitions
SupportPartner support•Service Status
Cookies|Terms & Conditions|Copyright Klarna AB 2026
Jump to section...