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

# Testing Network Tokens

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>;
};

<Note>
  Before testing network tokens in sandbox, make sure your account is fully enrolled to network tokenization.

  Speak to your Customer Success Manager or raise a ticket on our [Support Portal](https://primerapi.atlassian.net/servicedesk/customer/portal/11).  If you don't have access, please contact your account administrator for assistance.
</Note>

<Warning>
  Visa's testing environment is frequently reset, which makes testing Visa network tokens extremely unreliable.

  As a result, testing Visa network tokenization is not available on Primer sandbox. We encourage you to only test Mastercard network tokenization in sandbox, and to test Visa network tokenization in production.
</Warning>

### Provisioning network tokens

<Note>
  On sandbox, Primer attempts to provision a network token whenever a card is added to the vault of a customer ID starting with `primer-nt-testing`.
</Note>

The best way to vault a card is to use Universal Checkout. Make sure to call <ApiEndpoint method="POST" path="/client-session" /> with a ["customerId"](/api-reference/v2.4/api-reference/client-session-api/create-a-client-session#body-customer-id) and ["vaultOnSuccess"](/api-reference/v2.4/api-reference/client-session-api/create-a-client-session#response-payment-method-vault-on-success) set to `true`. This automatically vaults the card if the payment is successfully authorized.

This first payment is processed using the raw card data. Once vaulted, it usually takes a few seconds for the network token to be provisioned and available for subsequent payments.

Use the following test cards to simulate scenarios:

| Scenario          | Card Network | Card Number         | CVV                | Expiry date            |
| ----------------- | ------------ | ------------------- | ------------------ | ---------------------- |
| Eligible card     | Mastercard   | 2222 6904 2006 4590 | Any 3 digit number | Any future expiry date |
| Eligible card     | Mastercard   | 2222 6904 2006 4574 | Any 3 digit number | Any future expiry date |
| Eligible card     | Mastercard   | 2222 6904 2006 4590 | Any 3 digit number | Any future expiry date |
| Eligible card     | Mastercard   | 5120 3501 0006 4594 | Any 3 digit number | Any future expiry date |
| Non-eligible card | Mastercard   | 5460 1261 2820 0800 | Any 3 digit number | Any future expiry date |

<TestCardsTable getCards={(data) => data.cards.networkTokenization} />

To validate that the card was properly network tokenized, call <ApiEndpoint method="GET" path="/payment-instruments" /> to list the saved payment methods for a specific `customerId`. The field ["paymentMethod.isNetworkTokenized"](/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods#response.body.data.paymentMethodData.Payment%20Card%20Token%20API%20Schema.isNetworkTokenized) is set to `true` when the network token was successfully provisioned and attached to the vaulted card.

### Processing payments with network tokens

When a payment is created with a vaulted card that has been network tokenized, Primer automatically attempts to pass the network token to the processor, if the processor is supported.

You can test this by creating a payment with:

* the Payments API by following this [guide](/payment-services/save-payment-methods#create-merchant-initiated-payments)
* or with the vault section of Universal Checkout, by selecting a vaulted card that was network tokenized

To validate that the payment used a network token, call <ApiEndpoint method="GET" path="/payments/<PAYMENT_ID>" /> with the payment ID to retrieve the payment object. The field ["cardTokenType"](/api-reference/v2.4/api-reference/payments-api/get-a-payment#response.body.cardTokenType) is set to:

* `NETWORK_TOKEN` if the payment was processed with a network token
* `CARD_PAN` if the payment was processed with the raw credentials
