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

# Save Payment Methods

export const ApiEndpoint = ({method, path}) => {
  const getMethodColor = method => {
    switch (method?.toUpperCase()) {
      case "GET":
        return "#0285c7";
      case "POST":
        return "#008d71";
      case "PUT":
        return "#16a34a";
      case "PATCH":
        return "#808080";
      case "DELETE":
        return "#dc2626";
      default:
        return "#6b7280";
    }
  };
  const getEndpointUrl = (method, path) => {
    const endpoints = {
      "POST /client-session": "/api-reference/v2.4/api-reference/client-session-api/create-a-client-session",
      "PATCH /client-session": "/api-reference/v2.4/api-reference/client-session-api/update-client-session",
      "POST /payments": "/api-reference/v2.4/api-reference/payments-api/create-a-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/api-reference/v2.4/api-reference/payments-api/resume-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/api-reference/v2.4/api-reference/payments-api/adjust-authorized-amount",
      "POST /payments/<PAYMENT_ID>/cancel": "/api-reference/v2.4/api-reference/payments-api/cancel-payment",
      "POST /payments/<PAYMENT_ID>/refund": "/api-reference/v2.4/api-reference/payments-api/refund-payment",
      "GET /payments/<PAYMENT_ID>": "/api-reference/v2.4/api-reference/payments-api/get-a-payment",
      "GET /payment-instruments": "/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/api-reference/v2.4/api-reference/payment-methods-api/delete-payment-method-payment-methods-token-delete"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return endpoints[key] || "#";
  };
  const getPrettyPath = (method, path) => {
    const pathMapping = {
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/payments/{paymentId}/resume",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/payments/{paymentId}/adjust-authorization",
      "POST /payments/<PAYMENT_ID>/cancel": "/payments/{paymentId}/cancel",
      "POST /payments/<PAYMENT_ID>/refund": "/payments/{paymentId}/refund",
      "GET /payments/<PAYMENT_ID>": "/payments/{paymentId}",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/payment-instruments/{paymentMethodToken}"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return pathMapping[key] || path;
  };
  const methodColor = getMethodColor(method);
  const url = getEndpointUrl(method, path);
  const displayPath = getPrettyPath(method, path);
  return <div style={{
    display: "inline-flex",
    alignItems: "center",
    cursor: "pointer",
    margin: "2px 0",
    padding: "4px",
    paddingRight: "6px",
    background: "rgb(245, 245, 245)",
    borderRadius: "6px",
    whiteSpace: "nowrap",
    textDecoration: "none"
  }}>
      <a href={url} target="_blank" rel="noopener noreferrer" style={{
    textDecoration: "none",
    border: "none"
  }}>
        <span style={{
    display: "inline-block",
    whiteSpace: "nowrap",
    padding: "0 8px",
    fontSize: "13px",
    lineHeight: "23px",
    borderRadius: "6px",
    fontWeight: 400,
    backgroundColor: methodColor,
    color: "white",
    border: "none"
  }}>
          {method.toUpperCase()}
        </span>
        <code style={{
    padding: "0",
    marginLeft: "4px",
    fontFamily: "monospace",
    color: methodColor,
    border: "none",
    textDecorationColor: methodColor
  }}>
          {displayPath}
        </code>
      </a>
    </div>;
};

## Overview of Primer's Vault

<Note>
  Looking to migrate your existing saved payment methods to Primer? Check out our [token migration guide](/changelogs/migration-guides/token-migration)
</Note>

### Securely store payment method information

Primer's Vault is a centralized PCI-DSS Level 1 service you can use to store the details of a customer payment method in a unified way.

Sensitive payment data is stored as a secure multi-use `paymentMethodToken` that enables:

* recurring merchant-initiated payments
* a seamless one-click experience for your customers with Universal Checkout

Each `paymentMethodToken` is paired with a `customerId` which uniquely identifies identify a customer. You can use any unique identifier for this such as a UUID or an email address.

This `customerId` is required for:

* **generating a client session** to allow Universal Checkout to present your customer's vaulted payment data for one-click checkout
* **creating a payment request** using `vaultOnSuccess` or `vaultOn3DS` to save the customer's payment data
* **managing stored payment data with the Payment Methods API** to allow customers to add and delete vaulted payment method data from your site or app

<Frame caption="Primer's Vault">
  <img src="https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/save-payment-methods/vault.png" />
</Frame>

### Intelligently optimized for auth rate approval

We're fanatical about improving payments success. Primer will intelligently store data returned from your underlying processors to ensure the highest likelihood of success for recurring payments. This includes SCA authentication data as well as other data returned from card schemes and acquirers.

## Add payment methods to the vault

<Note>
  Not all payment methods can be added to Primer's centralized vault. Refer to our [payment method guides](/connections/payment-methods/overview) to know more about the capabilities of each payment method.
</Note>

Vaulting a payment method starts by capturing the payment method credentials using Drop-In Checkout or Headless Checkout.

You will then encounter two distinct behaviors:

* Vault the payment method directly after the user has completed the payment method flow
* Vault after a successful authorization

### Vault directly

To vault a supported payment method directly, additional options have to be passed to the SDK. Check the [payment method guides](connections/payment-methods/overview) to properly configure the Drop-in Checkout and Headless Checkout to vault each compatible payment method.

### Vault after authorization success or 3DS authentication

For card-based payment methods (Cards, Google Pay and Apple Pay), it is recommended to vault after a payment has been successfully authorized. This ensures the card is valid and is suitable for making payments.

Primer supports two vaulting options for card flows. These can be set in the Client Session API or the Payments API under `paymentMethod`.

Make sure to pass `customerId` to specify the customer's vault this payment method should be added to.

<Frame caption="Vaulting Token Flow">
  <img src="https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/save-payment-methods/vault-token-flow.png" />
</Frame>

#### vaultOnSuccess

When `paymentMethod.vaultOnSuccess` is set to `true` (and the payment method supports it), the payment method is added to the vault **only after the authorization succeeds**.

Use this when you want to save the card only if the payment is successful.

#### vaultOn3DS

When `paymentMethod.vaultOn3DS` is set to `true` (and the payment method supports it), the payment method is added to the vault **as soon as 3DS authentication succeeds**.

Use this when your flow can have a successful 3DS authentication followed by an authorization that may fail (for example soft decline and later retry), and you still want to save the card after the customer completed SCA.

#### vaultOnAgreement

When `paymentMethod.vaultOnAgreement` is set to `true`, the payment method is added to the vault when the customer explicitly agrees to future payments.

This option is intended for agreement or mandate based flows **without an immediate authorization**, such as ACH Direct Debit.

At the moment, `vaultOnAgreement` is primarily supported for **ACH payments via Stripe**, where the customer mandate is collected separately from any charge.

`vaultOnAgreement` is mutually exclusive with other vaulting options and cannot be combined with `vaultOnSuccess` or `vaultOn3DS`.

<Warning>
  Only one vaulting option is applied.

  If multiple vaulting options are set to `true`, the following rules apply:

  * If both `vaultOnSuccess` and `vaultOn3DS` are set, `vaultOnSuccess` takes precedence and `vaultOn3DS` is ignored.
  * `vaultOnAgreement` cannot be combined with any other vaulting option.

  We recommend using only one vaulting strategy per flow.
</Warning>

## Make payments with a vaulted payment method

### Simplify the drop-in payment flow

Vaulted payment methods appear automatically on the drop-in checkout if `customerId` has been provided in the client session and the customer has vaulted payment methods stored with Primer. This enables your customers to seamlessly pay with one of their saved payment method.

We recommend to set `paymentMethod.paymentType` to `ECOMMERCE` in the client session or payment request. This ensures the right data is sent to the processor to maximize the authorization rate.

<Frame caption="Universal Checkout Vault">
  <img src="https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/save-payment-methods/vault-1.png" />
</Frame>

### Recapture the CVV of saved cards

PCI standards prevent entities like Primer from [storing the CVV of a card](https://blog.pcisecuritystandards.org/faq-can-cvc-be-stored-for-card-on-file-or-recurring-transactions) when saving the card credentials for future payments.

This means that subsequent card-on-file customer-initiated payments are always processed without the CVV.

Although Primer sends the relevant parameters to tell each processor when a card-on-file payment occurs, some processors or issuers have a lower authorization rate when the CVV is not provided.

To increase the chances of payment success, Primer enables you to ask the customer to re-enter the CVV of the selected saved card before processing the payment.

#### Enabling CVV recapture on Drop-in Checkout

Include the `captureVaultedCardCvv` option within the `PAYMENT_CARD` payment method options in the `POST /client-session` request. When set to `true`, this flag activates the CVV recapture functionality in the Drop-In implementation, providing an out-of-the-box solution for transactions with vaulted payment cards.

**Example Request:**

```json JSON theme={"dark"}
POST /client-session
{
  "paymentMethod": {
    "options": {
      "PAYMENT_CARD": {
        "captureVaultedCardCvv": true
      }
    }
  }
}
```

### Create merchant-initiated payments

You can use the Payment Methods API and the Payments API together to create merchant-initiated payments with a saved payment method.

1. First, make a call to <ApiEndpoint method="GET" path="/payment-instruments" /> to get the list of payment methods tied to a `customerId`. Each entry in the list contains a `token` representing the payment method token to use to create a payment.

2. Then, create a payment by calling <ApiEndpoint method="POST" path="/payments" />. In addition to the required fields for creating a payment, pass the following data:

| Parameter Name                                                                                                                 | Description                                                                                                                                                                                                                                                  |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| paymentMethodToken                                                                                                             | The vaulted payment method token                                                                                                                                                                                                                             |
| paymentMethod <br /> ↳ [paymentType](/api-reference/v2.4/api-reference/payments-api/create-a-payment#body-payment-method-type) | Type of payment.<br />Used to improve conversion.<br /><ul><li>`SUBSCRIPTION` if the payment is part of a series of payments on a fixed schedule and a set amount</li><li>`UNSCHEDULED` if the payment is not following a fixed schedule or amount</li></ul> |

## Manage vaulted payment methods

### With the Payment Methods API

The [Payment Methods API](/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods) lets you interact with the vaulted payment methods for all your customers.

Use the Payments API to:

* retrieve the saved payment methods associated to a customer with <ApiEndpoint method="GET" path="/payment-instruments" />
* delete a saved payment method with <ApiEndpoint method="DELETE" path="/payment-instruments/<PAYMENT_METHOD_TOKEN>" />

### With Drop-in Checkout

When using Drop-in Checkout, customers have the ability to remove any of their previously vaulted ones.

<Frame caption="Universal Checkout Vault">
  <img src="https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/save-payment-methods/vault-1.png" />

  <img src="https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/save-payment-methods/dropin-vault-edit.png" />
</Frame>
