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)
This guide covers iOS (Swift), Android (Kotlin), and React Native integrations.
Prerequisites
Before you integrate, check that you meet the following prerequisites:
1.
A working Payment Presentation implementation in your Mobile SDK — the Klarna Mobile SDK is imported and initialized, and your payment sheet presents Klarna.
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.
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.
The customer selects Klarna and taps your payment button, and your Mobile SDK requests payment processing from your backend.
2.
Your backend calls authorizePayment 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.
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.
When STEP_UP_REQUIRED is returned:
4.1.
Your backend passes payment_request_id to your Mobile SDK.
4.2.
Your Mobile SDK calls KlarnaPayment.initiate(paymentRequestId:) to launch the Klarna Purchase Journey.
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.
Klarna delivers the klarna_network_session_token to your backend via the payment.request.state-change.completed webhook.
4.5.
Your backend finalizes the authorization by calling authorizePayment at the same path with the Klarna-Network-Session-Token header and acquiring_config.payment_account_id.
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 authorizePayment.
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.
Klarna evaluates the payment authorization and returns a payment_transaction_response object:
Result
Description
Next steps
APPROVED
The payment was authorized immediately and a payment_transaction created.
Store payment_transaction_id and notify your Mobile SDK to show the confirmation screen.
DECLINED
Authorization was declined. No transaction created.
Notify your Mobile SDK to show the decline screen or prompt for an alternative payment method.
STEP_UP_REQUIRED
Customer 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.
Launch the Klarna Purchase Journey when STEP_UP_REQUIRED
When authorizePayment returns STEP_UP_REQUIRED, Klarna creates a Payment Request for customer verification.
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.
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:):
Name
Type
Presence
Description
activity
Activity
required for Android only
The current Activity instance of your host app.
paymentRequestId
String
required
The identifier of the Payment Request returned in the STEP_UP_REQUIRED authorization response.
callback
KlarnaPaymentRequestCallback
required
Callback notified of the initiation outcome.
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.
Method: Read the Payment Request (optional fallback)
If the webhook is delayed, your backend can call readPaymentRequest 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 authorizePayment again from your backend. Include the session token in the Klarna-Network-Session-Token header along with the original payment parameters:
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)")
}
}