> ## 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.

# Tokenize a card

Tokenization replaces a raw card number (PAN) with a secure token that can be stored and reused. This can help reduce your PCI scope, but your scope depends on how you collect and send card data. Gr4vy supports two types of tokenization:

* **Gr4vy vault token** — the card is stored in the Gr4vy vault and referenced by a payment method ID. Use this for checkout, recurring payments, and vault forwarding.
* **PSP token** — the card is additionally tokenized on a specific payment provider. Use this when a downstream service needs a provider-specific token rather than raw card data.

## Store a card in the vault

To store a card you create a payment method. This can be done via the API directly, or through one of the Gr4vy SDKs.

### Via the API

<Warning>
  Direct API tokenization requires a PCI-compliant environment because the raw PAN and security code pass through your servers. If you want to keep PAN off your servers, use Secure Fields for web integrations or the mobile SDK for native apps.
</Warning>

Use the `POST /payment-methods` endpoint to store a card. The card is immediately vaulted and a payment method ID is returned for future use.

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

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

  var res = await sdk.PaymentMethods.CreateAsync(
      requestBody: Body.CreateCardPaymentMethodCreate(
          new CardPaymentMethodCreate() {
              Number = "4111111111111111",
              ExpirationDate = "11/25",
              SecurityCode = "123",
              BuyerId = "fe26475d-ec3e-4884-9553-f7356683f7f9",
          }
      )
  );

  // handle response
  ```

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

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

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

      s := gr4vygo.New(
          gr4vygo.WithMerchantAccountID("default"),
          gr4vygo.WithSecurity(os.Getenv("GR4VY_BEARER_AUTH")),
      )

      res, err := s.PaymentMethods.Create(ctx, operations.CreateBodyCardPaymentMethodCreate(
          components.CardPaymentMethodCreate{
              Number:         "4111111111111111",
              ExpirationDate: "11/25",
              SecurityCode:   gr4vygo.String("123"),
              BuyerID:        gr4vygo.String("fe26475d-ec3e-4884-9553-f7356683f7f9"),
          },
      ))
      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.CardPaymentMethodCreate;
  import com.gr4vy.sdk.models.operations.Body;
  import com.gr4vy.sdk.models.operations.CreatePaymentMethodResponse;
  import java.lang.Exception;

  public class Application {

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

          Gr4vy sdk = Gr4vy.builder()
                  .merchantAccountId("default")
                  .bearerAuth(System.getenv().getOrDefault("BEARER_AUTH", ""))
              .build();

          CreatePaymentMethodResponse res = sdk.paymentMethods().create()
                  .requestBody(Body.of(CardPaymentMethodCreate.builder()
                      .number("4111111111111111")
                      .expirationDate("11/25")
                      .securityCode("123")
                      .buyerId("fe26475d-ec3e-4884-9553-f7356683f7f9")
                      .build()))
                  .call();

          if (res.paymentMethod().isPresent()) {
              System.out.println(res.paymentMethod().get());
          }
      }
  }
  ```

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

  require 'vendor/autoload.php';

  use Gr4vy;
  use Gr4vy\Auth;

  $privateKey = file_get_contents('./private_key.pem');

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

  $response = $sdk->paymentMethods->create(
      requestBody: new Gr4vy\CardPaymentMethodCreate(
          number: '4111111111111111',
          expirationDate: '11/25',
          securityCode: '123',
          buyerId: 'fe26475d-ec3e-4884-9553-f7356683f7f9',
      )
  );

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

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

  with Gr4vy(
      id="example",
      server="sandbox",
      merchant_account_id="default",
      bearer_auth=auth.with_token(open("./private_key.pem").read())
  ) as g_client:
      res = g_client.payment_methods.create(request_body={
          "method": "card",
          "number": "4111111111111111",
          "expiration_date": "11/25",
          "security_code": "123",
          "buyer_id": "fe26475d-ec3e-4884-9553-f7356683f7f9",
      })
      print(res)
  ```

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

  const gr4vy = new Gr4vy({
      id: "example",
      server: "sandbox",
      merchantAccountId: "default",
      bearerAuth: withToken({
        privateKey: fs.readFileSync("private_key.pem", "utf8"),
      }),
  });

  const result = await gr4vy.paymentMethods.create({
      method: "card",
      number: "4111111111111111",
      expirationDate: "11/25",
      securityCode: "123",
      buyerId: "fe26475d-ec3e-4884-9553-f7356683f7f9",
  });

  console.log(result);
  ```
</CodeGroup>

The response includes the `id` of the new payment method, which you can use for transactions or [vault forwarding](./forward).

<Card title="API reference" icon="code" href="/reference/payment-methods/new-payment-method">
  POST /payment-methods
</Card>

### Via the mobile SDK

For mobile apps, use the native SDK `tokenize` method to securely collect and vault card details without the raw data passing through your servers.

<Card title="Mobile SDK vaulting guide" icon="mobile" href="/guides/payments/native/vault">
  Vaulting cards with the native SDKs
</Card>

### Via Secure Fields (web)

For web checkout, Gr4vy Embed and Secure Fields capture and vault the card in a PCI-compliant iframe, returning a payment method ID to your server.

## Next steps

Once a card is stored, you can [provision a PSP token](./psp-tokens) for it, or [forward it to a third-party endpoint](./forward) using Vault Forwarding.
