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

# Generating tokens for authentication

Before adding Embed to the web checkout, create a client
token that can be used to authenticate the transaction.

## Install a server-side SDK

Use the package manager in the preferred programming language to install the
server-side SDK. Token generation can only be done server side and doing this client side is not recommended
as it exposes the API key to customers.

<CodeGroup>
  ```sh C# theme={"system"}
  dotnet add package Gr4vy
  ```

  ```sh Go theme={"system"}
  go get github.com/gr4vy/gr4vy-go
  ```

  ```sh Java theme={"system"}
  # Please check for the latest version
  implementation 'com.gr4vy:sdk:1.0.0'
  ```

  ```sh PHP theme={"system"}
  composer require "gr4vy/gr4vy-php"
  ```

  ```sh Python theme={"system"}
  pip install gr4vy
  ```

  ```sh TypeScript theme={"system"}
  npm install @gr4vy/sdk
  # or: yarn add @gr4vy/sdk
  ```
</CodeGroup>

<Note>
  Please always check and install the [latest release](/guides/get-started#sdks-and-plugins) of the preferred SDK.
</Note>

## Initialize the SDK client

Next, initialize the SDK with the ID of the instance and the private key.

<CodeGroup>
  ```csharp C# theme={"system"}
  using Gr4vy;
  using Gr4vy.Models.Components;
  using System.Collections.Generic;

  // Loaded the key from a file, env variable, 
  // or anywhere else
  var privateKey = "..."; 

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

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

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

  func main() {
  	ctx := context.Background()

  	privateKey := "...." // Private key loaded from disk or env var
  	withToken := gr4vy.WithToken(privateKey, []JWTScope{ReadAll, WriteAll}, 60)

  	s := gr4vy.New(
  		gr4vy.WithID("example"),
  		gr4vy.WithServer(gr4vy.ServerSandbox),
  		gr4vy.WithSecuritySource(withToken),
  		gr4vy.WithMerchantAccountID("default"),
  	)
  }
  ```

  ```java Java theme={"system"}
  package hello.world;

  import com.gr4vy.sdk.BearerSecuritySource;
  import com.gr4vy.sdk.Gr4vy;
  import com.gr4vy.sdk.Gr4vy.AvailableServers;
  import com.gr4vy.sdk.models.components.AccountUpdaterJobCreate;
  import com.gr4vy.sdk.models.errors.*;
  import com.gr4vy.sdk.models.operations.ListTransactionsRequest;
  import java.lang.Exception;
  import java.util.List;

  public class Application {

      public static void main(String[] args) throws Exception {

          String privateKey = "-----BEGIN PRIVATE KEY-----\n...."; // a valid private key

          Gr4vy sdk = Gr4vy.builder()
                  .id("example")
                  .server(AvailableServers.SANDBOX)
                  .merchantAccountId("default")
                  .securitySource(new BearerSecuritySource.Builder(privateKey).build())
              .build();
      }
  }
  ```

  ```php PHP theme={"system"}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Gr4vy;
  use Gr4vy\Auth;

  // Loaded the key from a file, env variable, 
  // or anywhere else
  $privateKey = "..."; 

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

  ```python Python theme={"system"}
  from gr4vy import Gr4vy, auth
  import os

  client = Gr4vy(
      id="example",
      server="production",
      merchant_account_id="default",
      bearer_auth=auth.with_token(open("./private_key.pem").read())
  )
  ```

  ```ts TypeScript theme={"system"}
  import fs from "fs";
  import { Gr4vy, withToken } from "@gr4vy/sdk";

  const gr4vy = new Gr4vy({
      server: "sandbox",
      id: "example",
      bearerAuth: withToken({
        privateKey: fs.readFileSync("private_key.pem", "utf8"),
      }),
  });
  ```
</CodeGroup>

## Generate a token

The next step is to create a new token for frontend authentication. The SDK comes with
a helper function for exactly that purpose. It requires an amount and currency
for the transaction to be created and additionally accepts either the ID of a buyer
or an external identifier for a buyer to link the transaction to.

For Embed, it is recommended to attach a checkout session to every transaction. The
`getEmbedTokenWithCheckoutSession` helper creates a checkout session using your SDK client
and returns an Embed token with the resulting `checkout_session_id` already pinned, in a
single call.

<CodeGroup>
  ```csharp C# theme={"system"}
  using System.Collections.Generic;
  using Gr4vy;

  // Loaded the key from a file, env variable,
  // or anywhere else
  var privateKey = "...";

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

  var token = await Auth.GetEmbedTokenWithCheckoutSession(
      client: sdk,
      privateKey: privateKey,
      embedParams: new Dictionary<string, object>
      {
          ["amount"] = 1299,
          ["currency"] = "USD",
          ["buyer_external_identifier"] = "user-1234",
      }
  );
  ```

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

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

  func main() {
  	privateKey := "...." // Private key loaded from disk or env var

  	client := gr4vy.New(
  		gr4vy.WithID("example"),
  		gr4vy.WithServer(gr4vy.ServerSandbox),
  		gr4vy.WithSecuritySource(gr4vy.WithToken(privateKey, nil, 3600)),
  		gr4vy.WithMerchantAccountID("default"),
  	)

  	embedParams := map[string]interface{}{
  		"amount":                    1299,
  		"currency":                  "USD",
  		"buyer_external_identifier": "user-1234",
  	}

  	token, err := gr4vy.GetEmbedTokenWithCheckoutSession(context.Background(), client, privateKey, embedParams, nil, nil)
  	if err != nil {
  		log.Fatal(err)
  	}

  	log.Println(token)
  }
  ```

  ```java Java theme={"system"}
  package hello.world;

  import com.gr4vy.sdk.Auth;
  import com.gr4vy.sdk.BearerSecuritySource;
  import com.gr4vy.sdk.Gr4vy;
  import com.gr4vy.sdk.Gr4vy.AvailableServers;

  import java.util.HashMap;
  import java.util.Map;

  public class Application {

      public static void main(String[] args) throws Exception {
          String privateKey = "-----BEGIN PRIVATE KEY-----\n...."; // a valid private key

          Gr4vy client = Gr4vy.builder()
              .id("example")
              .server(AvailableServers.SANDBOX)
              .securitySource(new BearerSecuritySource.Builder(privateKey).build())
              .merchantAccountId("default")
              .build();

          Map<String, Object> embedParams = new HashMap<>();
          embedParams.put("amount", 1299);
          embedParams.put("currency", "USD");
          embedParams.put("buyer_external_identifier", "user-1234");

          String token = Auth.getEmbedTokenWithCheckoutSession(client, privateKey, embedParams);

          System.out.println(token);
      }
  }
  ```

  ```php PHP theme={"system"}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Gr4vy;
  use Gr4vy\Auth;

  // Loaded the key from a file, env variable, 
  // or anywhere else
  $privateKey = "..."; 

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

  $token = Auth::getEmbedTokenWithCheckoutSession(
      client: $sdk,
      privateKey: $privateKey,
      embedParams: [
          "amount" => 1299,
          "currency" => "USD",
          "buyer_external_identifier" => "user-1234",
      ],
  );
  ```

  ```python Python theme={"system"}
  from gr4vy import Gr4vy, auth

  private_key = open("./private_key.pem").read()

  g_client = Gr4vy(
      id="example",
      server="production",
      merchant_account_id="default",
      bearer_auth=auth.with_token(private_key)
  )

  token = auth.get_embed_token_with_checkout_session(
      g_client,
      private_key,
      embed_params={
          "amount": 1299,
          "currency": "USD",
          "buyer_external_identifier": "user-1234",
      },
  )
  ```

  ```ts TypeScript theme={"system"}
  import { Gr4vy, getEmbedTokenWithCheckoutSession, withToken } from "@gr4vy/sdk";
  import fs from "fs";

  async function run() {
      const privateKey = fs.readFileSync("private_key.pem", "utf8")

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

      const token = await getEmbedTokenWithCheckoutSession({
        client: gr4vy,
        privateKey,
        embedParams: {
          amount: 1299,
          currency: 'USD',
          buyerExternalIdentifier: 'user-1234',
        }
      });

      console.log(token);
  }

  run();
  ```
</CodeGroup>

This token can now be served to the frontend where it is used by the SDK.

If generating the client token without using a
server-side SDK is preferred, then please read the guide on [manually generating a JWT](/guides/api/authentication#manual-jwt).

## Checkout sessions

Passing a [checkout session](/reference/checkout-sessions/new-checkout-session) ID to the Embed token function is recommended.
This ID can be used to help identify multiple transaction attempts. This is useful to identify if one or more failed/declined
transactions eventually result in a successful transaction. Checkout sessions can also store `cart_items`, `metadata`, airline data, and more,
removing the need to pass these values on the transaction request.

<CodeGroup>
  ```csharp C# theme={"system"}
  using Gr4vy;
  using Gr4vy.Models.Components;
  using NodaTime;
  using System;
  using System.Collections.Generic;


  var res = await sdk.CheckoutSessions.CreateAsync(checkoutSessionCreate: new CheckoutSessionCreate() {
      CartItems = new List<CartItem>() {
          new CartItem() {
              Name = "GoPro HD",
              Quantity = 2,
              UnitAmount = 1299,
              DiscountAmount = 0,
              TaxAmount = 0,
              ExternalIdentifier = "goprohd",
              Sku = "GPHD1078",
              ProductUrl = "https://example.com/catalog/go-pro-hd",
              ImageUrl = "https://example.com/images/go-pro-hd.jpg",
              Categories = new List<string>() {
                  "camera",
                  "travel",
                  "gear",
              },
              ProductType = "physical",
              SellerCountry = "GB",
          },
          new CartItem() {
              Name = "GoPro HD",
              Quantity = 2,
              UnitAmount = 1299,
              DiscountAmount = 0,
              TaxAmount = 0,
              ExternalIdentifier = "goprohd",
              Sku = "GPHD1078",
              ProductUrl = "https://example.com/catalog/go-pro-hd",
              ImageUrl = "https://example.com/images/go-pro-hd.jpg",
              Categories = new List<string>() {
                  "camera",
                  "travel",
                  "gear",
              },
              ProductType = "physical",
              SellerCountry = "GB",
          },
          new CartItem() {
              Name = "GoPro HD",
              Quantity = 2,
              UnitAmount = 1299,
              DiscountAmount = 0,
              TaxAmount = 0,
              ExternalIdentifier = "goprohd",
              Sku = "GPHD1078",
              ProductUrl = "https://example.com/catalog/go-pro-hd",
              ImageUrl = "https://example.com/images/go-pro-hd.jpg",
              Categories = new List<string>() {
                  "camera",
                  "travel",
                  "gear",
              },
              ProductType = "physical",
              SellerCountry = "US",
          },
      },
      Metadata = new Dictionary<string, string>() {
          { "cohort", "cohort-a" },
          { "order_id", "order-12345" },
      },
      Buyer = new GuestBuyerInput() {
          DisplayName = "John Doe",
          ExternalIdentifier = "buyer-12345",
          BillingDetails = new BillingDetailsInput() {
              FirstName = "John",
              LastName = "Doe",
              EmailAddress = "john@example.com",
              PhoneNumber = "+1234567890",
              Address = new Address() {
                  City = "San Jose",
                  Country = "US",
                  PostalCode = "94560",
                  State = "California",
                  StateCode = "US-CA",
                  HouseNumberOrName = "10",
                  Line1 = "Stafford Apartments",
                  Line2 = "29th Street",
                  Organization = "Gr4vy",
              },
              TaxId = new TaxId() {
                  Value = "12345678931",
                  Kind = "ar.cuit",
              },
          },
          ShippingDetails = new ShippingDetailsCreate() {
              FirstName = "John",
              LastName = "Doe",
              EmailAddress = "john@example.com",
              PhoneNumber = "+1234567890",
              Address = new Address() {
                  City = "San Jose",
                  Country = "US",
                  PostalCode = "94560",
                  State = "California",
                  StateCode = "US-CA",
                  HouseNumberOrName = "10",
                  Line1 = "Stafford Apartments",
                  Line2 = "29th Street",
                  Organization = "Gr4vy",
              },
          },
      },
  });

  // handle response
  ```

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

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

  func main() {
      ctx := context.Background()

      // Init SDK

      res, err := s.CheckoutSessions.Create(ctx, &components.CheckoutSessionCreate{
          CartItems: []components.CartItem{
              components.CartItem{
                  Name: "GoPro HD",
                  Quantity: 2,
                  UnitAmount: 1299,
                  DiscountAmount: gr4vygo.Int64(0),
                  TaxAmount: gr4vygo.Int64(0),
                  ExternalIdentifier: gr4vygo.String("goprohd"),
                  Sku: gr4vygo.String("GPHD1078"),
                  ProductURL: gr4vygo.String("https://example.com/catalog/go-pro-hd"),
                  ImageURL: gr4vygo.String("https://example.com/images/go-pro-hd.jpg"),
                  Categories: []string{
                      "camera",
                      "travel",
                      "gear",
                  },
                  ProductType: components.ProductTypePhysical.ToPointer(),
                  SellerCountry: gr4vygo.String("US"),
              },
              components.CartItem{
                  Name: "GoPro HD",
                  Quantity: 2,
                  UnitAmount: 1299,
                  DiscountAmount: gr4vygo.Int64(0),
                  TaxAmount: gr4vygo.Int64(0),
                  ExternalIdentifier: gr4vygo.String("goprohd"),
                  Sku: gr4vygo.String("GPHD1078"),
                  ProductURL: gr4vygo.String("https://example.com/catalog/go-pro-hd"),
                  ImageURL: gr4vygo.String("https://example.com/images/go-pro-hd.jpg"),
                  Categories: []string{
                      "camera",
                      "travel",
                      "gear",
                  },
                  ProductType: components.ProductTypePhysical.ToPointer(),
                  SellerCountry: gr4vygo.String("US"),
              },
          },
          Metadata: map[string]string{
              "cohort": "cohort-a",
              "order_id": "order-12345",
          },
          Buyer: nil,
      })
      if err != nil {
          log.Fatal(err)
      }
      if res != nil {
          // handle response
      }
  }
  ```

  ```java Java theme={"system"}
  package hello.world;

  import com.gr4vy.sdk.Gr4vy;
  import com.gr4vy.sdk.models.components.*;
  import com.gr4vy.sdk.models.errors.*;
  import com.gr4vy.sdk.models.operations.CreateCheckoutSessionResponse;
  import java.lang.Exception;
  import java.time.LocalDate;
  import java.time.OffsetDateTime;
  import java.util.List;
  import java.util.Map;
  import org.openapitools.jackson.nullable.JsonNullable;

  public class Application {

      public static void main(String[] args) throws Exception {

          // Init SDK

          CreateCheckoutSessionResponse res = sdk.checkoutSessions().create()
                  .checkoutSessionCreate(CheckoutSessionCreate.builder()
                      .cartItems(List.of(
                          CartItem.builder()
                              .name("GoPro HD")
                              .quantity(2L)
                              .unitAmount(1299L)
                              .discountAmount(0L)
                              .taxAmount(0L)
                              .externalIdentifier("goprohd")
                              .sku("GPHD1078")
                              .productUrl("https://example.com/catalog/go-pro-hd")
                              .imageUrl("https://example.com/images/go-pro-hd.jpg")
                              .categories(List.of(
                                  "camera",
                                  "travel",
                                  "gear"))
                              .productType(ProductType.PHYSICAL)
                              .sellerCountry("US")
                              .build(),
                          CartItem.builder()
                              .name("GoPro HD")
                              .quantity(2L)
                              .unitAmount(1299L)
                              .discountAmount(0L)
                              .taxAmount(0L)
                              .externalIdentifier("goprohd")
                              .sku("GPHD1078")
                              .productUrl("https://example.com/catalog/go-pro-hd")
                              .imageUrl("https://example.com/images/go-pro-hd.jpg")
                              .categories(List.of(
                                  "camera",
                                  "travel",
                                  "gear"))
                              .productType(ProductType.PHYSICAL)
                              .sellerCountry("US")
                              .build()))
                      .metadata(Map.ofEntries(
                          Map.entry("cohort", "cohort-a"),
                          Map.entry("order_id", "order-12345")))
                      .buyer(JsonNullable.of(null))
                      .build())
                  .call();

          if (res.checkoutSession().isPresent()) {
              // handle response
          }
      }
  }
  ```

  ```php PHP theme={"system"}
  declare(strict_types=1);

  require 'vendor/autoload.php';

  use Brick\DateTime\LocalDate;
  use Gr4vy;
  use Gr4vy\Utils;

  // Init SDK

  $checkoutSessionCreate = new Gr4vy\CheckoutSessionCreate(
      cartItems: [
          new Gr4vy\CartItem(
              name: 'GoPro HD',
              quantity: 2,
              unitAmount: 1299,
              discountAmount: 0,
              taxAmount: 0,
              externalIdentifier: 'goprohd',
              sku: 'GPHD1078',
              productUrl: 'https://example.com/catalog/go-pro-hd',
              imageUrl: 'https://example.com/images/go-pro-hd.jpg',
              categories: [
                  'camera',
                  'travel',
                  'gear',
              ],
              productType: 'physical',
              sellerCountry: 'US',
          ),
          new Gr4vy\CartItem(
              name: 'GoPro HD',
              quantity: 2,
              unitAmount: 1299,
              discountAmount: 0,
              taxAmount: 0,
              externalIdentifier: 'goprohd',
              sku: 'GPHD1078',
              productUrl: 'https://example.com/catalog/go-pro-hd',
              imageUrl: 'https://example.com/images/go-pro-hd.jpg',
              categories: [
                  'camera',
                  'travel',
                  'gear',
              ],
              productType: 'physical',
              sellerCountry: 'US',
          ),
      ],
      metadata: [
          'cohort' => 'cohort-a',
          'order_id' => 'order-12345',
      ],
      buyer: new Gr4vy\GuestBuyerInput(
          displayName: 'John Doe',
          externalIdentifier: 'buyer-12345',
          billingDetails: new Gr4vy\BillingDetailsInput(
              firstName: 'John',
              lastName: 'Doe',
              emailAddress: 'john@example.com',
              phoneNumber: '+1234567890',
              address: new Gr4vy\Address(
                  city: 'San Jose',
                  country: 'US',
                  postalCode: '94560',
                  state: 'California',
                  stateCode: 'US-CA',
                  houseNumberOrName: '10',
                  line1: 'Stafford Apartments',
                  line2: '29th Street',
                  organization: 'Gr4vy',
              ),
              taxId: new Gr4vy\TaxId(
                  value: '12345678931',
                  kind: 'my.frp',
              ),
          ),
          shippingDetails: new Gr4vy\ShippingDetailsCreate(
              firstName: 'John',
              lastName: 'Doe',
              emailAddress: 'john@example.com',
              phoneNumber: '+1234567890',
              address: null,
          ),
      ),
  );

  $response = $sdk->checkoutSessions->create(
      checkoutSessionCreate: $checkoutSessionCreate
  );

  if ($response->checkoutSession !== null) {
      // handle response
  }
  ```

  ```python Python theme={"system"}
  from datetime import date
  from gr4vy import Gr4vy, models
  from gr4vy.utils import parse_datetime
  import os

  # Init SDK

  res = g_client.checkout_sessions.create(checkout_session_create=models.CheckoutSessionCreate(
      cart_items=[
          models.CartItem(
              name="GoPro HD",
              quantity=2,
              unit_amount=1299,
              discount_amount=0,
              tax_amount=0,
              external_identifier="goprohd",
              sku="GPHD1078",
              product_url="https://example.com/catalog/go-pro-hd",
              image_url="https://example.com/images/go-pro-hd.jpg",
              categories=[
                  "camera",
                  "travel",
                  "gear",
              ],
              product_type="physical",
              seller_country="GB",
          ),
          models.CartItem(
              name="GoPro HD",
              quantity=2,
              unit_amount=1299,
              discount_amount=0,
              tax_amount=0,
              external_identifier="goprohd",
              sku="GPHD1078",
              product_url="https://example.com/catalog/go-pro-hd",
              image_url="https://example.com/images/go-pro-hd.jpg",
              categories=[
                  "camera",
                  "travel",
                  "gear",
              ],
              product_type="physical",
              seller_country="GB",
          ),
          models.CartItem(
              name="GoPro HD",
              quantity=2,
              unit_amount=1299,
              discount_amount=0,
              tax_amount=0,
              external_identifier="goprohd",
              sku="GPHD1078",
              product_url="https://example.com/catalog/go-pro-hd",
              image_url="https://example.com/images/go-pro-hd.jpg",
              categories=[
                  "camera",
                  "travel",
                  "gear",
              ],
              product_type="physical",
              seller_country="GB",
          ),
      ],
      metadata={
          "cohort": "cohort-a",
          "order_id": "order-12345",
      },
      buyer=models.GuestBuyerInput(
          display_name="John Doe",
          external_identifier="buyer-12345",
          billing_details=models.BillingDetailsInput(
              first_name="John",
              last_name="Doe",
              email_address="john@example.com",
              phone_number="+1234567890",
              address=models.Address(
                  city="San Jose",
                  country="US",
                  postal_code="94560",
                  state="California",
                  state_code="US-CA",
                  house_number_or_name="10",
                  line1="Stafford Apartments",
                  line2="29th Street",
                  organization="Gr4vy",
              ),
              tax_id=models.TaxID(
                  value="12345678931",
                  kind="ar.cuit",
              ),
          ),
          shipping_details=models.ShippingDetailsCreate(
              first_name="John",
              last_name="Doe",
              email_address="john@example.com",
              phone_number="+1234567890",
              address=models.Address(
                  city="San Jose",
                  country="US",
                  postal_code="94560",
                  state="California",
                  state_code="US-CA",
                  house_number_or_name="10",
                  line1="Stafford Apartments",
                  line2="29th Street",
                  organization="Gr4vy",
              ),
          ),
      ),
  ))

  # Handle response
  print(res)
  ```

  ```ts Typescript theme={"system"}
  const result = await gr4vy.checkoutSessions.create();
  ```
</CodeGroup>

<Warning>
  **Checkout session expiry**

  Checkout sessions expire after 1 hour by default. Updating a checkout session does not extend the time.
</Warning>

## Summary

In this step:

* Created a signed JWT token using a server-side SDK.
* Served the JWT token to the front-end app, where it is used by
  Embed.
