Klarna Direct

Payment Tokenization Overview

Understand how Partners save a customer's payment method with Klarna and reuse it to authorize future Payment Transactions for on-demand purchases, subscriptions, and partner-initiated authorizations.
Payment Tokenization is the process of securely saving a customer's Klarna payment method for future use. It produces a customer_token that Partners store and use to authorize subsequent Payment Transactions, either when the customer is actively initiating the payment (on-demand purchases, one-click checkout) or when the Partner is initiating the authorization on behalf of the customer (subscription renewals, scheduled authorizations).
To enable repeat purchases, subscriptions, or on-demand authorizations, Partners must first create a Customer Token through customer-present consent in the Klarna Purchase Journey. Once Klarna has issued the Customer Token, the Partner can subsequently use it to authorize future Payment Transactions on behalf of the customer.

Tokenization scenarios

ScenarioWhen to use
Tokenization onlySave a payment method without an immediate Payment Authorization (for example, free trials, wallet linking, or account setup). The Payment Request completion delivers the customer_token directly. No second API call is needed.
Tokenization combined with authorizationSave a payment method and authorize the first Payment Transaction in the same flow (for example, the first month of a subscription, or a one-off purchase that also enables on-demand re-authorizations). Klarna delivers both the customer_token and a Klarna Network Session Token, and Partners call authorizePaymentAPI to create the initial Payment Transaction.

End-to-end flow

For Partners, tokenization is built on the same Payment Request resource as a Payment Authorization. The flow always starts by creating a Payment Request with createPaymentRequestAPI and asking Klarna to issue a token via request_customer_token. The customer completes the Klarna Purchase Journey to grant consent, and Klarna issues the customer_token to the Partner, either alone (tokenization only) or alongside a first Payment Transaction (tokenization combined with authorization). Detailed steps for each scenario are covered in Tokenization flows in detail.

Token scopes

The scopes set on request_customer_token define how the resulting token can be used. Partners must pick the scope that matches the use case. Klarna issues exactly one scope per token.
ScopeAuthorization patternTypical use cases
payment:customer_presentThe customer is actively initiating the payment when re-authorizing. Subsequent authorizations run through authorizePayment and may still trigger step-up when Klarna's risk signals require it.One-click checkout, ride-hailing, food delivery, in-app purchases.
payment:customer_not_presentThe Partner initiates the authorization without customer interaction. The authorization happens directly without redirecting the customer anywhere.Subscription renewals, membership billing, scheduled or metered authorizations.

Tokenization flows in detail

The simplest tokenization flow saves a payment method without an immediate Payment Transaction. Partners create a Payment Request with request_customer_token and without request_payment_transaction (or amount). When the customer approves, Klarna issues the token via the Payment Request completion. There is no second authorize call.

Sequence diagram

sequenceDiagram autonumber participant C as Customer participant P as Partner participant K as Klarna C->>P: Initiate tokenization P->>K: createPaymentRequest (request_customer_token, scopes, customer_interaction_config) K-->>P: payment_request_id, payment_request_url (state SUBMITTED) P->>C: Redirect to payment_request_url (or launch via Web SDK) C->>K: Authenticate and approve tokenization K-->>P: Webhook payment.request.state-change.completed Note over K,P: state COMPLETED, customer_token in state_context.klarna_customer P->>C: Confirm tokenization success

Flow steps

  • The customer initiates tokenization on the Partner's frontend (subscription signup, "save for later", wallet linking).
  • The Partner's backend calls createPaymentRequestAPI with:
    • request_customer_token and the desired scopes (typically payment:customer_not_present for subscriptions or payment:customer_present for on-demand).
    • currency.
    • customer_interaction_config (HANDOVER + return_url). The Klarna Purchase Journey is mandatory because the customer must consent to the token.
  • Klarna returns a Payment Request in SUBMITTED state with a payment_request_url.
  • Launch the Klarna Purchase Journey, either by redirecting the customer to payment_request_url (server-side integration) or via the Klarna Web SDK.
  • The customer authenticates and approves tokenization.
  • Klarna sends a payment.request.state-change.completed webhook. The payload, and state_context.klarna_customer.customer_token on the Payment Request, carry the issued customer_token.
  • Store the token securely and confirm success to the customer.

Integration paths

Both integration paths use the same API model: a Payment Request followed (when needed) by an authorize call. What differs is how the Klarna Purchase Journey is launched.
PathHow the Klarna Purchase Journey is launchedWhen to use
Server-side integrationThe Partner's backend creates the Payment Request, returns the payment_request_url to the frontend, and the customer's browser is redirected. After the journey, Klarna sends the customer back to the configured return_url.Server-rendered checkouts, native mobile apps, and any flow that does not embed the Klarna Web SDK. See the canonical pattern in Authorize a customer-initiated payment (server-side).
Klarna Web SDKThe Klarna Web SDK is embedded in the checkout. The SDK calls the Partner's backend (which still creates the Payment Request) and orchestrates the Klarna Purchase Journey in a popup or modal, with no full-page redirect.Single-page web checkouts where the Klarna Purchase Journey should happen in-context.
In both paths, the API contract is identical: createPaymentRequest with request_customer_token, then, for combined tokenization, authorizePayment with the Klarna Network Session Token after the customer completes the Klarna Purchase Journey.

Authorize a payment with the customer token

Once a customer_token is issued, Partners reuse it on subsequent authorizations by passing it in the Klarna-Customer-Token request header. The pattern depends on whether the customer is initiating the payment or the Partner is initiating it on the customer's behalf.

Customer-initiated authorization (on-demand, one-click)

When the customer is actively initiating the payment (for example, completing a one-click purchase or buying a ride), call authorizePaymentAPI directly with the Klarna-Customer-Token header, and include step_up_config so Klarna can fall back to a step-up Klarna Purchase Journey when its risk signals require it. No upfront Payment Request is needed: the stored token already represents the customer's consent, and step_up_config is what makes recovery from borderline cases possible.
  • The Partner's backend calls authorizePaymentAPI with:
    • Klarna-Customer-Token header containing the stored customer_token.
    • currency and request_payment_transaction.amount.
    • supplementary_purchase_data matching the original tokenization context.
    • step_up_config with customer_interaction_config.method = HANDOVER and a return_url (and optionally app_return_url for mobile). This opts the Partner in to the STEP_UP_REQUIRED outcome.
  • Klarna returns one of three results:
    • APPROVED: the authorization succeeded with no further customer interaction. Persist the payment_transaction_id.
    • STEP_UP_REQUIRED: Klarna's risk signals require additional customer interaction. The response includes a new Payment Request with customer_interaction details. Launch the Klarna Purchase Journey using that Payment Request, and when the customer completes it (a new Klarna Network Session Token is delivered via webhook) call authorizePaymentAPI again with that Klarna Network Session Token to finalize.
    • DECLINED: the authorization was rejected. Surface a clear error to the customer.
Use scope payment:customer_present.

Sequence diagram

sequenceDiagram autonumber participant C as Customer participant FE as Partner frontend participant BE as Partner backend participant K as Klarna C->>FE: Triggers a one-click purchase / on-demand authorization FE->>BE: Initiate authorization (amount, token reference) BE->>K: authorizePayment with Klarna-Customer-Token header (+ step_up_config) alt APPROVED K-->>BE: APPROVED + payment_transaction BE->>FE: Show success else STEP_UP_REQUIRED K-->>BE: STEP_UP_REQUIRED + new Payment Request BE->>FE: New paymentRequestUrl FE->>K: Launch step-up Purchase Journey C->>K: Customer completes step-up K-->>BE: Webhook with new klarna_network_session_token BE->>K: authorizePayment with Klarna-Network-Session-Token header K-->>BE: APPROVED / DECLINED BE->>FE: Show result else DECLINED K-->>BE: DECLINED BE->>FE: Show alternative payment page end
When step_up_config is omitted, Klarna will return DECLINED instead of STEP_UP_REQUIRED whenever additional customer interaction would have been needed, and recoverable cases will fail. Always include step_up_config for customer-initiated token authorizations.

Partner-initiated authorization (subscriptions, scheduled billing)

When the Partner is initiating the authorization on behalf of the customer (for example, a monthly subscription renewal), call authorizePaymentAPI directly with the Klarna-Customer-Token header and without step_up_config. There is no customer available to complete a step-up Klarna Purchase Journey, so step-up is not a valid recovery path.
  • The Partner's backend calls authorizePaymentAPI with:
    • Klarna-Customer-Token header containing the stored customer_token.
    • currency and request_payment_transaction.amount.
    • supplementary_purchase_data (include the subscriptions[] or ondemand_service context that matches the original tokenization purchase data).
  • Klarna evaluates the authorization and returns APPROVED or DECLINED. STEP_UP_REQUIRED is not a possible outcome for partner-initiated authorizations, and step_up_config should not be included.
  • On APPROVED, Klarna creates the Payment Transaction. Persist the payment_transaction_id and continue with capture/refund as needed.
Use scope payment:customer_not_present.
Both token-based authorization flows (customer-initiated and partner-initiated) start with authorizePaymentAPI and bypass the upfront Payment Request. The stored Customer Token already carries the customer's consent. The difference is only whether step_up_config is included. Authorizations without a Customer Token still always start with createPaymentRequest.

Comparison

AspectCustomer-initiatedPartner-initiated
Token scopepayment:customer_presentpayment:customer_not_present
Starting callauthorizePayment with Klarna-Customer-TokenauthorizePayment with Klarna-Customer-Token
step_up_configUsed to enable recovery via Klarna Purchase Journey when risk signals require additional customer interactionDo not include
Customer interactionOnly when Klarna returns STEP_UP_REQUIRED (then a follow-up authorizePayment with the new Klarna Network Session Token)Never
Possible authorize resultsAPPROVED, DECLINED, STEP_UP_REQUIREDAPPROVED, DECLINED

Webhooks

Subscribe to Klarna webhooks to receive tokenization outcomes asynchronously. The events relevant to tokenization are the standard Payment Request state-change events. The tokenization context lives in the payload.
EventWhen it firesRequired action
payment.request.state-change.completed (tokenization only)The customer completed consent. The payload sets state = COMPLETED and exposes the customer_token at state_context.klarna_customer.customer_token.Store the token securely. No further API call is needed.
payment.request.state-change.completed (tokenization combined)The customer completed consent for the combined flow. The payload sets state = COMPLETED and includes the klarna_network_session_token.Call authorizePaymentAPI with the Klarna Network Session Token to finalize the Payment Transaction. The response carries both customer_token_response and payment_transaction_response.
payment.request.state-change.canceledThe customer canceled before approving. The payload sets state = CANCELED.Clean up local state. No token is issued.
payment.request.state-change.expiredThe Payment Request expired before completion. The payload sets state = EXPIRED.Prompt the customer to retry. No token is issued.
Subscribe to events via the Webhooks registration guide. As a fallback, the Payment Request can always be read directly to pick up the customer_token or klarna_network_session_token from state_context.

Token storage and security

Treat customer_token values as sensitive credentials. They allow authorizations on behalf of the customer until they expire or are revoked.
PracticeDescription
Store securelyPersist customer_token values in encrypted storage. Restrict access to the systems that authorize Payment Transactions.
Associate with the customerLink each token to the relevant customer record, including the issuing scope and the issuance timestamp.
Track scope and intentRecord the token's scope (payment:customer_present or payment:customer_not_present) and the business intent (subscription, wallet, on-demand) so the right token can be picked at authorization time.
Honor lifecycle eventsWhen a customer cancels their subscription or removes their saved payment method, stop using the token and delete it or mark it as inactive.
Do not expose tokensNever return raw customer_token values to frontends, mobile clients, or third parties. Reference them by an internal identifier instead.
For the conceptual model and lifecycle of the resource, see Customer Token.
Related articles
Payment Request
Build Payment Presentation with the Klarna Web SDK
Authorize a customer-initiated payment (server-side)
Set up your webhooks
Customer Token