Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .cspell/custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,10 @@ zapatillas
yml
jwks
keyid
CAVV
Cybersource
MDES
ntoken
TAVV
TRID
YFAAAAAAAAAAA
173 changes: 173 additions & 0 deletions docs/specification/card-network-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<!--
Copyright 2026 UCP Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

# Card Network Token Credential

## Overview

The card network token credential type enables platforms to present card
network tokens (Visa VTS, Mastercard MDES, Amex Token Service) directly as
payment credentials in checkout sessions. Network tokens are opaque
credentials issued by card networks that replace the primary account number
(PAN) with a domain-restricted, cryptogram-protected token.

**Key features:**

- Present pre-provisioned network tokens directly at checkout
- Eliminate CVV collection (cryptogram structurally replaces CVC)
- Reduce PCI DSS compliance scope compared to handling raw card data
- Support all major card networks (Visa, Mastercard, Amex, Discover, JCB)

**Dependencies:**

- Checkout Capability
- Payment Handler Guide

## Credential Schema

### `card_network_token_credential.json`

The credential extends `payment_credential.json` via `allOf`:

| Field | Type | Required | Description |
|----------------------|---------|----------|------------------------------------------------------------------|
| `type` | const | Yes | `"card_network_token"` |
| `token` | string | Yes | Card network token value (DPAN). Omitted from responses. |
| `token_expiry_month` | integer | Yes | Month of the token's expiration date (1-12) |
| `token_expiry_year` | integer | Yes | Year of the token's expiration date |
| `cryptogram` | string | No | One-time-use cryptogram (TAVV/CAVV). Omitted from responses. |
| `eci_value` | string | No | Electronic Commerce Indicator / Security Level Indicator |
| `name` | string | No | Cardholder name. Required by some PSPs (e.g., Adyen). |
| `token_requestor_id` | string | No | Token Requestor ID (TRID) from the card network |

**Required vs optional fields reflect PSP reality:**

- `token` and `token_expiry_*` are universally required by all PSPs
- `cryptogram` and `eci_value` are conditional: required for customer-initiated
transactions (CIT) but may be omitted for merchant-initiated transactions
(MIT/recurring)
- `name` is optional because only some PSPs (e.g., Adyen) require it
- `token_requestor_id` is optional; relevant when the token presenter differs
from the provisioner

**Response omission:** `token` and `cryptogram` use `ucp_response: "omit"` to
prevent sensitive data leakage in API responses, following the pattern from
`token_credential.json`.

## Instrument Schema

### `card_network_token_instrument.json`

Network tokens are cards — they share display properties (brand, last digits,
expiry, card art) with card instruments. The instrument extends
`card_payment_instrument.json`:

```json
{
"allOf": [
{ "$ref": "card_payment_instrument.json" },
{
"type": "object",
"required": ["type"],
"properties": {
"type": { "const": "card_network_token" },
"credential": {
"$ref": "card_network_token_credential.json"
}
}
}
]
}
```

The instrument inherits the card display properties (`brand`, `last_digits`,
`expiry_month`, `expiry_year`, `card_art`) from the card instrument schema.

### Available Instrument Variant

The schema defines `available_card_network_token_instrument` in `$defs`,
extending `available_card_payment_instrument` to inherit `constraints.brands`:

```json
{
"$defs": {
"available_card_network_token_instrument": {
"allOf": [
{ "$ref": "card_payment_instrument.json#/$defs/available_card_payment_instrument" },
{
"type": "object",
"properties": {
"type": { "const": "card_network_token" }
}
}
]
}
}
}
```

## How Network Tokens Fit the Handler Model

Network tokens are **pre-provisioned credentials** that bypass the
tokenize/detokenize flow:

1. **Negotiation** — The business's handler declares `available_instruments`
including `card_network_token`. The platform sees that the handler accepts
network token instruments.
2. **Acquisition** — No tokenizer round-trip is needed. The platform constructs
the instrument from a pre-provisioned network token, including a fresh
cryptogram from the card network.
3. **Completion** — The platform submits the `card_network_token` instrument.
The business's PSP processes the network token directly.

This is analogous to how wallet handlers (e.g., Google Pay, Shop Pay) work:
the platform holds a pre-provisioned opaque credential and presents it
directly.

## Usage Example

A platform presenting a pre-provisioned Visa network token at checkout:

```json
{
"payment": {
"instruments": [
{
"id": "pi_ntoken_001",
"handler_id": "handler_merchant_psp",
"type": "card_network_token",
"credential": {
"type": "card_network_token",
"token": "4895370012003478",
"token_expiry_month": 12,
"token_expiry_year": 2028,
"name": "Jane Doe",
"cryptogram": "AJkBBkhAAAAA0YFAAAAAAAAAAA==",
"eci_value": "05",
"token_requestor_id": "40012345678"
},
"display": {
"brand": "visa",
"last_digits": "3478",
"expiry_month": 12,
"expiry_year": 2028
},
"selected": true
}
]
}
}
```
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ nav:
- Payment Handlers:
- Guide: specification/payment-handler-guide.md
- Template: specification/payment-handler-template.md
- Card Network Token: specification/card-network-token.md
- Tokenization Guide: specification/tokenization-guide.md
- Examples:
- Processor Tokenizer: specification/examples/processor-tokenizer-payment-handler.md
Expand Down Expand Up @@ -236,6 +237,7 @@ plugins:
- specification/identity-linking.md
- specification/payment-handler-guide.md
- specification/payment-handler-template.md
- specification/card-network-token.md
- specification/tokenization-guide.md
- specification/examples/processor-tokenizer-payment-handler.md
- specification/examples/platform-tokenizer-payment-handler.md
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/shopping/types/card_network_token_credential.json",
"title": "Card Network Token Credential",
"description": "Credential for card network tokens (e.g., Visa VTS, Mastercard MDES). Network tokens are opaque credentials that replace raw PANs, reducing PCI DSS compliance scope.",
"allOf": [
{ "$ref": "payment_credential.json" },
{
"type": "object",
"required": ["type", "token", "token_expiry_month", "token_expiry_year"],
"properties": {
"type": { "const": "card_network_token" },
"token": {
"type": "string",
"description": "Card network token value (DPAN).",
"ucp_response": "omit"
},
"token_expiry_month": {
"type": "integer",
"description": "The month of the token's expiration date (1-12)."
},
"token_expiry_year": {
"type": "integer",
"description": "The year of the token's expiration date."
},
"cryptogram": {
"type": "string",
"description": "One-time-use cryptogram (TAVV/CAVV) for authorization.",
"ucp_response": "omit"
},
"eci_value": {
"type": "string",
"description": "Electronic Commerce Indicator / Security Level Indicator.",
"examples": ["05", "07"]
},
"name": {
"type": "string",
"description": "Cardholder name. Required by some PSPs (e.g., Adyen)."
},
"token_requestor_id": {
"type": "string",
"description": "Token Requestor ID (TRID) from the card network."
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/shopping/types/card_network_token_instrument.json",
"title": "Card Network Token Payment Instrument",
"description": "A card network token payment instrument. Extends card_payment_instrument with network token credential.",
"$defs": {
"available_card_network_token_instrument": {
"title": "Available Card Network Token Instrument",
"description": "Declares card network token instrument availability with card-specific constraints.",
"allOf": [
{ "$ref": "card_payment_instrument.json#/$defs/available_card_payment_instrument" },
{
"type": "object",
"properties": {
"type": { "const": "card_network_token" }
}
}
]
}
},
"allOf": [
{ "$ref": "card_payment_instrument.json" },
{
"type": "object",
"required": ["type"],
"properties": {
"type": {
"const": "card_network_token",
"description": "Indicates this is a card network token payment instrument."
},
"credential": {
"$ref": "card_network_token_credential.json"
}
}
}
]
}