Skip to main content
Klarna is a buy now, pay later (BNPL) payment method that offers flexible payment options and supports recurring payments through merchant-initiated transactions (MIT).

Setup

A Klarna account can be requested from the Klarna Business Portal.

Credentials

To connect a Klarna account, obtain the following credentials from the Klarna Business Portal.
  • Username: An API username which can be generated by navigating to PreferencesSettingsManage Klarna API Credentials
  • Password: An API password which can be generated by navigating to PreferencesSettingsManage Klarna API Credentials
  • Region: The region of the Klarna account. Enter EU for Europe, NA for North America, or OC for Oceania
  • Client ID (optional): Required only for Express Checkout. Obtain from your Klarna Business Portal and enter it here so Gr4vy can return it via the Create Session API to initialize the Klarna Payments Buttons SDK.

Capabilities

Supported countries

Supported currencies

Integration

For Klarna, the default integration uses a redirect to the Klarna hosted payments page. A direct integration using the Klarna JavaScript SDK or mobile SDKs is also supported.

Redirect integration

Start by creating a new transaction with the following required fields.
var transaction = await client.Transactions.CreateAsync(
  transactionCreate: new TransactionCreate()
  {
    Amount = 1299,
    Currency = "USD",
    Country = "US",
    PaymentMethod = new PaymentMethodRequest()
    {
      Method = "klarna",
      RedirectUrl = "https://example.com/callback",
      Country = "US",
      Currency = "USD",
    },
  }
);
After the transaction is created, the API response includes payment_method.approval_url and the buyer_approval_pending status.
{
  "type": "transaction",
  "id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
  "payment_method": {
    "type": "payment-method",
    "approval_url": "https://cdn.sandbox.spider.gr4vy.app/connectors/klarna/apm.html?token=..."
  },
  "method": "klarna"
}
Redirect the buyer to the approval_url to complete the Klarna approval flow. Once approved, the transaction moves to authorization_succeeded.

Direct integration

Gr4vy supports direct integration with Klarna using the Klarna Payments SDK or mobile SDKs, allowing you to embed the payment UI directly in your app while using Gr4vy to manage the transaction lifecycle. Two modes are supported: Standard Checkout (session-based) and Express Checkout (button-based, no session required).

Standard Checkout

To initiate Standard Checkout, create a transaction with integration_client set to web, ios, or android. For mobile, use your app deep link for redirect_url (for example, yourapp://). After the transaction is created, the API response includes a session_token which can be used to get the session data for that transaction.
POST /transactions/:transaction_id/session?token=:session_token
{
  "session_data": {
    "client_token": "...",
    "purchase_country": "US",
    "purchase_currency": "USD",
    "amount": 1000
  },
  "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
  "integration_client": "web"
}
Use the client_token from the session data to initialize the Klarna SDK. Refer to the Klarna SDK documentation for web integration. Web
<script src="https://js.klarna.com/web-sdk/v1/klarna.js"></script>
iOS (Swift) — See the iOS SDK guide.
let paymentView = KlarnaPaymentView(category: "pay_over_time", eventHandler: self)
paymentView.initialize(clientToken: sessionData.client_token, returnUrl: URL(string: "yourapp://")!)
Android (Kotlin) — See the Android SDK guide.
val paymentView = KlarnaPaymentView(context, "pay_over_time")
paymentView.initialize(clientToken, "yourapp://")
Complete the transaction After the customer authorizes the payment through the Klarna SDK, Klarna returns an authorization_token. To finalize the transaction, send this token to Gr4vy as a query parameter on the default_completion_url returned in the session response.
Terminal
curl -X GET \
    "<default_completion_url>&authorization_token=<AUTHORIZATION_TOKEN>"
Once the request completes successfully, the transaction moves to authorization_succeeded. It can then be captured, voided, or refunded through Gr4vy.

Express Checkout

Klarna Express Checkout embeds the Klarna payment button directly in your page using the Klarna Payments Buttons SDK. The buyer authorizes the payment inside the SDK widget — no redirect to a hosted page is required. After authorization, your backend creates the Gr4vy transaction in a single call using the authorization_token returned by the SDK. Get the client ID The Klarna Payments Buttons SDK requires a client_id to initialize. You can obtain this in one of two ways:
  • Via the Gr4vy API — Call the Create Payment Service Session endpoint for your Klarna connection. Gr4vy returns a clientId from the connector credentials without making any Klarna API call.
    Terminal
    POST /payment-services/{payment_service_id}/sessions
    
    Response
    {
      "client_id": "klarna_live_client_..."
    }
    
  • Hardcoded — Copy the client_id from your Klarna Business Portal and embed it directly in your frontend. This is suitable when the client ID does not change per session.
Embed the Express Checkout button Load the Klarna SDK and render the Express Checkout button. The klarnaAsyncCallback function must be defined before the SDK script tag so it is available when the SDK initializes.
<div id="klarna-express-button"></div>

<script>
  window.klarnaAsyncCallback = function () {
    var orderPayload = {
      purchase_country: "US",
      purchase_currency: "USD",
      locale: "en-US",
      order_amount: 2999,
      order_tax_amount: 0,
      order_lines: [
        {
          type: "physical",
          reference: "item-001",
          name: "Example Product",
          quantity: 1,
          unit_price: 2999,
          tax_rate: 0,
          total_amount: 2999,
          total_tax_amount: 0,
        },
      ],
    };

    var klarnaButton = window.Klarna.Payments.Buttons.init({
      client_id: "<YOUR_CLIENT_ID>",
    });

    klarnaButton.load({
      container: document.getElementById("klarna-express-button"),
      theme: "default",
      shape: "default",
      locale: "en-US",
      on_click: function (authorize) {
        authorize(
          {
            collect_shipping_address: true,
            auto_finalize: true,
          },
          orderPayload,
          function (response) {
            if (!response.approved) {
              // buyer cancelled or was declined
              return;
            }

            // Send authorization_token to your server
            fetch("/create-transaction", {
              method: "POST",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({
                authorization_token: response.authorization_token,
              }),
            });
          }
        );
      },
    });
  };
</script>

<script defer src="https://x.klarnacdn.net/kp/lib/v1/api.js"></script>
Mobile For mobile applications, use the Klarna Mobile SDK. The SDK is initialized with a client_id and renders a KlarnaExpressCheckoutButton. iOS (Swift) — See the iOS integration guide.
let options = KlarnaExpressCheckoutButtonOptions(
    sessionOptions: .ClientSideSession(clientId: "<CLIENT_ID>", sessionData: orderData),
    returnUrl: "yourapp://",
    delegate: self
)
Android (Kotlin) — See the Android integration guide.
val sessionOptions = KlarnaExpressCheckoutSessionOptions.ClientSideSession(
    clientId = "<CLIENT_ID>",
    sessionData = orderData,
)
React Native — See the React Native integration guide.
<KlarnaExpressCheckoutView
    sessionOptions={{ clientId: "<CLIENT_ID>" }}
    returnUrl="yourapp://klarna-redirect"
    onAuthorized={handleAuthorization}
/>
Create the transaction Once your server receives the authorization_token, create a Gr4vy transaction and pass the token in connection_options under the klarna-klarna key. Gr4vy forwards the token to Klarna to place the order directly — the transaction moves to authorization_succeeded without any redirect.
var res = await sdk.Transactions.CreateAsync(transactionCreate: new TransactionCreate() {
    Amount = 2999,
    Currency = "USD",
    Country = "US",
    PaymentMethod = new PaymentMethodRequest() {
        Method = "klarna",
    },
    CartItems = new List<CartItem> {
        new CartItem() {
            Name = "Example Product",
            Quantity = 1,
            UnitAmount = 2999,
            Sku = "item-001",
            Type = "physical",
        },
    },
    ConnectionOptions = new Dictionary<string, object> {
        ["klarna-klarna"] = new Dictionary<string, object> {
            ["authorization_token"] = "<AUTHORIZATION_TOKEN>",
        },
    },
});
The authorization_token returned by the Klarna SDK expires within approximately 60 minutes. Create the Gr4vy transaction immediately after receiving it.

Subscriptions (MIT)

Klarna supports storing the buyer’s payment method during the first (customer-present) payment and charging future renewals as merchant-initiated transactions (MIT) using the saved payment method, typically with no redirect.
Webhooks must be configured for the Klarna payment service. After the buyer approves the payment, Klarna sends an authorization_token via webhook which Gr4vy uses to create the reusable customer token. Without this webhook, store: true will not work.

First payment

Set store to true to save the Klarna payment method for the buyer.
using Gr4vy;
using Gr4vy.Models.Components;

// Load your private key from disk, env, or your secret manager
var privateKey = "...";

var sdk = new Gr4vySDK(
    id: "example",
    server: SDKConfig.Server.Sandbox,
    bearerAuthSource: Auth.WithToken(privateKey),
    merchantAccountId: "default"
);

var res = await sdk.Transactions.CreateAsync(transactionCreate: new TransactionCreate() {
    Amount = 5000,
    Currency = "USD",
    Country = "US",
    PaymentMethod = new PaymentMethodRequest() {
        Method = "klarna",
        RedirectUrl = "https://yourapp.com/callback",
        Country = "US",
        Currency = "USD"
    },
    Store = true,
    PaymentSource = "recurring",
    MerchantInitiated = false,
    IsSubsequentPayment = false,
});
// handle response

Subsequent payment

After the payment method is saved, use the payment method ID to charge future renewals.
  • Set payment_method.method to id and pass the saved payment method ID.
  • Set payment_source to recurring.
  • Set merchant_initiated and is_subsequent_payment to true.
using Gr4vy;
using Gr4vy.Models.Components;

// Load your private key from disk, env, or your secret manager
var privateKey = "...";

var sdk = new Gr4vySDK(
    id: "example",
    server: SDKConfig.Server.Sandbox,
    bearerAuthSource: Auth.WithToken(privateKey),
    merchantAccountId: "default"
);

var res = await sdk.Transactions.CreateAsync(transactionCreate: new TransactionCreate() {
    Amount = 5000,
    Currency = "USD",
    Country = "US",
    PaymentMethod = new PaymentMethodRequest() {
        Method = "id",
        Id = "c2495b14-ca95-4199-87c3-27cbfefcbe9e"
    },
    PaymentSource = "recurring",
    MerchantInitiated = true,
    IsSubsequentPayment = true,
});
// handle response