From bdef773f95abb0f0a4721339f1c040237074aaac Mon Sep 17 00:00:00 2001 From: James Andersen Date: Fri, 17 Apr 2026 00:02:35 -0700 Subject: [PATCH 1/4] docs: clarify network token usage and PCI scope in card credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation for pre-provisioned network token usage and PCI scope distinctions between FPAN and network token credential modes: - Add "Pre-Provisioned Network Tokens" section to the tokenization guide covering the BYOT path where platforms present card network tokens directly as card_number_type: "network_token" without a tokenize/detokenize round-trip - Add network token bullet to Platform PCI Scope in the overview - Update card_credential.json description to distinguish PCI scope between fpan (full PCI DSS) and network_token (reduced scope) References #296 — split from the original card network token credential PR into a focused docs-only change per reviewer feedback. --- .cspell/custom-words.txt | 1 + docs/specification/overview.md | 4 +++ docs/specification/tokenization-guide.md | 36 +++++++++++++++++++ .../shopping/types/card_credential.json | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index c46d3595d..f5431f692 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -26,6 +26,7 @@ Kroger Lowe's Macy's Mastercard +MDES Paymentech Paypal Preorders diff --git a/docs/specification/overview.md b/docs/specification/overview.md index 1265aef6a..bba5699ed 100644 --- a/docs/specification/overview.md +++ b/docs/specification/overview.md @@ -1464,6 +1464,10 @@ Most platform implementations can **avoid PCI-DSS scope** by: - Forwarding credentials without the ability to use them directly - Using PSP tokenization payment handlers where raw credentials never pass through the platform +- Presenting pre-provisioned card network tokens + (`card_number_type: "network_token"`) — DPANs with cryptograms are not + considered cardholder data by most acquirers, reducing PCI scope compared + to handling FPANs directly #### Business Scope diff --git a/docs/specification/tokenization-guide.md b/docs/specification/tokenization-guide.md index c574b6fbf..1b18522d1 100644 --- a/docs/specification/tokenization-guide.md +++ b/docs/specification/tokenization-guide.md @@ -68,6 +68,42 @@ Tokenization handlers transform credentials between source and checkout forms: Tokenization handlers accept source credentials (e.g., card with FPAN) and produce checkout credentials (e.g., tokens). +### Pre-Provisioned Network Tokens + +Not all credential flows require a tokenize/detokenize round-trip. When a +platform already holds a **card network token** (provisioned via Visa VTS, +Mastercard MDES, or similar), it can present the token directly as a +`card_credential` with `card_number_type: "network_token"`. This bypasses +the tokenization handler lifecycle entirely — the credential is ready for +checkout as-is. + +```json +{ + "type": "card", + "card_number_type": "network_token", + "number": "4000000000000002", + "expiry_month": 12, + "expiry_year": 2027, + "cryptogram": "gXc5UCLnM6ckD7pjM1TdPA==", + "eci_value": "07" +} +``` + +Key differences from the tokenize/detokenize flow: + +| Aspect | Tokenize/Detokenize | Pre-Provisioned Network Token | +| :----- | :------------------ | :---------------------------- | +| Source | Platform holds FPAN | Platform holds DPAN from card network | +| Flow | Platform → handler `/tokenize` → token | Platform presents credential directly | +| Cryptogram | Not applicable | Required — generated by the token service | +| PCI scope | Platform may handle raw PANs | Reduced — DPANs are not considered cardholder data by most acquirers | + +When a handler's `available_instruments` includes +`requires_card_verification: true`, the platform **MUST** provide the +`cryptogram` and `eci_value` fields for network token credentials. See +the [Card Constraints](payment-handler-guide.md#card-constraints) section +in the Payment Handler Guide for details. + ### Token Lifecycle Tokens move through distinct phases. Your handler specification must document diff --git a/source/schemas/shopping/types/card_credential.json b/source/schemas/shopping/types/card_credential.json index 0d08cc790..256ebf586 100644 --- a/source/schemas/shopping/types/card_credential.json +++ b/source/schemas/shopping/types/card_credential.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://ucp.dev/schemas/shopping/types/card_credential.json", "title": "Card Credential", - "description": "A card credential containing sensitive payment card details including raw Primary Account Numbers (PANs). This credential type MUST NOT be used for checkout, only with payment handlers that tokenize or encrypt credentials. CRITICAL: Both parties handling CardCredential (sender and receiver) MUST be PCI DSS compliant. Transmission MUST use HTTPS/TLS with strong cipher suites.", + "description": "A card credential containing payment card details. When card_number_type is 'fpan', this contains a raw Primary Account Number (PAN) — both parties MUST be PCI DSS compliant. When card_number_type is 'network_token', this contains a Device PAN (DPAN) with cryptogram and ECI, which operates under reduced PCI scope as DPANs are not considered cardholder data by most acquirers. FPAN credentials MUST NOT be used directly for checkout — use payment handlers that tokenize or encrypt credentials. Transmission MUST use HTTPS/TLS with strong cipher suites.", "allOf": [ { "$ref": "payment_credential.json" From b299bf0ab1ab3712c5b6106f7cd72af06d824316 Mon Sep 17 00:00:00 2001 From: James Andersen Date: Mon, 20 Apr 2026 22:49:34 -0700 Subject: [PATCH 2/4] docs: replace PCI scope assertions with references to PCI DSS guidance Update three locations that asserted DPANs "are not considered cardholder data by most acquirers" to instead reference current PCI DSS guidance, avoiding scope claims that could go stale if PCI SSC updates requirements. --- docs/specification/overview.md | 7 ++++--- docs/specification/tokenization-guide.md | 2 +- source/schemas/shopping/types/card_credential.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/specification/overview.md b/docs/specification/overview.md index bba5699ed..f7fe830cf 100644 --- a/docs/specification/overview.md +++ b/docs/specification/overview.md @@ -1465,9 +1465,10 @@ Most platform implementations can **avoid PCI-DSS scope** by: - Using PSP tokenization payment handlers where raw credentials never pass through the platform - Presenting pre-provisioned card network tokens - (`card_number_type: "network_token"`) — DPANs with cryptograms are not - considered cardholder data by most acquirers, reducing PCI scope compared - to handling FPANs directly + (`card_number_type: "network_token"`) — DPANs with cryptograms may + qualify for reduced PCI scope compared to handling FPANs directly; + consult current [PCI DSS guidance](https://www.pcisecuritystandards.org/) + for applicable requirements #### Business Scope diff --git a/docs/specification/tokenization-guide.md b/docs/specification/tokenization-guide.md index 1b18522d1..29fbf246e 100644 --- a/docs/specification/tokenization-guide.md +++ b/docs/specification/tokenization-guide.md @@ -96,7 +96,7 @@ Key differences from the tokenize/detokenize flow: | Source | Platform holds FPAN | Platform holds DPAN from card network | | Flow | Platform → handler `/tokenize` → token | Platform presents credential directly | | Cryptogram | Not applicable | Required — generated by the token service | -| PCI scope | Platform may handle raw PANs | Reduced — DPANs are not considered cardholder data by most acquirers | +| PCI scope | Platform may handle raw PANs | May be reduced — consult current [PCI DSS guidance](https://www.pcisecuritystandards.org/) for applicable scope | When a handler's `available_instruments` includes `requires_card_verification: true`, the platform **MUST** provide the diff --git a/source/schemas/shopping/types/card_credential.json b/source/schemas/shopping/types/card_credential.json index 256ebf586..3e5cb314b 100644 --- a/source/schemas/shopping/types/card_credential.json +++ b/source/schemas/shopping/types/card_credential.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://ucp.dev/schemas/shopping/types/card_credential.json", "title": "Card Credential", - "description": "A card credential containing payment card details. When card_number_type is 'fpan', this contains a raw Primary Account Number (PAN) — both parties MUST be PCI DSS compliant. When card_number_type is 'network_token', this contains a Device PAN (DPAN) with cryptogram and ECI, which operates under reduced PCI scope as DPANs are not considered cardholder data by most acquirers. FPAN credentials MUST NOT be used directly for checkout — use payment handlers that tokenize or encrypt credentials. Transmission MUST use HTTPS/TLS with strong cipher suites.", + "description": "A card credential containing payment card details. When card_number_type is 'fpan', this contains a raw Primary Account Number (PAN) — both parties MUST be PCI DSS compliant. When card_number_type is 'network_token', this contains a Device PAN (DPAN) with cryptogram and ECI, which may qualify for reduced PCI scope — consult current PCI DSS guidance for applicable requirements. FPAN credentials MUST NOT be used directly for checkout — use payment handlers that tokenize or encrypt credentials. Transmission MUST use HTTPS/TLS with strong cipher suites.", "allOf": [ { "$ref": "payment_credential.json" From ab9db8555da9605f7d6dcb863b27ae0ee1c8d8dd Mon Sep 17 00:00:00 2001 From: James Andersen Date: Thu, 23 Apr 2026 23:11:27 -0700 Subject: [PATCH 3/4] docs: generalize network token section per review feedback Reframe pre-provisioned network tokens as a general credential pattern: - Rename section to "Pre-Provisioned Credentials" - Drop DPAN qualifier and VTS/MDES API references - Clarify payment handler is required for capability negotiation - Use network tokens as concrete example, not sole focus --- docs/specification/overview.md | 7 +++--- docs/specification/tokenization-guide.md | 28 ++++++++++++++---------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/docs/specification/overview.md b/docs/specification/overview.md index f7fe830cf..0c7fd4b80 100644 --- a/docs/specification/overview.md +++ b/docs/specification/overview.md @@ -1465,9 +1465,10 @@ Most platform implementations can **avoid PCI-DSS scope** by: - Using PSP tokenization payment handlers where raw credentials never pass through the platform - Presenting pre-provisioned card network tokens - (`card_number_type: "network_token"`) — DPANs with cryptograms may - qualify for reduced PCI scope compared to handling FPANs directly; - consult current [PCI DSS guidance](https://www.pcisecuritystandards.org/) + (`card_number_type: "network_token"`) — network tokens with + cryptograms may qualify for reduced PCI scope compared to handling + FPANs directly; consult current + [PCI DSS guidance](https://www.pcisecuritystandards.org/) for applicable requirements #### Business Scope diff --git a/docs/specification/tokenization-guide.md b/docs/specification/tokenization-guide.md index 29fbf246e..eeb153048 100644 --- a/docs/specification/tokenization-guide.md +++ b/docs/specification/tokenization-guide.md @@ -68,14 +68,20 @@ Tokenization handlers transform credentials between source and checkout forms: Tokenization handlers accept source credentials (e.g., card with FPAN) and produce checkout credentials (e.g., tokens). -### Pre-Provisioned Network Tokens +### Pre-Provisioned Credentials -Not all credential flows require a tokenize/detokenize round-trip. When a -platform already holds a **card network token** (provisioned via Visa VTS, -Mastercard MDES, or similar), it can present the token directly as a -`card_credential` with `card_number_type: "network_token"`. This bypasses -the tokenization handler lifecycle entirely — the credential is ready for -checkout as-is. +Not all credential flows require a tokenize/detokenize round-trip per +transaction. In some cases, a platform may have acquired credentials in +advance — for example, by provisioning a card network token via the +network's token service — and can present them in place of tokenizing an +FPAN at each transaction. Although no credential transformation occurs, +a payment handler is still required for capability negotiation — the +handler advertises support for this credential type so that platforms and +businesses can discover and agree on its use. + +Card network tokens are one such case. When a platform already holds a +network token, it can present the token directly as a `card_credential` +with `card_number_type: "network_token"`: ```json { @@ -91,10 +97,10 @@ checkout as-is. Key differences from the tokenize/detokenize flow: -| Aspect | Tokenize/Detokenize | Pre-Provisioned Network Token | -| :----- | :------------------ | :---------------------------- | -| Source | Platform holds FPAN | Platform holds DPAN from card network | -| Flow | Platform → handler `/tokenize` → token | Platform presents credential directly | +| Aspect | Tokenize/Detokenize | Pre-Provisioned Credential | +| :----- | :------------------ | :------------------------- | +| Source | Platform holds FPAN | Platform holds network token provisioned in advance | +| Flow | Platform → handler `/tokenize` → token per transaction | Platform presents credential directly | | Cryptogram | Not applicable | Required — generated by the token service | | PCI scope | Platform may handle raw PANs | May be reduced — consult current [PCI DSS guidance](https://www.pcisecuritystandards.org/) for applicable scope | From 016d00fc3f3bd257e13b25dc09a2b297cd11011c Mon Sep 17 00:00:00 2001 From: James Andersen Date: Thu, 30 Apr 2026 09:06:48 -0700 Subject: [PATCH 4/4] docs: make card_credential description DPAN/CPAN agnostic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review nit from @kmcduffie — use "network token" instead of "Device PAN (DPAN)" to cover both DPANs and CPANs. --- source/schemas/shopping/types/card_credential.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/schemas/shopping/types/card_credential.json b/source/schemas/shopping/types/card_credential.json index 3e5cb314b..7db8fece1 100644 --- a/source/schemas/shopping/types/card_credential.json +++ b/source/schemas/shopping/types/card_credential.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://ucp.dev/schemas/shopping/types/card_credential.json", "title": "Card Credential", - "description": "A card credential containing payment card details. When card_number_type is 'fpan', this contains a raw Primary Account Number (PAN) — both parties MUST be PCI DSS compliant. When card_number_type is 'network_token', this contains a Device PAN (DPAN) with cryptogram and ECI, which may qualify for reduced PCI scope — consult current PCI DSS guidance for applicable requirements. FPAN credentials MUST NOT be used directly for checkout — use payment handlers that tokenize or encrypt credentials. Transmission MUST use HTTPS/TLS with strong cipher suites.", + "description": "A card credential containing payment card details. When card_number_type is 'fpan', this contains a raw Primary Account Number (PAN) — both parties MUST be PCI DSS compliant. When card_number_type is 'network_token', this contains a network token with cryptogram and ECI, which may qualify for reduced PCI scope — consult current PCI DSS guidance for applicable requirements. FPAN credentials MUST NOT be used directly for checkout — use payment handlers that tokenize or encrypt credentials. Transmission MUST use HTTPS/TLS with strong cipher suites.", "allOf": [ { "$ref": "payment_credential.json"