klarna_ network_ session_ token, then authorizePaymentinitiate callback on the Klarna payment button, while the Partner's backend remains responsible for creating the Payment Request and authorizing the payment.payment. request. state-change. completed webhook event.return_ url on the Partner's domain that Klarna can redirect the customer to when the Klarna Purchase Journey ends in a REDIRECT or DEVICE_ BEST flow.step_ up_ config. A step-up is unlikely on this path. A customer-present payment with a stored Customer Token also starts with createPaymentRequestKlarna-Customer-Token header.initiate callback configured on the payment button.klarnaNetworkSessionToken and paymentOptionId. The Partner's frontend posts both to its own backend.customer_ interaction_ config, and returns the resulting payment_ request_ url to the frontend.initiate callback with { paymentRequestUrl }. The SDK launches the Klarna Purchase Journey in a popup, modal, or redirect depending on the configured initiationMode (DEVICE_ BEST is the recommended default). See Step 3: Configure how the Klarna Purchase Journey is launched.COMPLETED and Klarna sends a payment. request. state-change. completed webhook carrying the klarna_ network_ session_ token.Klarna-Network-Session-Token header to create the Payment Transaction. Include step_ up_ config when the transaction can change between the Payment Request and the authorize call and the customer stays in the checkout, so Klarna can return STEP_ UP_ REQUIRED with a new Payment Request instead of DECLINED. Omit it when nothing changes and the Partner authorizes from the completion webhook. See Payment Authorization.STEP_ UP_ REQUIRED, the customer clicks the Klarna payment button again and the initiate callback returns the new Payment Request's URL, so the SDK launches the Klarna Purchase Journey for it. After the customer completes it, a new Klarna Network Session Token arrives via webhook and the backend calls authorizePaymentinitiate callback is configured on the Klarna payment button when it is mounted. The SDK invokes it the moment the customer clicks the button and passes it one object with klarnaNetworkSessionToken and paymentOptionId. Use the callback to forward both to the backend, create the Payment Request, and resolve the callback with the resulting paymentRequestUrl. The Klarna Network Session Token doesn't need to go on createPaymentRequestasync function initiateKlarnaPayment({ klarnaNetworkSessionToken, paymentOptionId }) {
try {
// Forward both values to the backend, which creates the Payment Request
const response = await fetch('/api/payment-request', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ klarnaNetworkSessionToken, paymentOptionId })
});
if (!response.ok) throw new Error('Network or server error');paymentButton. component({ initiate, initiationMode, . .. }) parameters, see Build Payment Presentation with the Klarna Web SDK, Step 7: Configure the Klarna payment button.initiate callback, call createPaymentRequestcustomer_ interaction_ config. For Web SDK integrations, set method = HANDOVER and provide a return_ url (and optionally an app_ return_ url for native apps). The same fields apply as in the server-side flow. See Payment Request for the full resource model and Supplementary purchase data for the recommended data points.| Parameter | Required | Description |
|---|---|---|
currency | Yes | Currency in ISO 4217 format. |
amount | Conditional | Total amount of the Payment Request, including tax and discounts. Required unless request_ is provided. Omit it only when the Payment Request creates a Customer Token without an initial charge. |
customer_ | Yes | Set to HANDOVER. The SDK orchestrates how the Klarna Purchase Journey is launched (modal, popup, or redirect) based on initiationMode. |
customer_ | Yes | URL on the Partner's domain where Klarna redirects the customer when the SDK falls back to a redirect. It's used by the recommended DEVICE_ mode on mobile and by REDIRECT mode. |
customer_ | Optional | Application URL scheme that returns the customer to the Partner's native app after a mid-flow handover to a third-party app (for example, a bank app or the Klarna app). Not a substitute for return_. |
payment_ | Recommended | The Partner's own reference for the Payment Request, used for reconciliation. |
supplementary_ | Recommended | Additional purchase context (line items, customer, shipping, purchase reference). Improves underwriting and fraud detection and powers customer communication. See Supplementary purchase data. |
acquiring_ | Conditional | Routes the Payment Request to a specific Payment Account or Payment Acquiring Account. Required when the Partner's Klarna setup includes more than one account. Provide either payment_ (account-only routing) or payment_ together with payment_ (acquiring-account routing). When omitted, Klarna uses the default account configured for the Partner. |
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}",SUBMITTED state. For the full list of states a Payment Request can transition through, see Payment Request: States. The backend returns state_ context. customer_ interaction. payment_ request_ url to the frontend so the initiate callback can resolve with it and the SDK can launch the Klarna Purchase Journey. Fill line_ items, customer and shipping in the request as described in Supplementary purchase data.{
"payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-aacb-41d55fafbdb4",
"payment_request_reference": "partner-request-reference-1234",
"currency": "USD",
"amount": 11800,
"state": "SUBMITTED",
"state_context": {
"customer_interaction": {
"method": "HANDOVER",
"payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-aacb-41d55fafbdb4",initiationMode parameter set on the Klarna payment button. It controls whether the journey opens in a popup, an in-page iframe, or as a full-page redirect.initiationMode | Description |
|---|---|
DEVICE_ | Default and recommended. Selects the best launch method per device: on the page on desktop (popup, with a full-screen iframe as fallback), redirect on mobile and in native WebViews. Requires return_ in customer_. |
ON_ | Launches the Klarna Purchase Journey on the same page in a popup (or full-screen iframe as fallback). The customer never leaves the page. |
REDIRECT | Redirects the customer to the Klarna Purchase Journey. Requires return_ in customer_. |
paymentButton. component() configuration parameters and a sample integration, see Build Payment Presentation with the Klarna Web SDK, Step 7: Configure the Klarna payment button.KlarnaPayment SDK interface to track the lifecycle of the Klarna Purchase Journey on the client side. See complete, abort and error in the Klarna Web SDK reference.| Event handler | Purpose |
|---|---|
on("complete", callback) | Triggered when the customer completes the purchase. During a redirect flow, fires once the success page loads. |
on("abort", callback) | Triggered when the customer cancels the Klarna Purchase Journey. |
on("error", callback) | Triggered when initiate() (including a click on the payment button), fetch() or cancel() fails. The error is still thrown afterwards, so try/catch around your own calls keeps working. A failed button click has no caller to catch it, so handle it here. Not triggered when the customer closes the payment window, which is a cancellation rather than an error, or for presentation(). |
klarna.Payment.on("complete", (paymentRequest) => {
console.log("Payment request completed");
// By default, Klarna will redirect to the submitted return_url upon completion.
// Return false if you want to prevent the redirection to the success page.
return true;
});klarna_ network_ session_ token and finalize the payment after the customer completes the purchase.klarna_ network_ session_ token and the Payment Request transitions to COMPLETED. This token is used in Step 5 to finalize the authorization.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.COMPLETED state, indicating that the customer has approved the purchase and the authorization can be finalized. Subscribe via the Webhooks registration guide.{
"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-[...]",COMPLETED state, the token is available in state_ context. klarna_ network_ session_ token.{
"payment_request_id": "krn:payment:us1:request:552603c0-fe8b-4ab1-[...]",
"payment_request_reference": "partner-request-reference-1234",
"state": "COMPLETED",
"previous_state": "IN_PROGRESS",
"state_context": {
"klarna_network_session_token": "krn:network:us1:test:session-token:eyJhbGciOiJIU..."
},
"currency": "USD",
"amount": 11800,klarna_ network_ session_ token in the Klarna-Network-Session-Token request header. Klarna creates the Payment Transaction and returns the result.payment_ option_ id.| Parameter | Required | Description |
|---|---|---|
Klarna-Network-Session-Token (header) | Yes | The Klarna Network Session Token received in Step 4. |
currency | Yes | Same currency used in the Payment Request. |
request_ | Yes | The final amount for the purchase, including tax or shipping calculated after the Payment Request was created. When it differs from the Payment Request, Klarna asks for approval of the new amount. If Klarna can't approve it without the customer, result_ is AMOUNT_, on STEP_ when step_ is included and on DECLINED otherwise. |
request_ | Recommended | The Partner's own reference for the Payment Transaction, used for reconciliation. |
supplementary_ | Recommended | The final purchase details: the final line_ and the shipping address the customer ends up with. After Express Checkout, use the shipping returned on the completed Payment Request. Sending the final values keeps the transaction eligible for the merchant protection program. |
acquiring_ | Conditional | Routes the Payment Transaction to a specific Payment Account or Payment Acquiring Account, and optionally requests the currency Klarna uses to settle the transaction. Use the same Payment Account as on the Payment Request: a different one returns STEP_ with result_ set to ACQUIRING_. Adding a Payment Account the Payment Request didn't have, or adding settlement_ (ISO 4217), isn't a mismatch. An unsupported settlement_ returns a 400 validation error. See Request settlement currency. |
step_ | Conditional | Include it when the transaction can change between the Payment Request and this call, and keep the customer in the checkout until the result arrives. Klarna can then return STEP_ with a new Payment Request. Omit it when nothing changes and you authorize from the completion webhook. Set customer_ and provide a return_, plus an app_ for native apps. See Payment Authorization. |
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"
},payment_ transaction_ response object. The result field indicates the outcome and determines the next action:| Result | Description | Next steps |
|---|---|---|
APPROVED | The authorization succeeded and a payment_ was created. | Store the payment_ and proceed with post-purchase operations (capture, refund, etc.). Show the customer a confirmation page. |
DECLINED | The authorization was not approved. No transaction is created. Common causes include an expired Klarna Network Session Token when step_ wasn't included, a currency that differs from the one on the Payment Request, or a risk decision that another Klarna Purchase Journey can't resolve. result_ says why, for example KLARNA_. | Show the customer a decline or alternative payment page. |
STEP_ | Klarna requires additional customer interaction before approving. Only returned when step_ was included in the authorize request. result_ says why, for example AMOUNT_ or KLARNA_. The response includes a new Payment Request with state_. | Pass the new paymentRequestUrl back to the Web 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 authorizePayment |
step_ up_ config when the transaction can change on the authorize call and the customer is still in the checkout. When nothing changes, authorize from the completion webhook without it. See Payment Authorization for both patterns.{
"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": {STEP_ UP_ REQUIRED, Klarna creates a new Payment Request that drives the customer through an additional Klarna Purchase Journey to resolve the cause named in result_ reason. The integration loops once more through Step 3, Step 4, and Step 5, using the new Payment Request, and ends with a second authorizePaymentAPPROVED or DECLINED.payment_ request. state_ context. customer_ interaction. payment_ request_ url from the STEP_ UP_ REQUIRED response, and return it when the frontend asks for it. Return a JSON response that the initiate callback can use:// Backend
res.json({
paymentRequestUrl:
response.payment_request.state_context.customer_interaction.payment_request_url
});initiate callback from Step 1 has already resolved by the time authorizePaymentinitiate when the customer clicks the Klarna payment button, so show the customer the button again, with a short explanation that Klarna needs them to confirm the purchase. When they click it, the initiate callback fetches the step-up paymentRequestUrl from the backend and returns it. The Web SDK launches the step-up Klarna Purchase Journey using the same initiationMode configured on the button:// Frontend: initiate callback for the step-up, called when the customer clicks the button again
async function initiateKlarnaStepUp() {
const response = await fetch('/api/klarna-step-up'); // Returns the stored step-up URL
if (!response.ok) throw new Error('Network or server error');
const { paymentRequestUrl } = await response.json();
return { paymentRequestUrl };
}COMPLETED.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 in Step 4.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 DECLINED. STEP_ UP_ REQUIRED is not returned a second time once the customer has gone through the step-up Klarna Purchase Journey.