> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gr4vy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Klarna

> Set up Klarna and charge recurring subscriptions using merchant-initiated transactions (MIT) with a saved payment method.

## What is Klarna?

Klarna is a buy now, pay later (BNPL) payment method that offers flexible payment options and supports recurring payments. This allows for accepting recurring payments and giving buyers more flexible ways to pay.

## Setup

A Klarna account can be requested from the
[Klarna Business Portal](https://portal.klarna.com/products/signup/basic-info).

## 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 **Preferences** → **Settings** → **Manage Klarna API Credentials**.
* **Password:** An API password which can be generated by navigating to **Preferences** → **Settings** → **Manage Klarna API Credentials**.
* **Region:** The region of the Klarna account. This can be Europe, North America, or Oceania.

## Supported countries and currencies

Klarna supports transactions from buyers in `AT`, `AU`, 17 more.

Klarna supports processing payments in `AUD`, `CAD`, 8 more.

## Subscriptions (MIT)

Klarna can be used to:

1. Store the buyer's Klarna payment method during the first (customer-present) payment, and
2. Charge future subscription renewals as merchant-initiated transactions (MIT) using the saved payment method - typically with no redirect.

This is the recommended approach for recurring subscriptions.

### When to use this flow

Use this flow when:

* A customer approves Klarna once during sign-up or checkout, and
* they need to be charged again later for subscription renewals without requiring them to re-authenticate each time.

### Prerequisites

* A Klarna payment service needs to be configured for the merchant account.
* Webhooks need to be configured for the Klarna payment service (required for tokenization).

### How it works

#### Step 1. First payment (customer present)

On the initial subscription payment:

* Use Klarna as the payment method
* Provide a `redirect_url` so the customer can complete Klarna approval
* Set `store: true` so the Klarna payment method is saved for the buyer

##### Example request

<CodeGroup>
  ```csharp C# theme={"system"}
  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
  ```

  ```go Go theme={"system"}
  package main

  import(
      "context"
      "log"
      "github.com/gr4vy/gr4vy-go"
      "github.com/gr4vy/gr4vy-go/models/components"
  )

  func main() {
      // Load your private key from disk, env, or your secret manager
      privateKey := "..."

      s := gr4vy.New(
          gr4vy.WithID("example"),
          gr4vy.WithServer(gr4vy.ServerSandbox),
          gr4vy.WithBearerAuth(gr4vy.WithToken(privateKey)),
          gr4vy.WithMerchantAccountID("default"),
      )

      amount := int64(5000)
      store := true
      merchantInitiated := false
      isSubsequentPayment := false
      res, err := s.Transactions.Create(context.Background(), &components.TransactionCreate{
          Amount: &amount,
          Currency: "USD",
          Country: "US",
          PaymentMethod: &components.PaymentMethodRequest{
              Method: "klarna",
              RedirectUrl: "https://yourapp.com/callback",
              Country: "US",
              Currency: "USD",
          },
          Store: &store,
          PaymentSource: "recurring",
          MerchantInitiated: &merchantInitiated,
          IsSubsequentPayment: &isSubsequentPayment,
      })
      if err != nil {
          log.Fatal(err)
      }

      if res.StatusCode == 201 {
          // handle response
      }
  }
  ```

  ```java Java theme={"system"}
  import com.gr4vy.Gr4vy;
  import com.gr4vy.models.components.*;
  import com.gr4vy.models.operations.*;

  public class Main {
      public static void main(String[] args) {
          // Load your private key from disk, env, or your secret manager
          String privateKey = "...";

          Gr4vy sdk = new Gr4vy.Builder()
              .id("example")
              .server(Server.SANDBOX)
              .bearerAuth(Auth.withToken(privateKey))
              .merchantAccountId("default")
              .build();

          TransactionCreate transactionCreate = new TransactionCreate.Builder()
              .amount(5000)
              .currency("USD")
              .country("US")
              .paymentMethod(new PaymentMethodRequest.Builder()
                  .method("klarna")
                  .redirectUrl("https://yourapp.com/callback")
                  .country("US")
                  .currency("USD")
                  .build())
              .store(true)
              .paymentSource("recurring")
              .merchantInitiated(false)
              .isSubsequentPayment(false)
              .build();

          try {
              CreateTransactionResponse res = sdk.transactions().create(transactionCreate);
              
              if (res.statusCode == 201) {
                  // handle response
              }
          } catch (Exception e) {
              // handle exception
          }
      }
  }
  ```

  ```javascript Javascript theme={"system"}
  import Gr4vy, { withToken } from "gr4vy";
  import { PaymentMethodRequest, TransactionCreate } from "gr4vy/models/components";

  // Load your private key from disk, env, or your secret manager
  const privateKey = process.env.GR4VY_PRIVATE_KEY ?? "...";

  const sdk = new Gr4vy({
      id: "example",
      server: "sandbox",
      bearerAuth: withToken({ privateKey }),
      merchantAccountId: "default",
  });

  const res = await sdk.transactions.create(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,
  }));

  if (res.statusCode === 201) {
      // handle response
  }
  ```

  ```php PHP theme={"system"}
  <?php

  require_once 'vendor/autoload.php';

  use Gr4vy;
  use Gr4vy\Auth;
  use Gr4vy\Models\Components;

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

  $sdk = Gr4vy\SDK::builder()
      ->setId('example')
      ->setServer('sandbox')
      ->setSecuritySource(Auth::withToken($privateKey))
      ->setMerchantAccountId('default')
      ->build();

  $res = $sdk->transactions->create(new Components\TransactionCreate(
      amount: 5000,
      currency: 'USD',
      country: 'US',
      paymentMethod: new Components\PaymentMethodRequest(
          method: 'klarna',
          redirectUrl: 'https://yourapp.com/callback',
          country: 'US',
          currency: 'USD',
      ),
      store: true,
      paymentSource: 'recurring',
      merchantInitiated: false,
      isSubsequentPayment: false,
  ));

  if ($res->statusCode === 201) {
      // handle response
  }
  ```

  ```python Python theme={"system"}
  import gr4vy
  from gr4vy import auth
  from gr4vy.models import components

  # Load your private key from disk, env, or your secret manager
  private_key = "..."

  s = gr4vy.Gr4vy(
      id="example",
      server=gr4vy.SERVER_SANDBOX,
      bearer_auth=auth.with_token(private_key),
      merchant_account_id="default",
  )

  res = s.transactions.create(
      components.TransactionCreate(
          amount=5000,
          currency="USD",
          country="US",
          payment_method=components.PaymentMethodRequest(
              method="klarna",
              redirect_url="https://yourapp.com/callback",
              country="US",
              currency="USD",
          ),
          store=True,
          payment_source="recurring",
          merchant_initiated=False,
          is_subsequent_payment=False,
      ),
  )

  if res.status_code == 201:
      # handle response
      pass
  ```
</CodeGroup>

#### Step 2. Subscription renewals (merchant initiated)

For each renewal:

* Use the saved payment method ID by setting `method` to `"id"`
* Mark the transaction as a subsequent recurring payment and merchant-initiated

##### Example request

<CodeGroup>
  ```csharp C# theme={"system"}
  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
  ```

  ```go Go theme={"system"}
  package main

  import(
      "context"
      "log"
      "github.com/gr4vy/gr4vy-go"
      "github.com/gr4vy/gr4vy-go/models/components"
  )

  func main() {
      // Load your private key from disk, env, or your secret manager
      privateKey := "..."

      s := gr4vy.New(
          gr4vy.WithID("example"),
          gr4vy.WithServer(gr4vy.ServerSandbox),
          gr4vy.WithBearerAuth(gr4vy.WithToken(privateKey)),
          gr4vy.WithMerchantAccountID("default"),
      )

      amount := int64(5000)
      merchantInitiated := true
      isSubsequentPayment := true
      res, err := s.Transactions.Create(context.Background(), &components.TransactionCreate{
          Amount: &amount,
          Currency: "USD",
          Country: "US",
          PaymentMethod: &components.PaymentMethodRequest{
              Method: "id",
              Id: "c2495b14-ca95-4199-87c3-27cbfefcbe9e",
          },
          PaymentSource: "recurring",
          MerchantInitiated: &merchantInitiated,
          IsSubsequentPayment: &isSubsequentPayment,
      })
      if err != nil {
          log.Fatal(err)
      }

      if res.StatusCode == 201 {
          // handle response
      }
  }
  ```

  ```java Java theme={"system"}
  import com.gr4vy.Gr4vy;
  import com.gr4vy.models.components.*;
  import com.gr4vy.models.operations.*;

  public class Main {
      public static void main(String[] args) {
          // Load your private key from disk, env, or your secret manager
          String privateKey = "...";

          Gr4vy sdk = new Gr4vy.Builder()
              .id("example")
              .server(Server.SANDBOX)
              .bearerAuth(Auth.withToken(privateKey))
              .merchantAccountId("default")
              .build();

          TransactionCreate transactionCreate = new TransactionCreate.Builder()
              .amount(5000)
              .currency("USD")
              .country("US")
              .paymentMethod(new PaymentMethodRequest.Builder()
                  .method("id")
                  .id("c2495b14-ca95-4199-87c3-27cbfefcbe9e")
                  .build())
              .paymentSource("recurring")
              .merchantInitiated(true)
              .isSubsequentPayment(true)
              .build();

          try {
              CreateTransactionResponse res = sdk.transactions().create(transactionCreate);
              
              if (res.statusCode == 201) {
                  // handle response
              }
          } catch (Exception e) {
              // handle exception
          }
      }
  }
  ```

  ```javascript Javascript theme={"system"}
  import Gr4vy, { withToken } from "gr4vy";
  import { PaymentMethodRequest, TransactionCreate } from "gr4vy/models/components";

  // Load your private key from disk, env, or your secret manager
  const privateKey = process.env.GR4VY_PRIVATE_KEY ?? "...";

  const sdk = new Gr4vy({
      id: "example",
      server: "sandbox",
      bearerAuth: withToken({ privateKey }),
      merchantAccountId: "default",
  });

  const res = await sdk.transactions.create(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,
  }));

  if (res.statusCode === 201) {
      // handle response
  }
  ```

  ```php PHP theme={"system"}
  <?php

  require_once 'vendor/autoload.php';

  use Gr4vy;
  use Gr4vy\Auth;
  use Gr4vy\Models\Components;

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

  $sdk = Gr4vy\SDK::builder()
      ->setId('example')
      ->setServer('sandbox')
      ->setSecuritySource(Auth::withToken($privateKey))
      ->setMerchantAccountId('default')
      ->build();

  $res = $sdk->transactions->create(new Components\TransactionCreate(
      amount: 5000,
      currency: 'USD',
      country: 'US',
      paymentMethod: new Components\PaymentMethodRequest(
          method: 'id',
          id: 'c2495b14-ca95-4199-87c3-27cbfefcbe9e',
      ),
      paymentSource: 'recurring',
      merchantInitiated: true,
      isSubsequentPayment: true,
  ));

  if ($res->statusCode === 201) {
      // handle response
  }
  ```

  ```python Python theme={"system"}
  import gr4vy
  from gr4vy import auth
  from gr4vy.models import components

  # Load your private key from disk, env, or your secret manager
  private_key = "..."

  s = gr4vy.Gr4vy(
      id="example",
      server=gr4vy.SERVER_SANDBOX,
      bearer_auth=auth.with_token(private_key),
      merchant_account_id="default",
  )

  res = s.transactions.create(
      components.TransactionCreate(
          amount=5000,
          currency="USD",
          country="US",
          payment_method=components.PaymentMethodRequest(
              method="id",
              id="c2495b14-ca95-4199-87c3-27cbfefcbe9e",
          ),
          payment_source="recurring",
          merchant_initiated=True,
          is_subsequent_payment=True,
      ),
  )

  if res.status_code == 201:
      # handle response
      pass
  ```
</CodeGroup>
