diff --git a/docs/documentation/core-concepts.md b/docs/documentation/core-concepts.md index c525ce5e0..f768edad4 100644 --- a/docs/documentation/core-concepts.md +++ b/docs/documentation/core-concepts.md @@ -186,8 +186,8 @@ up-to-date list. | :--- | :--- | :--- | | `dev.ucp.shopping.discount` | checkout, cart | Discount codes and promotions | | `dev.ucp.shopping.fulfillment` | checkout | Shipping and delivery options | -| `dev.ucp.shopping.payment_authentication` | checkout | Browser-surface device data collection and 3DS challenges | -| `dev.ucp.shopping.ap2_mandate` | checkout | Non-repudiable authorization for autonomous commerce | +| `dev.ucp.common.payment.authentication` | checkout | Browser-surface device data collection and 3DS challenges | +| `dev.ucp.common.payment.ap2_mandate` | checkout | Non-repudiable authorization for autonomous commerce | | `dev.ucp.shopping.buyer_consent` | checkout, cart | Explicit consent capture | ### Services diff --git a/docs/documentation/schema-authoring.md b/docs/documentation/schema-authoring.md index c6ae11983..2413409dd 100644 --- a/docs/documentation/schema-authoring.md +++ b/docs/documentation/schema-authoring.md @@ -144,7 +144,7 @@ Do **not** appear in registries. Examples: -- `schemas/shopping/payment.json` — Payment configuration (part of checkout) +- `schemas/common/types/payment.json` — Payment configuration (part of lower funnel capabilities like checkout in retail shopping) ### Type Schemas diff --git a/docs/specification/glossary.md b/docs/specification/glossary.md index f47164c00..e14024cd2 100644 --- a/docs/specification/glossary.md +++ b/docs/specification/glossary.md @@ -44,6 +44,7 @@ acronym in each specification Markdown file spells out the full term (e.g., | Term | Acronym | Definition | | :--------------------------- | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Business** | - | The entity selling goods or services. In UCP, they act as the **Merchant of Record (MoR)**, retaining financial liability and ownership of the order. | +| **Buyer** | - | The transacting customer or end consumer completing a commerce action over UCP. Synonymous to vocabularies like `user` and `consumer`. | | **Location** | - | A physical place (e.g., store, restaurant, property, pickup point) identified by a stable, opaque string in a Business's namespace. | | **Increment** | - | Optional [ordering granularity](overview/index.md#ordering-increment) of a sale basis, a count of steps; advisory for Platform-authored quantities. | | **Merchant of Record** | MoR | The legal entity responsible for the sale, including financial liability and order ownership. | diff --git a/docs/specification/overview/index.md b/docs/specification/overview/index.md index 9182b6a25..df8bac3a6 100644 --- a/docs/specification/overview/index.md +++ b/docs/specification/overview/index.md @@ -91,7 +91,7 @@ values Section 6) and within which [JCS](https://www.rfc-editor.org/rfc/rfc8785.html){ target="_blank" } canonicalization, required for -[AP2 mandate signing](../ap2-mandates.md#canonicalization), is defined. The +[AP2 mandate signing](../payment/extensions/ap2-mandates.md#canonicalization), is defined. The same cap derives `scale`'s maximum of 15: at scale 16, one whole unit (10^16 steps) would be unrepresentable. An out-of-range value is schema-invalid and is rejected like any other invalid payload. @@ -248,7 +248,7 @@ The grammar is defined independently of the object it is bound to. Request Constraints bind it to objects in the next request and add `path`; other UCP schemas reuse it where a declaration already identifies the object it constrains, such as -[`available_instruments[].constraints`](site:schemas/shopping/types/available_payment_instrument.json), +[`available_instruments[].constraints`](site:schemas/common/types/available_payment_instrument.json), whose object is the `constraint_target` declared by the instrument schema for that entry's `type`. @@ -533,7 +533,7 @@ In this example, a Business emits `ucp.request_constraints` on an available card instrument to require `billing_address` in the next request if it contains a matching submitted card instrument: - + ```json { "type": "card", @@ -563,7 +563,7 @@ network token must carry a `cryptogram` with its `eci_value`. Each credential family is its own schema, so every branch discriminates on the credential's own `type` and no rule has to branch on a sibling field: - + ```json { "type": "card", @@ -595,16 +595,16 @@ it. The sibling `required` applies to every matching instrument; the `anyOf` branches then apply to the nested `credential` object, which must satisfy at least one. Each branch pins `type` with `const`, so a branch matches only the credential family it describes; -[`payment_credential.json`](site:schemas/shopping/types/payment_credential.json) +[`payment_credential.json`](site:schemas/common/types/payment_credential.json) already requires `type` on every credential, so no branch has to name it in -`required`. A [PAN credential](site:schemas/shopping/types/pan_credential.json) +`required`. A [PAN credential](site:schemas/common/types/pan_credential.json) without a `cvc` fails, as does a [network -token](site:schemas/shopping/types/network_token_credential.json) missing its +token](site:schemas/common/types/network_token_credential.json) missing its `eci_value`. Because every branch pins the discriminator, the branch set also closes the accepted credential families. A handler -[token credential](site:schemas/shopping/types/token_credential.json) is a valid +[token credential](site:schemas/common/types/token_credential.json) is a valid credential at this position but satisfies neither branch, so this Business does not accept it at this path. A Business that later accepts another family adds a branch for it. @@ -2470,7 +2470,7 @@ either suffices. This rule governs **HTTP transport identity**. Payload-layer assertions (e.g., AP2 mandate JWTs carried in the request body) have their own identity binding and key-resolution rules; see -[AP2 Mandates](../ap2-mandates.md). +[AP2 Mandates](../payment/extensions/ap2-mandates.md). ## Payment Architecture @@ -2497,11 +2497,11 @@ touch raw financial credentials. For scenarios requiring cryptographic proof of user authorization (e.g., autonomous AI agents), UCP supports the **AP2 Mandates Extension** -(`dev.ucp.shopping.ap2_mandate`). This optional extension provides +(`dev.ucp.common.payment.ap2_mandate`). This optional extension provides non-repudiable authorization through verifiable digital credentials. See [Transaction Integrity](#transaction-integrity-and-non-repudiation) -and [AP2 Mandates Extension](../ap2-mandates.md) for details on when and how to +and [AP2 Mandates Extension](../payment/extensions/ap2-mandates.md) for details on when and how to use this extension. #### Credential Flow & PCI Scope @@ -2579,10 +2579,10 @@ the [Payment Handler Guide](../payment/guide.md#resolving-available_instruments) for the full resolution semantics. **Instrument Cardinality:** A checkout submission **MUST** contain exactly one -payment instrument unless the `dev.ucp.shopping.split_payments` capability is +payment instrument unless the `dev.ucp.common.payment.split_payments` capability is active. Businesses **MUST** reject submissions that violate this constraint with a `payment_failed` error in `messages[]`. See -[Split Payments](../payment/split-payments.md) for the extension that relaxes this +[Split Payments](../payment/extensions/split-payments.md) for the extension that relaxes this constraint. ### Implementation Scenarios @@ -2906,8 +2906,8 @@ certified and handle: 4. Log payment events without logging credentials 5. Set appropriate credential timeouts 6. For autonomous commerce scenarios requiring cryptographic proof, consider - supporting the `dev.ucp.shopping.ap2_mandate` extension (see - [AP2 Mandates Extension](../ap2-mandates.md)) + supporting the `dev.ucp.common.payment.ap2_mandate` extension (see + [AP2 Mandates Extension](../payment/extensions/ap2-mandates.md)) **For Platforms:** @@ -2916,9 +2916,9 @@ certified and handle: 3. Implement timeout handling for credential acquisition 4. Clear credentials from memory after submission 5. Handle credential expiration gracefully (re-acquire if needed) -6. For autonomous agents, consider using the `dev.ucp.shopping.ap2_mandate` +6. For autonomous agents, consider using the `dev.ucp.common.payment.ap2_mandate` extension for cryptographic proof of authorization (see - [AP2 Mandates Extension](../ap2-mandates.md)) + [AP2 Mandates Extension](../payment/extensions/ap2-mandates.md)) **For Payment Credential Providers:** @@ -2950,10 +2950,10 @@ payment architecture: The core payment architecture described above can be extended for specialized use cases: -- **AP2 Mandates Extension** (`dev.ucp.shopping.ap2_mandate`): Adds +- **AP2 Mandates Extension** (`dev.ucp.common.payment.ap2_mandate`): Adds cryptographic proof of user authorization for autonomous commerce scenarios where non-repudiable evidence is required. See - [AP2 Mandates Extension](../ap2-mandates.md). + [AP2 Mandates Extension](../payment/extensions/ap2-mandates.md). - **Custom Handler Types**: Payment credential providers can define custom handlers to support new payment instruments. See @@ -3411,7 +3411,7 @@ business-emitted snapshot of the originating checkout's attribution. For scenarios requiring cryptographic proof of authorization (e.g., autonomous agents, high-value transactions), UCP supports the **AP2 Mandates Extension** -(`dev.ucp.shopping.ap2_mandate`). When this optional extension is negotiated: +(`dev.ucp.common.payment.ap2_mandate`). When this optional extension is negotiated: - Businesses provide a cryptographic signature on checkout terms - Platforms provide cryptographic mandates proving user authorization @@ -3420,7 +3420,7 @@ This mechanism provides strong, end-to-end cryptographic assurances about transaction details and participant consent, significantly reducing risks of tampering and disputes. -See [AP2 Mandates Extension](../ap2-mandates.md) for complete specification, +See [AP2 Mandates Extension](../payment/extensions/ap2-mandates.md) for complete specification, implementation guide, and examples. ## Versioning diff --git a/docs/specification/payment/examples/encrypted-credential-payment-handler.md b/docs/specification/payment/examples/encrypted-credential-payment-handler.md index fbdd566a6..abef5050c 100644 --- a/docs/specification/payment/examples/encrypted-credential-payment-handler.md +++ b/docs/specification/payment/examples/encrypted-credential-payment-handler.md @@ -121,7 +121,7 @@ Businesses advertise the platform's handler. The `business_id` field identifies the business, which the platform uses to look up the correct public key for encryption. -The only supported instrument schema is [CardPaymentInstrument](site:schemas/shopping/types/card_payment_instrument.json), the only supported checkout credential schema is `EncryptedCredential`, and the only supported source credential schema is [PanCredential](site:schemas/shopping/types/pan_credential.json). +The only supported instrument schema is [CardPaymentInstrument](site:schemas/common/types/card_payment_instrument.json), the only supported checkout credential schema is `EncryptedCredential`, and the only supported source credential schema is [PanCredential](site:schemas/common/types/pan_credential.json). **Note:** The `EncryptedCredential` shape would be formally defined in the handler's schema (referenced via the `schema` field in the handler declaration). @@ -359,5 +359,5 @@ Content-Type: application/json ## References -* **Identity Schema:** [schemas/shopping/types/payment_identity.json](site:schemas/shopping/types/payment_identity.json) -* **Instrument Schema:** [schemas/shopping/types/card_payment_instrument.json](site:schemas/shopping/types/card_payment_instrument.json) +* **Identity Schema:** [schemas/common/types/payment_identity.json](site:schemas/common/types/payment_identity.json) +* **Instrument Schema:** [schemas/common/types/card_payment_instrument.json](site:schemas/common/types/card_payment_instrument.json) diff --git a/docs/specification/payment/examples/platform-tokenizer-payment-handler.md b/docs/specification/payment/examples/platform-tokenizer-payment-handler.md index 34b3d00f5..254f4a50e 100644 --- a/docs/specification/payment/examples/platform-tokenizer-payment-handler.md +++ b/docs/specification/payment/examples/platform-tokenizer-payment-handler.md @@ -176,7 +176,7 @@ platform's handler specification (referenced via `spec`) documents the `/detokenize` endpoint URL exposed by the platform's **payment credential provider**. -The handler accepts [PanCredential](site:schemas/shopping/types/pan_credential.json) and [NetworkTokenCredential](site:schemas/shopping/types/network_token_credential.json) for tokenization and produces [TokenCredential](site:schemas/shopping/types/token_credential.json) for checkout. +The handler accepts [PanCredential](site:schemas/common/types/pan_credential.json) and [NetworkTokenCredential](site:schemas/common/types/network_token_credential.json) for tokenization and produces [TokenCredential](site:schemas/common/types/token_credential.json) for checkout. **Note:** The result of `/detokenize` contains **sensitive payment data**. Both the sender (platform's credential provider) and receiver @@ -414,12 +414,12 @@ Content-Type: application/json ## Runtime Payment Authentication Actions This handler supports both Action types from the negotiated -[Payment Authentication extension](../authentication.md): +[Payment Authentication extension](../extensions/authentication.md): | Action type | Use | | :---------- | :-- | -| `dev.ucp.payment.device_data_collection` | Collect device/browser data for the selected tokenized instrument. | -| `dev.ucp.payment.three_ds_challenge` | Present a buyer-facing 3DS challenge during payment completion. | +| `dev.ucp.common.payment.device_data_collection` | Collect device/browser data for the selected tokenized instrument. | +| `dev.ucp.common.payment.three_ds_challenge` | Present a buyer-facing 3DS challenge during payment completion. | When either step is needed, the Business returns the corresponding Action while processing the selected instrument. Its `config.payment_instrument_id` identifies @@ -519,4 +519,4 @@ The platform's payment credential provider verifies that: * **Pattern:** [Tokenization Payment Handler](../guide.md) * **API Pattern:** [handlers/tokenization/openapi.json](site:handlers/tokenization/openapi.json) -* **Identity Schema:** [schemas/shopping/types/payment_identity.json](site:schemas/shopping/types/payment_identity.json) +* **Identity Schema:** [schemas/common/types/payment_identity.json](site:schemas/common/types/payment_identity.json) diff --git a/docs/specification/payment/actions/device-data-collection.md b/docs/specification/payment/extensions/actions/device-data-collection.md similarity index 95% rename from docs/specification/payment/actions/device-data-collection.md rename to docs/specification/payment/extensions/actions/device-data-collection.md index bb8b39b50..2d78c9382 100644 --- a/docs/specification/payment/actions/device-data-collection.md +++ b/docs/specification/payment/extensions/actions/device-data-collection.md @@ -20,7 +20,7 @@ This specification defines the device data collection Action type declared by the [Payment Authentication extension](../authentication.md): ```text -dev.ucp.payment.device_data_collection +dev.ucp.common.payment.device_data_collection ``` It asks the Platform to mount an invisible payment-authentication surface to @@ -56,11 +56,11 @@ will not wait for, the Business **MUST NOT** emit an Action. The Action is emitted under its type key: - + ```json { "actions": { - "dev.ucp.payment.device_data_collection": [ + "dev.ucp.common.payment.device_data_collection": [ { "id": "ddc-1", "config": { @@ -74,7 +74,7 @@ The Action is emitted under its type key: ``` The config shape is defined inline by the -[Payment Authentication extension schema](site:schemas/shopping/payment_authentication.json). +[Payment Authentication extension schema](site:schemas/common/payment_authentication.json). | Field | Type | Required | Notes | | :---- | :--- | :------- | :---- | @@ -100,7 +100,7 @@ The Platform **MUST**: Mounting the surface **MUST** follow the shared [Payment Authentication rendering contract](../authentication.md#surface-rendering-and-notifications) -and [Embedded Protocol security requirements](../../embedded-protocol.md#security). +and [Embedded Protocol security requirements](../../../embedded-protocol.md#security). On the web the surface is typically a hidden iframe. A native Platform may use an isolated webview or equivalent browser surface. It **MUST NOT** be visible to diff --git a/docs/specification/payment/actions/three-ds-challenge.md b/docs/specification/payment/extensions/actions/three-ds-challenge.md similarity index 95% rename from docs/specification/payment/actions/three-ds-challenge.md rename to docs/specification/payment/extensions/actions/three-ds-challenge.md index 979c8cc78..1a7032853 100644 --- a/docs/specification/payment/actions/three-ds-challenge.md +++ b/docs/specification/payment/extensions/actions/three-ds-challenge.md @@ -20,7 +20,7 @@ This specification defines the 3DS challenge Action type declared by the [Payment Authentication extension](../authentication.md): ```text -dev.ucp.payment.three_ds_challenge +dev.ucp.common.payment.three_ds_challenge ``` It asks the Platform to present a buyer-facing payment-authentication surface to @@ -55,11 +55,11 @@ challenge occurrence. The Action is emitted under its type key: - + ```json { "actions": { - "dev.ucp.payment.three_ds_challenge": [ + "dev.ucp.common.payment.three_ds_challenge": [ { "id": "three-ds-challenge-1", "config": { @@ -73,7 +73,7 @@ The Action is emitted under its type key: ``` The config shape is defined inline by the -[Payment Authentication extension schema](site:schemas/shopping/payment_authentication.json). +[Payment Authentication extension schema](site:schemas/common/payment_authentication.json). | Field | Type | Required | Notes | | :---- | :--- | :------- | :---- | @@ -102,7 +102,7 @@ The Platform **MUST**: Mounting the surface **MUST** follow the shared [Payment Authentication rendering contract](../authentication.md#surface-rendering-and-notifications) -and [Embedded Protocol security requirements](../../embedded-protocol.md#security). +and [Embedded Protocol security requirements](../../../embedded-protocol.md#security). On the web the surface may be a full-page frame, modal frame, or separate window when the negotiated handler defines that presentation and its security policy. diff --git a/docs/specification/ap2-mandates.md b/docs/specification/payment/extensions/ap2-mandates.md similarity index 92% rename from docs/specification/ap2-mandates.md rename to docs/specification/payment/extensions/ap2-mandates.md index a6204d376..1ba806d41 100644 --- a/docs/specification/ap2-mandates.md +++ b/docs/specification/payment/extensions/ap2-mandates.md @@ -60,7 +60,7 @@ and the platform. ### Business Profile Advertisement -Businesses declare support by adding `dev.ucp.shopping.ap2_mandate` to their +Businesses declare support by adding `dev.ucp.common.payment.ap2_mandate` to their `capabilities` list in `/.well-known/ucp`. **Business Profile Example:** @@ -79,11 +79,11 @@ Businesses declare support by adding `dev.ucp.shopping.ap2_mandate` to their "schema": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/checkout.json" } ], - "dev.ucp.shopping.ap2_mandate": [ + "dev.ucp.common.payment.ap2_mandate": [ { "version": "{{ ucp_version }}", - "spec": "https://ucp.dev/{{ ucp_version }}/specification/ap2-mandates", - "schema": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/ap2_mandate.json", + "spec": "https://ucp.dev/{{ ucp_version }}/specification/payment/extensions/ap2-mandates", + "schema": "https://ucp.dev/{{ ucp_version }}/schemas/common/payment_ap2_mandate.json", "extends": "dev.ucp.shopping.checkout", "config": { "vp_formats_supported": { @@ -108,7 +108,7 @@ key in the top-level `keys` array in their profile. 1. The platform advertises its profile URI (transport-specific mechanism). 2. The business fetches the profile and computes the intersection. -3. If `dev.ucp.shopping.ap2_mandate` is present in the intersection: +3. If `dev.ucp.common.payment.ap2_mandate` is present in the intersection: * The business **MUST** include `ap2.merchant_authorization` in all checkout responses. * The business **MUST NOT** accept a `complete_checkout` request that @@ -130,16 +130,16 @@ If a public key cannot be resolved, or if the signature is invalid, the business ## Cryptographic Requirements This extension uses the cryptographic primitives defined in the -[Message Signatures](signatures.md) specification: +[Message Signatures](../../signatures.md) specification: * **Algorithm:** per AP2's Checkout JWT signing rule — AP2 v0.2 requires ECDSA (`ES256`/`ES384`/`ES512`); see the note below. * **Canonicalization:** JCS ([RFC 8785](https://datatracker.ietf.org/doc/html/rfc8785)) * **Key Format:** JWK ([RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517)) * **Key Discovery:** `keys[]` in `/.well-known/ucp` (see - [Key Discovery](overview/index.md#key-discovery)) + [Key Discovery](../../overview/index.md#key-discovery)) -See [Message Signatures](signatures.md) for key format and rotation. +See [Message Signatures](../../signatures.md) for key format and rotation. > **Note (algorithm requirement).** AP2 binds the Payment Mandate to the > Checkout via `hash(checkout_jwt)`; the underlying security property is @@ -267,7 +267,7 @@ are automatically handled. ## The Mandate Flow -Once the `dev.ucp.shopping.ap2_mandate` capability is negotiated, the session +Once the `dev.ucp.common.payment.ap2_mandate` capability is negotiated, the session is locked into the following flow. Both parties **MUST** follow these steps to ensure cryptographic integrity; any attempt to bypass these steps or submit a completion request without mandates **MUST** result in a session failure. @@ -277,7 +277,7 @@ a completion request without mandates **MUST** result in a session failure. The platform initiates the session. The business returns the `Checkout` object with `ap2.merchant_authorization` embedded in the response body. -{{ extension_schema_fields('ap2_mandate.json#/$defs/dev.ucp.shopping.checkout', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/dev.ucp.shopping.checkout', 'payment/extensions/ap2-mandates') }} **Example Response:** @@ -367,7 +367,7 @@ Binding (+kb) signature. Once the mandates are generated, the platform submits them in the completion request: -{{ extension_schema_fields('ap2_mandate.json#/$defs/ap2_with_checkout_mandate', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/ap2_with_checkout_mandate', 'payment/extensions/ap2-mandates') }} ```json @@ -455,27 +455,27 @@ checkout. ### Business Authorization {: #merchant-authorization } -{{ extension_schema_fields('ap2_mandate.json#/$defs/merchant_authorization', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/merchant_authorization', 'payment/extensions/ap2-mandates') }} ### AP2 Checkout Response The `ap2` object included in checkout responses. -{{ extension_schema_fields('ap2_mandate.json#/$defs/ap2_with_merchant_authorization', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/ap2_with_merchant_authorization', 'payment/extensions/ap2-mandates') }} ### Checkout Mandate -{{ extension_schema_fields('ap2_mandate.json#/$defs/checkout_mandate', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/checkout_mandate', 'payment/extensions/ap2-mandates') }} ### AP2 Complete Request The `ap2` object included in COMPLETE checkout requests. -{{ extension_schema_fields('ap2_mandate.json#/$defs/ap2_with_checkout_mandate', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/ap2_with_checkout_mandate', 'payment/extensions/ap2-mandates') }} ### Error Codes -{{ extension_schema_fields('ap2_mandate.json#/$defs/error_code', 'ap2-mandates') }} +{{ extension_schema_fields('payment_ap2_mandate.json#/$defs/error_code', 'payment/extensions/ap2-mandates') }} | Error Code | Description | | :------------------------------- | :---------------------------------------------------------------- | diff --git a/docs/specification/payment/authentication.md b/docs/specification/payment/extensions/authentication.md similarity index 92% rename from docs/specification/payment/authentication.md rename to docs/specification/payment/extensions/authentication.md index 91980be9d..06692dbc7 100644 --- a/docs/specification/payment/authentication.md +++ b/docs/specification/payment/extensions/authentication.md @@ -20,17 +20,17 @@ The Payment Authentication extension defines browser-surface interactions that a Platform may need to process while a payment attempt is underway. It declares -two concrete [Action types](../overview/index.md#actions): +two concrete [Action types](../../overview/index.md#actions): | Action type | Platform interaction | | :---------- | :------------------- | -| `dev.ucp.payment.device_data_collection` | Run an invisible browser-capable device data collection surface. | -| `dev.ucp.payment.three_ds_challenge` | Present a buyer-facing 3DS challenge surface. | +| `dev.ucp.common.payment.device_data_collection` | Run an invisible browser-capable device data collection surface. | +| `dev.ucp.common.payment.three_ds_challenge` | Present a buyer-facing 3DS challenge surface. | The extension is named: ```text -dev.ucp.shopping.payment_authentication +dev.ucp.common.payment.authentication ``` It extends `dev.ucp.shopping.checkout`. Negotiating this extension activates the @@ -53,12 +53,12 @@ Businesses and Platforms advertise this extension in their profiles: "ucp": { "version": "{{ ucp_version }}", "capabilities": { - "dev.ucp.shopping.payment_authentication": [ + "dev.ucp.common.payment.authentication": [ { "version": "{{ ucp_version }}", "extends": "dev.ucp.shopping.checkout", - "spec": "https://ucp.dev/{{ ucp_version }}/specification/payment/authentication/", - "schema": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/payment_authentication.json" + "spec": "https://ucp.dev/{{ ucp_version }}/specification/payment/extensions/authentication", + "schema": "https://ucp.dev/{{ ucp_version }}/schemas/common/payment_authentication.json" } ] } @@ -81,14 +81,14 @@ context established by the payment attempt, and Platform policy. Actions are keyed by type in the Checkout response. For example, a device data collection step can be followed by a challenge in a later response: - + ```json { "ucp": { "version": "{{ ucp_version }}", "status": "success", "capabilities": { - "dev.ucp.shopping.payment_authentication": [ + "dev.ucp.common.payment.authentication": [ { "version": "{{ ucp_version }}", "extends": "dev.ucp.shopping.checkout" @@ -121,7 +121,7 @@ collection step can be followed by a challenge in a later response: ] }, "actions": { - "dev.ucp.payment.device_data_collection": [ + "dev.ucp.common.payment.device_data_collection": [ { "id": "ddc-1", "config": { @@ -139,9 +139,9 @@ outstanding per payment attempt at a time, emitting only the next interaction the Platform can process, because collection completes or times out before a challenge is emitted. When collection must precede a challenge, the Business emits the device data collection Action first and emits the challenge under -`dev.ucp.payment.three_ds_challenge` only in a later Checkout response. +`dev.ucp.common.payment.three_ds_challenge` only in a later Checkout response. -When `dev.ucp.shopping.split_payments` is active a Checkout can carry an attempt +When `dev.ucp.common.payment.split_payments` is active a Checkout can carry an attempt per instrument, each with its own outstanding authentication action, and `config.payment_instrument_id` is what distinguishes them. @@ -154,7 +154,7 @@ association cannot be resolved unambiguously. ## Checkout Lifecycle These Action types use the parent Checkout lifecycle defined in -[Checkout — Actions](../shopping/checkout/index.md#actions): +[Checkout — Actions](../../shopping/checkout/index.md#actions): - Every emitted Payment Authentication Action gates advancement of its associated payment attempt while the same Action type and `id` remain outstanding in the @@ -238,7 +238,7 @@ before navigating so an immediately completing surface cannot race initialization. The `postMessage` and native-webview mechanics follow -[Embedded Protocol — Communication Channels](../embedded-protocol.md#communication-channels). +[Embedded Protocol — Communication Channels](../../embedded-protocol.md#communication-channels). Payment Authentication uses the Action methods below. It does not use a capability-specific Embedded Protocol `ready` method or `MessageChannel` upgrade; `action.ready` is its scoped handshake. @@ -333,9 +333,9 @@ reconciliation path above. ## Security and Data Handling Web Platforms **MUST** follow the shared -[Embedded Protocol security requirements](../embedded-protocol.md#security) for +[Embedded Protocol security requirements](../../embedded-protocol.md#security) for CSP, iframe sandboxing, credentialless iframe evaluation, and strict origin -validation. [Embedded Checkout security](../shopping/checkout/embedded.md#security-for-web-based-hosts) +validation. [Embedded Checkout security](../../shopping/checkout/embedded.md#security-for-web-based-hosts) shows how a UCP capability applies those requirements. Payment Authentication uses its own `action.ready` handshake and terminal notification methods; it does not adopt the Embedded Protocol's capability lifecycle or delegation messages. diff --git a/docs/specification/payment/split-payments.md b/docs/specification/payment/extensions/split-payments.md similarity index 97% rename from docs/specification/payment/split-payments.md rename to docs/specification/payment/extensions/split-payments.md index 5598c3b97..542bf32cb 100644 --- a/docs/specification/payment/split-payments.md +++ b/docs/specification/payment/extensions/split-payments.md @@ -16,7 +16,7 @@ # Split Payments Extension -* **Capability Name:** `dev.ucp.shopping.split_payments` +* **Capability Name:** `dev.ucp.common.payment.split_payments` > **Note on examples:** Instrument `type` strings used in this spec > (`card`, `gift_card`, `store_credit`, `loyalty`) are illustrative. @@ -67,7 +67,7 @@ allocation, not processing sequence. When this capability is active, each payment instrument in `checkout.payment.instruments` gains an optional `amount` field. -{{ extension_schema_fields('split_payments.json#/$defs/payment_instrument', 'payment/split-payments') }} +{{ extension_schema_fields('payment_split_payments.json#/$defs/payment_instrument', 'payment/extensions/split-payments') }} ## Configuration @@ -75,7 +75,7 @@ Businesses declare split payments configuration in their profile. ### Business Profile -{{ schema_fields('types/business_split_payments_config', 'payment/split-payments') }} +{{ schema_fields('types/business_split_payments_config', 'payment/extensions/split-payments') }} #### `allowed_combinations` @@ -90,7 +90,7 @@ A set of instruments is valid if it matches **any** combination in the array. Each group within a combination defines a "slot" that accepts certain instrument types: -{{ schema_fields('types/instrument_group', 'payment/split-payments') }} +{{ schema_fields('types/instrument_group', 'payment/extensions/split-payments') }} **Matching algorithm:** a submission matches a combination if there exists an assignment of each submitted instrument to exactly one group such that @@ -111,7 +111,7 @@ gift cards alone, and (c) two credit cards: ```json { "capabilities": [{ - "dev.ucp.shopping.split_payments": [ + "dev.ucp.common.payment.split_payments": [ { "version": "2026-01-23", "config": { @@ -175,7 +175,7 @@ reference to prior requests or responses. > [!NOTE] > Each split payments submission is processed as a complete, > self-contained request: a modified instrument set is a new submission, -> requiring a fresh [idempotency key](../signatures.md#replay-protection). +> requiring a fresh [idempotency key](../../signatures.md#replay-protection). > Split-payments state — including authorizations — does not persist > between submissions; the unwind-on-failure requirement above > enforces this. diff --git a/docs/specification/payment-terms.md b/docs/specification/payment/extensions/terms.md similarity index 94% rename from docs/specification/payment-terms.md rename to docs/specification/payment/extensions/terms.md index 32b1f9f1e..6449b825a 100644 --- a/docs/specification/payment-terms.md +++ b/docs/specification/payment/extensions/terms.md @@ -16,7 +16,7 @@ # Payment Terms Extension -* **Capability Name:** `dev.ucp.shopping.payment_terms` +* **Capability Name:** `dev.ucp.common.payment.terms` ## Overview @@ -38,7 +38,7 @@ This extension adds two properties to `checkout.payment`: is; a Platform writes it to change the selection. A Buyer picks one of the options in `terms[]`, the same way they pick -one [fulfillment option](shopping/extensions/fulfillment.md#platform-responsibilities). +one [fulfillment option](../../shopping/extensions/fulfillment.md#platform-responsibilities). ## When a Checkout carries terms @@ -194,7 +194,7 @@ charged immediately therefore cannot be offered on a term that defers any part of the payment. A term with more than one schedule **MUST** be funded by a single instrument. -[Split Payments](payment/split-payments.md) composes with a term that has exactly one +[Split Payments](split-payments.md) composes with a term that has exactly one schedule, and not otherwise. ## Disclosures @@ -206,7 +206,7 @@ consumer-protection rules about what must be shown, and when. This extension does not define a private disclosure channel. It uses the two that already exist: -1. A [policy](overview/index.md#policies) carries the durable terms text, targeted +1. A [policy](../../overview/index.md#policies) carries the durable terms text, targeted with `applies_to` at the node the terms concern — the payment term when the terms are about payment timing, the line item when they are about the goods. 2. A `messages[]` warning with `presentation: "disclosure"` and `code` set to @@ -219,7 +219,7 @@ optional for a Platform, so any content that **must** reach the Buyer belongs in the warning `content`, not only in the policy `description`. Disclosure display is unconditional. Under [Warning -Presentation](shopping/checkout/index.md#warning-presentation) a Platform **MUST** display +Presentation](../../shopping/checkout/index.md#warning-presentation) a Platform **MUST** display every returned disclosure, **MUST** keep it in proximity to the node named by `path`, and **MUST NOT** hide, collapse, or auto-dismiss it. A Platform that cannot honor that contract — for example one that collapses a list of terms and @@ -268,15 +268,15 @@ Businesses advertise payment terms support in their profile: "ucp": { "version": "{{ ucp_version }}", "capabilities": { - "dev.ucp.shopping.payment_terms": [ + "dev.ucp.common.payment.terms": [ { "version": "{{ ucp_version }}", "extends": [ "dev.ucp.shopping.checkout", "dev.ucp.shopping.order" ], - "spec": "https://ucp.dev/{{ ucp_version }}/specification/payment-terms", - "schema": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/payment_terms.json" + "spec": "https://ucp.dev/{{ ucp_version }}/specification/payment/extensions/terms", + "schema": "https://ucp.dev/{{ ucp_version }}/schemas/common/payment_terms.json" } ] } @@ -291,7 +291,7 @@ Businesses advertise payment terms support in their profile: When this capability is active, `checkout.payment` is extended with available terms and the selected term. -{{ extension_schema_fields('payment_terms.json#/$defs/payment', 'payment-terms') }} +{{ extension_schema_fields('payment_terms.json#/$defs/payment', 'payment/extensions/terms') }} ### Order Payment @@ -306,17 +306,17 @@ can therefore sum to more than the Order currently owes after a refund, or less after an exchange: the term states what was agreed, and the adjustments state what happened after. -{{ extension_schema_fields('payment_terms.json#/$defs/order_payment', 'payment-terms') }} +{{ extension_schema_fields('payment_terms.json#/$defs/order_payment', 'payment/extensions/terms') }} ### Entities #### Payment Term -{{ schema_fields('types/payment_term', 'payment-terms') }} +{{ schema_fields('types/payment_term', 'payment/extensions/terms') }} #### Payment Schedule -{{ schema_fields('types/payment_schedule', 'payment-terms') }} +{{ schema_fields('types/payment_schedule', 'payment/extensions/terms') }} ## Examples @@ -332,7 +332,7 @@ total. **Checkout response fragment — the terms on offer.** The Buyer has not chosen yet, so the Business defaults to paying now, and says so: - + ```json { "selected_term_id": "pt_pay_now", @@ -390,7 +390,7 @@ own entry in `checkout.totals`: **Update request — the Buyer selects the deposit term:** - + ```json { "selected_term_id": "pt_deposit_balance" @@ -399,14 +399,14 @@ own entry in `checkout.totals`: **Checkout response — recomputed and authoritative:** - + ```json { "ucp": { "version": "{{ ucp_version }}", "capabilities": { "dev.ucp.shopping.checkout": [{ "version": "{{ ucp_version }}" }], - "dev.ucp.shopping.payment_terms": [{ "version": "{{ ucp_version }}" }] + "dev.ucp.common.payment.terms": [{ "version": "{{ ucp_version }}" }] }, "payment_handlers": { "com.example.card_handler": [ @@ -499,14 +499,14 @@ On completion, the accepted term travels to the Order, so the Buyer can still see that $900 is due at check-in. The other terms do not travel, and the deposit disclosure moves with the term it governs: - + ```json { "ucp": { "version": "{{ ucp_version }}", "capabilities": { "dev.ucp.shopping.order": [{"version": "{{ ucp_version }}"}], - "dev.ucp.shopping.payment_terms": [{"version": "{{ ucp_version }}"}] + "dev.ucp.common.payment.terms": [{"version": "{{ ucp_version }}"}] } }, "id": "order_9f2", @@ -582,7 +582,7 @@ Four payments and four schedules: one due at completion, and three with computed due dates. The Business does the calendar arithmetic; the Platform reads dates. - + ```json { "id": "pt_pay_in_4", @@ -631,7 +631,7 @@ Platforms **MUST**: * Treat an unrecognized schedule `type` as not due at completion, and present the term regardless. * Process disclosures attached to terms per - [Warning Presentation](shopping/checkout/index.md#warning-presentation), escalating through + [Warning Presentation](../../shopping/checkout/index.md#warning-presentation), escalating through `continue_url` when the rendering contract cannot be honored. Platforms **MAY** use `type` and `due_at` for enhanced presentation — calendar diff --git a/docs/specification/payment/guide.md b/docs/specification/payment/guide.md index 574eadfab..111ebcc10 100644 --- a/docs/specification/payment/guide.md +++ b/docs/specification/payment/guide.md @@ -125,7 +125,7 @@ PREREQUISITES(participant, onboarding_input) → prerequisites_output **Prerequisites Output:** The `prerequisites_output` contains what a participant receives from onboarding. -At minimum, this includes an **identity** (see [Payment Identity](site:schemas/shopping/types/payment_identity.json)). +At minimum, this includes an **identity** (see [Payment Identity](site:schemas/common/types/payment_identity.json)). It **MAY** also include additional configuration, credentials, or settings specific to the handler. @@ -574,8 +574,8 @@ Each variant has its own config schema tailored to its context: | Schema | Description | | :----------------------------------------------------------------------------------------- | :--------------------------------------------------------------- | -| [`payment_instrument.json`](site:schemas/shopping/types/payment_instrument.json) | Base: id, handler_id, type, billing_address, credential, display | -| [`card_payment_instrument.json`](site:schemas/shopping/types/card_payment_instrument.json) | Extends base with display: brand, last_digits, expiry, card art | +| [`payment_instrument.json`](site:schemas/common/types/payment_instrument.json) | Base: id, handler_id, type, billing_address, credential, display | +| [`card_payment_instrument.json`](site:schemas/common/types/card_payment_instrument.json) | Extends base with display: brand, last_digits, expiry, card art | UCP provides base schemas for universal payment instruments like `card`. Spec authors **MAY** extend any of the base instruments to add handler-specific @@ -588,7 +588,7 @@ An instrument schema declares what its availability constraints may name in `$defs/constraint_target`: a plain object of members and their types, never carried in a payload. The handler's `payment_instrument` set binds each `type` to the schema that owns its target. -[`card_payment_instrument.json`](site:schemas/shopping/types/card_payment_instrument.json) +[`card_payment_instrument.json`](site:schemas/common/types/card_payment_instrument.json) declares `brand` as a string, so `{ "properties": { "brand": { "enum": ["visa", "mastercard"] } } }` names a declared member and pins it to string values. The base Payment Handler validates @@ -612,7 +612,7 @@ instrument **SHOULD** extend that instrument's target rather than restate it. "title": "Tokenizer Card Constraint Target", "description": "Extends the card target with tokenizer-specific members.", "allOf": [ - { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/types/card_payment_instrument.json#/$defs/constraint_target" }, + { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/common/types/card_payment_instrument.json#/$defs/constraint_target" }, { "type": "object", "properties": { @@ -627,7 +627,7 @@ instrument **SHOULD** extend that instrument's target rather than restate it. }, "allOf": [ - { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/types/card_payment_instrument.json" } + { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/common/types/card_payment_instrument.json" } ], "type": "object", "required": ["type"], @@ -657,7 +657,7 @@ instrument **SHOULD** extend that instrument's target rather than restate it. "title": "Tokenizer Alt Instrument", "description": "Alternative payment instrument for com.example.tokenizer.", "allOf": [ - { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/types/payment_instrument.json" } + { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/common/types/payment_instrument.json" } ], "type": "object", "required": ["type"], @@ -683,12 +683,12 @@ instrument **SHOULD** extend that instrument's target rather than restate it. **Base Credential Schemas:** -| Schema | Description | -| :------------------------------------------------------------------------------------------- | :------------------------------------------ | -| [`payment_credential.json`](site:schemas/shopping/types/payment_credential.json) | Base: type discriminator only | -| [`token_credential.json`](site:schemas/shopping/types/token_credential.json) | Token: type + token string | -| [`pan_credential.json`](site:schemas/shopping/types/pan_credential.json) | Raw FPAN, verified with `cvc`. Source only. | -| [`network_token_credential.json`](site:schemas/shopping/types/network_token_credential.json) | Network token, verified with `cryptogram` | +| Schema | Description | +| :--------------------------------------------------------------------------------------------- | :------------------------------------------ | +| [`payment_credential.json`](site:schemas/common/types/payment_credential.json) | Base: type discriminator only | +| [`token_credential.json`](site:schemas/common/types/token_credential.json) | Token: type + token string | +| [`pan_credential.json`](site:schemas/common/types/pan_credential.json) | Raw FPAN, verified with `cvc`. Source only. | +| [`network_token_credential.json`](site:schemas/common/types/network_token_credential.json) | Network token, verified with `cryptogram` | UCP provides base schemas for universal payment credentials. Authors **MAY** extend these schemas to include handler-specific credential context. Handlers @@ -711,7 +711,7 @@ refresh credentials. "title": "Tokenizer Card Token", "description": "Card token credential for com.example.tokenizer.", "allOf": [ - { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/types/token_credential.json" } + { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/common/types/token_credential.json" } ], "type": "object", "required": ["type", "token", "expiry"], @@ -739,7 +739,7 @@ refresh credentials. "title": "Tokenizer Alt Token", "description": "Alt token credential for com.example.tokenizer, adding routing hints", "allOf": [ - { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/types/token_credential.json" } + { "$ref": "https://ucp.dev/{{ ucp_version }}/schemas/common/types/token_credential.json" } ], "type": "object", "required": ["type", "token", "expiry"], @@ -803,9 +803,9 @@ Handler authors have two options: - **Use the standard Payment Authentication extension.** Handlers that need device data collection or a 3DS challenge use - [`dev.ucp.shopping.payment_authentication`](authentication.md), which - defines the `dev.ucp.payment.device_data_collection` and - `dev.ucp.payment.three_ds_challenge` Action types. The handler specification + [`dev.ucp.common.payment.authentication`](extensions/authentication.md), which + defines the `dev.ucp.common.payment.device_data_collection` and + `dev.ucp.common.payment.three_ds_challenge` Action types. The handler specification states which types it can cause and any provider-specific trust or fallback requirements, such as allowed origins. - **Define handler-specific Actions.** When the standard types do not fit, the diff --git a/docs/specification/payment/template.md b/docs/specification/payment/template.md index 19b3c1b0f..a09d7ebc6 100644 --- a/docs/specification/payment/template.md +++ b/docs/specification/payment/template.md @@ -319,7 +319,7 @@ Content-Type: application/json {Include this section if the handler can cause Actions. Identify the negotiated Checkout extension that declares them. Use the standard -[Payment Authentication extension](authentication.md) for device data +[Payment Authentication extension](extensions/authentication.md) for device data collection and 3DS challenges; link to the defining extension specification for custom Actions.} diff --git a/docs/specification/payment/tokenization.md b/docs/specification/payment/tokenization.md index 46cc7756c..82ed0bbc0 100644 --- a/docs/specification/payment/tokenization.md +++ b/docs/specification/payment/tokenization.md @@ -112,7 +112,7 @@ alongside `binding` rather than inside it: `binding` says which resource the token is for, `identity` says which participant it is for. `identity` is required when the caller acts on behalf of another participant, and omitted when the authenticated caller is that participant. See -[Payment Identity Schema](site:schemas/shopping/types/payment_identity.json). +[Payment Identity Schema](site:schemas/common/types/payment_identity.json). Binding is a replay guard, not a resource reference. The following rules apply to every tokenizer: @@ -313,14 +313,14 @@ A tokenizer handler conforms to this pattern if it: | Resource | URL | | :---------------------- | :-------------------------------------------------------------------------------------------------------------- | | Tokenization OpenAPI | [handlers/tokenization/openapi.json](site:handlers/tokenization/openapi.json) | -| Identity Schema | [schemas/shopping/types/payment_identity.json](site:schemas/shopping/types/payment_identity.json) | +| Identity Schema | [schemas/common/types/payment_identity.json](site:schemas/common/types/payment_identity.json) | | Binding Schema | [schemas/common/types/binding.json](site:schemas/common/types/binding.json) | -| Token Credential Schema | [schemas/shopping/types/token_credential.json](site:schemas/shopping/types/token_credential.json) | -| Card Instrument Schema | [schemas/shopping/types/card_payment_instrument.json](site:schemas/shopping/types/card_payment_instrument.json) | +| Token Credential Schema | [schemas/common/types/token_credential.json](site:schemas/common/types/token_credential.json) | +| Card Instrument Schema | [schemas/common/types/card_payment_instrument.json](site:schemas/common/types/card_payment_instrument.json) | --- ## See Also - **[Encrypted Credential Handler](examples/encrypted-credential-payment-handler.md)** — Alternative pattern using encryption instead of tokenize/detokenize round-trips -- **[AP2 Mandates Extension](../ap2-mandates.md)** — Add cryptographic proof of checkout agreement for PSP verification +- **[AP2 Mandates Extension](extensions/ap2-mandates.md)** — Add cryptographic proof of checkout agreement for PSP verification diff --git a/docs/specification/reference.md b/docs/specification/reference.md index d84d3da49..73f4291dc 100644 --- a/docs/specification/reference.md +++ b/docs/specification/reference.md @@ -21,6 +21,8 @@ within the UCP. ## Capability Schemas +{{ auto_generate_schema_reference('.', 'reference', include_extensions=False, base_dir='source/schemas/common') }} + {{ auto_generate_schema_reference('.', 'reference', include_extensions=False) }} ## Type Schemas @@ -55,6 +57,8 @@ within the UCP. ## Extension Schemas +{{ auto_generate_schema_reference('.', 'reference', include_capability=False, base_dir='source/schemas/common') }} + {{ auto_generate_schema_reference('.', 'reference', include_capability=False) }} ## UCP Metadata diff --git a/docs/specification/shopping/checkout/a2a.md b/docs/specification/shopping/checkout/a2a.md index e32d473eb..567cb980e 100644 --- a/docs/specification/shopping/checkout/a2a.md +++ b/docs/specification/shopping/checkout/a2a.md @@ -355,7 +355,7 @@ be submitted as part of a `DataPart` with attribute name `a2a.ucp.checkout.payment`. Signed checkout mandate must be specified in the `DataPart` as `ap2.checkout_mandate`. The `token` attribute of `payment` contains the payment mandate. Refer to -[AP2 Mandates Extension](../../ap2-mandates.md) documentation for more details about +[AP2 Mandates Extension](../../payment/extensions/ap2-mandates.md) documentation for more details about verification and processing of the mandates to complete the checkout. #### Request format diff --git a/docs/specification/shopping/checkout/embedded.md b/docs/specification/shopping/checkout/embedded.md index 04fbaf4b7..7a3a7e080 100644 --- a/docs/specification/shopping/checkout/embedded.md +++ b/docs/specification/shopping/checkout/embedded.md @@ -1576,7 +1576,7 @@ account, or wallet credential) available to the buyer. #### Selected Payment Instrument -{{ extension_schema_fields('types/payment_instrument.json#/$defs/selected_payment_instrument', 'embedded-checkout') }} +{{ extension_schema_fields('../common/types/payment_instrument.json#/$defs/selected_payment_instrument', 'embedded-checkout') }} ### Card Payment Instrument diff --git a/docs/specification/shopping/checkout/index.md b/docs/specification/shopping/checkout/index.md index 06ef125e6..96d7a76e7 100644 --- a/docs/specification/shopping/checkout/index.md +++ b/docs/specification/shopping/checkout/index.md @@ -1268,7 +1268,7 @@ this response root (e.g., `$.line_items[0]`). See #### Selected Payment Instrument -{{ extension_schema_fields('types/payment_instrument.json#/$defs/selected_payment_instrument', 'shopping/checkout') }} +{{ extension_schema_fields('../common/types/payment_instrument.json#/$defs/selected_payment_instrument', 'shopping/checkout') }} ### Payment Credential diff --git a/docs/specification/shopping/checkout/mcp.md b/docs/specification/shopping/checkout/mcp.md index d33ee1d95..d0f281c94 100644 --- a/docs/specification/shopping/checkout/mcp.md +++ b/docs/specification/shopping/checkout/mcp.md @@ -144,7 +144,7 @@ Maps to the [Create Checkout](index.md#create-checkout) operation. * `dev.ucp.shopping.buyer_consent`: [Buyer Consent](../extensions/buyer-consent.md) * `dev.ucp.shopping.fulfillment`: [Fulfillment](../extensions/fulfillment.md) * `dev.ucp.shopping.discount`: [Discount](../extensions/discount.md) - * `dev.ucp.shopping.ap2_mandate`: [AP2 Mandates](../../ap2-mandates.md) + * `dev.ucp.common.payment.ap2_mandate`: [AP2 Mandates](../../payment/extensions/ap2-mandates.md) #### Output Schema @@ -404,7 +404,7 @@ unchanged and return the current Checkout with a recoverable error Message. * `dev.ucp.shopping.buyer_consent`: [Buyer Consent](../extensions/buyer-consent.md) * `dev.ucp.shopping.fulfillment`: [Fulfillment](../extensions/fulfillment.md) * `dev.ucp.shopping.discount`: [Discount](../extensions/discount.md) - * `dev.ucp.shopping.ap2_mandate`: [AP2 Mandates](../../ap2-mandates.md) + * `dev.ucp.common.payment.ap2_mandate`: [AP2 Mandates](../../payment/extensions/ap2-mandates.md) #### Output Schema diff --git a/docs/specification/shopping/playground.md b/docs/specification/shopping/playground.md index df79fa1e8..1f3832279 100644 --- a/docs/specification/shopping/playground.md +++ b/docs/specification/shopping/playground.md @@ -532,12 +532,12 @@ const UcpData = { schema: "https://ucp.dev/{{ ucp_version }}/schemas/shopping/buyer_consent.json" } ], - "dev.ucp.shopping.ap2_mandates": [ + "dev.ucp.common.payment.ap2_mandate": [ { extends: "dev.ucp.shopping.checkout", version: "{{ ucp_version }}", - spec: "https://ucp.dev/{{ ucp_version }}/specification/ap2-mandates", - schema: "https://ucp.dev/{{ ucp_version }}/schemas/shopping/ap2_mandate.json" + spec: "https://ucp.dev/{{ ucp_version }}/specification/payment/extensions/ap2-mandates", + schema: "https://ucp.dev/{{ ucp_version }}/schemas/common/payment_ap2_mandate.json" } ] }, @@ -551,7 +551,7 @@ const UcpData = { full: { label: "Full", description: "Supports core + Fulfillment and Discount extensions.", - caps: ["dev.ucp.shopping.checkout", "dev.ucp.shopping.order", "dev.ucp.shopping.fulfillment", "dev.ucp.shopping.discount", "dev.ucp.shopping.buyer_consent", "dev.ucp.shopping.ap2_mandates"] + caps: ["dev.ucp.shopping.checkout", "dev.ucp.shopping.order", "dev.ucp.shopping.fulfillment", "dev.ucp.shopping.discount", "dev.ucp.shopping.buyer_consent", "dev.ucp.common.payment.ap2_mandate"] } }, diff --git a/docs/specification/signatures.md b/docs/specification/signatures.md index 4593cdc28..88683e25b 100644 --- a/docs/specification/signatures.md +++ b/docs/specification/signatures.md @@ -120,7 +120,7 @@ additive option that unlocks Web Bot Auth (WBA) interop. (WBA's algorithm rules and the current deployment landscape are in [WBA Interop](#wba-interop).) * **AP2 mandate signing follows AP2's own algorithm rule** — see - [AP2 Mandates](ap2-mandates.md). + [AP2 Mandates](payment/extensions/ap2-mandates.md). * The algorithm is derived from the key's `kty`/`crv` field in the JWK; `alg` is **NOT** included in `Signature-Input` parameters. @@ -130,7 +130,7 @@ algorithm is accepted by every audience it signs for; separate keys (selected by `kid`) are needed only when audiences impose incompatible algorithm constraints — for example, a WBA verifier that accepts only Ed25519 together with an AP2 mandate algorithm requirement that excludes -it (see [AP2 Mandates](ap2-mandates.md)). When one algorithm satisfies +it (see [AP2 Mandates](payment/extensions/ap2-mandates.md)). When one algorithm satisfies every audience, a single key serves all of them. See [Business Profile](overview/index.md#business-profile) for a two-key example. @@ -414,7 +414,7 @@ derived identity). hashes the raw body bytes. This binds the message body to the signature without requiring JSON canonicalization. Implementations **MUST** use `sha-256`. For durable artifacts requiring canonicalization, see -[AP2 Mandates - Canonicalization](ap2-mandates.md#canonicalization). +[AP2 Mandates - Canonicalization](payment/extensions/ap2-mandates.md#canonicalization). **Intermediary Warning:** Proxies, API gateways, and other intermediaries **MUST NOT** re-serialize JSON bodies, as this would invalidate the signature. diff --git a/main.py b/main.py index 419641e20..ca95b39f1 100644 --- a/main.py +++ b/main.py @@ -1296,6 +1296,9 @@ def auto_generate_schema_reference( rendered_table = _read_schema_from_defs( f"{entity_name}.json#/$defs/{def_name}", spec_file_name ) + if rendered_table == "_No properties defined._": + output.pop() # remove title + continue output.append(rendered_table) output.append("\n") diff --git a/mkdocs.yml b/mkdocs.yml index d80ea3107..76b4a199b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,8 +54,6 @@ nav: - MCP: specification/shopping/checkout/mcp.md - A2A: specification/shopping/checkout/a2a.md - Embedded: specification/shopping/checkout/embedded.md - - AP2 Mandates Extension: specification/ap2-mandates.md - - Payment Terms Extension: specification/payment-terms.md - Cart Capability: - Overview: specification/shopping/cart/index.md - Transports: @@ -82,13 +80,16 @@ nav: specification/shopping/extensions/buyer-consent.md - Playground: specification/shopping/playground.md - Payment: - - Payment Authentication: - - Overview: specification/payment/authentication.md - - Device Data Collection: - specification/payment/actions/device-data-collection.md - - 3DS Challenge: - specification/payment/actions/three-ds-challenge.md - - Split Payments: specification/payment/split-payments.md + - Extensions: + - AP2 Mandates Extension: specification/payment/extensions/ap2-mandates.md + - Payment Authentication: + - Overview: specification/payment/extensions/authentication.md + - Device Data Collection: + specification/payment/extensions/actions/device-data-collection.md + - 3DS Challenge: + specification/payment/extensions/actions/three-ds-challenge.md + - Payment Terms Extension: specification/payment/extensions/terms.md + - Split Payments Extension: specification/payment/extensions/split-payments.md - Payment Handlers: - Guide: specification/payment/guide.md - Template: specification/payment/template.md @@ -280,26 +281,41 @@ plugins: specification/identity-linking.md: specification/common/identity-linking/index.md # Payment + specification/ap2-mandates.md: + specification/payment/extensions/ap2-mandates.md specification/payment-authentication.md: - specification/payment/authentication.md + specification/payment/extensions/authentication.md specification/payment-handler-guide.md: specification/payment/guide.md specification/payment-handler-template.md: specification/payment/template.md specification/split-payments.md: - specification/payment/split-payments.md + specification/payment/extensions/split-payments.md + specification/payment-terms.md: + specification/payment/extensions/terms.md specification/tokenization-guide.md: specification/payment/tokenization.md specification/payment-actions/device-data-collection.md: - specification/payment/actions/device-data-collection.md + specification/payment/extensions/actions/device-data-collection.md specification/payment-actions/three-ds-challenge.md: - specification/payment/actions/three-ds-challenge.md + specification/payment/extensions/actions/three-ds-challenge.md specification/examples/processor-tokenizer-payment-handler.md: specification/payment/examples/processor-tokenizer-payment-handler.md specification/examples/platform-tokenizer-payment-handler.md: specification/payment/examples/platform-tokenizer-payment-handler.md specification/examples/encrypted-credential-handler.md: specification/payment/examples/encrypted-credential-payment-handler.md + # Payment Extensions: currently-published paths under specification/payment/, + # superseded by the payment/extensions/ subtree. Distinct from the flat + # pre-vertical URLs above, which are also still served. + specification/payment/authentication.md: + specification/payment/extensions/authentication.md + specification/payment/split-payments.md: + specification/payment/extensions/split-payments.md + specification/payment/actions/device-data-collection.md: + specification/payment/extensions/actions/device-data-collection.md + specification/payment/actions/three-ds-challenge.md: + specification/payment/extensions/actions/three-ds-challenge.md # Common Extensions specification/loyalty.md: specification/common/extensions/loyalty.md @@ -411,15 +427,6 @@ plugins: per-session delegation negotiation, URL parameters, native UI event mappings, W3C Payment Request conceptual alignment, and core lifecycle messages. - - specification/ap2-mandates.md: >- - AP2 Mandates Extension, detailing secure, cryptographically bound - checkout commitments (using SD-JWT+kb digital credentials and - detached JWS signatures) between business, platform, and payment - providers. - - specification/payment-terms.md: >- - Payment Terms Extension, enabling checkout payment schedules for - immediate and deferred payments such as deposits, installments, - and lodging balance-at-check-in flows. Cart Capability: - specification/shopping/cart/index.md: >- Pre-purchase Cart Capability, detailing item collection, state @@ -494,19 +501,28 @@ plugins: buyer privacy choices (analytics, marketing, personalization) to assist with privacy compliance (CCPA/GDPR). Payment: - - specification/payment/authentication.md: >- + - specification/payment/extensions/ap2-mandates.md: >- + AP2 Mandates Extension, detailing secure, cryptographically bound + checkout commitments (using SD-JWT+kb digital credentials and + detached JWS signatures) between business, platform, and payment + providers. + - specification/payment/extensions/authentication.md: >- Payment Authentication Extension, defining negotiation, payment-handler association, lifecycle, trust, and embedded notifications for standard payment authentication Actions. - - specification/payment/actions/device-data-collection.md: >- + - specification/payment/extensions/actions/device-data-collection.md: >- Standard Action type for running invisible device-data collection surfaces during payment processing. - - specification/payment/actions/three-ds-challenge.md: >- + - specification/payment/extensions/actions/three-ds-challenge.md: >- Standard Action type for presenting buyer-facing 3DS challenges. - - specification/payment/split-payments.md: >- + - specification/payment/extensions/split-payments.md: >- Split Payments Extension, defining multiple payment instrument allocation, settlement rules, and amount distribution across payment handlers. + - specification/payment/extensions/terms.md: >- + Payment Terms Extension, enabling checkout payment schedules for + immediate and deferred payments such as deposits, installments, + and lodging balance-at-check-in flows. - specification/payment/guide.md: >- Architectural framework and standard vocabulary for specifying UCP payment handlers, covering configuration declarations and diff --git a/scripts/scaffolds/shopping_payment_authentication_response.json b/scripts/scaffolds/common_payment_authentication_response.json similarity index 94% rename from scripts/scaffolds/shopping_payment_authentication_response.json rename to scripts/scaffolds/common_payment_authentication_response.json index 596ad105b..5bc241c1f 100644 --- a/scripts/scaffolds/shopping_payment_authentication_response.json +++ b/scripts/scaffolds/common_payment_authentication_response.json @@ -3,7 +3,7 @@ "version": "2026-01-01", "status": "success", "capabilities": { - "dev.ucp.shopping.payment_authentication": [ + "dev.ucp.common.payment.authentication": [ { "version": "2026-01-01", "extends": "dev.ucp.shopping.checkout" diff --git a/source/handlers/tokenization/openapi.json b/source/handlers/tokenization/openapi.json index 4533baae3..8193b9f2d 100644 --- a/source/handlers/tokenization/openapi.json +++ b/source/handlers/tokenization/openapi.json @@ -20,7 +20,7 @@ "required": ["credential", "binding"], "properties": { "credential": { - "$ref": "../../schemas/shopping/types/payment_credential.json", + "$ref": "../../schemas/common/types/payment_credential.json", "description": "Credential to tokenize. Handlers define accepted credential types in their specification." }, "binding": { @@ -28,7 +28,7 @@ "description": "Resource this token is bound to. Ties the token to a specific capability resource." }, "identity": { - "$ref": "../../schemas/shopping/types/payment_identity.json", + "$ref": "../../schemas/common/types/payment_identity.json", "description": "The participant this token is issued to. Required when acting on behalf of another participant, for example an agent tokenizing for a business. Omit when the authenticated caller is that participant." } } @@ -148,7 +148,7 @@ "description": "Resource binding that must match the original tokenization request." }, "identity": { - "$ref": "../../schemas/shopping/types/payment_identity.json", + "$ref": "../../schemas/common/types/payment_identity.json", "description": "Participant whose token is being retrieved. Required when the caller acts on behalf of another participant; omit when the authenticated caller is that participant." } } @@ -187,7 +187,7 @@ "content": { "application/json": { "schema": { - "$ref": "../../schemas/shopping/types/payment_credential.json" + "$ref": "../../schemas/common/types/payment_credential.json" }, "examples": { "pan_credential": { diff --git a/source/schemas/shopping/ap2_mandate.json b/source/schemas/common/payment_ap2_mandate.json similarity index 93% rename from source/schemas/shopping/ap2_mandate.json rename to source/schemas/common/payment_ap2_mandate.json index 4d8b7d071..c9f5e4333 100644 --- a/source/schemas/shopping/ap2_mandate.json +++ b/source/schemas/common/payment_ap2_mandate.json @@ -1,8 +1,8 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/ap2_mandate.json", - "name": "dev.ucp.shopping.ap2_mandate", - "title": "AP2 Mandate Extension", + "$id": "https://ucp.dev/schemas/common/payment_ap2_mandate.json", + "name": "dev.ucp.common.payment.ap2_mandate", + "title": "Payment AP2 Mandate Extension", "description": "Extends Checkout with cryptographic mandate support for non-repudiable authorization per the AP2 protocol. Uses embedded signature model with ap2 namespace.", "$defs": { "merchant_authorization": { @@ -48,7 +48,7 @@ "description": "Checkout extended with AP2 mandate support.", "allOf": [ { - "$ref": "checkout.json" + "$ref": "../shopping/checkout.json" }, { "type": "object", diff --git a/source/schemas/shopping/payment_authentication.json b/source/schemas/common/payment_authentication.json similarity index 85% rename from source/schemas/shopping/payment_authentication.json rename to source/schemas/common/payment_authentication.json index 6a4ee841f..34c77dc88 100644 --- a/source/schemas/shopping/payment_authentication.json +++ b/source/schemas/common/payment_authentication.json @@ -1,14 +1,14 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/payment_authentication.json", - "name": "dev.ucp.shopping.payment_authentication", + "$id": "https://ucp.dev/schemas/common/payment_authentication.json", + "name": "dev.ucp.common.payment.authentication", "title": "Payment Authentication Extension", - "description": "Extends Checkout with standard device data collection and 3DS challenge Action types used during payment authentication.", + "description": "Extends capabilities (e.g., checkout in retail shopping) with standard device data collection and 3DS challenge Action types used during payment authentication.", "$defs": { "dev.ucp.shopping.checkout": { "allOf": [ { - "$ref": "checkout.json" + "$ref": "../shopping/checkout.json" }, { "type": "object", @@ -17,7 +17,7 @@ "type": "object", "ucp_request": "omit", "properties": { - "dev.ucp.payment.device_data_collection": { + "dev.ucp.common.payment.device_data_collection": { "type": "array", "description": "A 3DS device data collection Action.", "items": { @@ -48,7 +48,7 @@ } } }, - "dev.ucp.payment.three_ds_challenge": { + "dev.ucp.common.payment.three_ds_challenge": { "type": "array", "description": "A 3DS challenge Action.", "items": { diff --git a/source/schemas/shopping/split_payments.json b/source/schemas/common/payment_split_payments.json similarity index 73% rename from source/schemas/shopping/split_payments.json rename to source/schemas/common/payment_split_payments.json index 6e5ec820a..adcb77cef 100644 --- a/source/schemas/shopping/split_payments.json +++ b/source/schemas/common/payment_split_payments.json @@ -1,15 +1,9 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/split_payments.json", - "name": "dev.ucp.shopping.split_payments", - "title": "Split Payments Extension", - "description": "Enables buyers to use multiple payment instruments for a single checkout.", - "requires": { - "protocol": { "min": "2026-01-23" }, - "capabilities": { - "dev.ucp.shopping.checkout": { "min": "2026-01-23" } - } - }, + "$id": "https://ucp.dev/schemas/common/payment_split_payments.json", + "name": "dev.ucp.common.payment.split_payments", + "title": "Payment Split Payments Extension", + "description": "Enables Buyers to use multiple payment instruments for a single session.", "$defs": { "instrument_group": { "$ref": "types/instrument_group.json" @@ -23,8 +17,8 @@ "type": "object", "properties": { "amount": { - "$ref": "../common/types/amount.json", - "description": "Contribution amount for this instrument in `checkout.currency` minor units (ISO 4217). On request: the platform's requested contribution (omit for open-amount). On response: the actual amount authorized or charged (omitted when not finally processed)." + "$ref": "types/amount.json", + "description": "Contribution amount for this instrument expressed in ISO 4217 minor units of the containing capability object's `currency`. On request: the platform's requested contribution (omit for open-amount). On response: the actual amount authorized or charged (omitted when not finally processed)." } } } @@ -34,7 +28,7 @@ "title": "Checkout with Split Payments", "description": "Checkout extended with split payment instrument amounts.", "allOf": [ - { "$ref": "checkout.json" }, + { "$ref": "../shopping/checkout.json" }, { "type": "object", "properties": { @@ -59,7 +53,7 @@ } ] }, - "dev.ucp.shopping.split_payments": { + "dev.ucp.common.payment.split_payments": { "business_schema": { "title": "Split Payments Capability (Business)", "description": "Business-level split payments capability configuration.", diff --git a/source/schemas/shopping/payment_terms.json b/source/schemas/common/payment_terms.json similarity index 84% rename from source/schemas/shopping/payment_terms.json rename to source/schemas/common/payment_terms.json index 034116460..f5e246d78 100644 --- a/source/schemas/shopping/payment_terms.json +++ b/source/schemas/common/payment_terms.json @@ -1,16 +1,9 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/payment_terms.json", - "name": "dev.ucp.shopping.payment_terms", + "$id": "https://ucp.dev/schemas/common/payment_terms.json", + "name": "dev.ucp.common.payment.terms", "title": "Payment Terms Extension", - "description": "Extends Checkout with selectable payment terms, letting a Business offer alternative schedules for when payment for the checkout is due, and projects the accepted term onto the resulting Order.", - "requires": { - "protocol": { "min": "2026-04-08" }, - "capabilities": { - "dev.ucp.shopping.checkout": { "min": "2026-04-08" }, - "dev.ucp.shopping.order": { "min": "2026-04-08" } - } - }, + "description": "Extends capabilities (e.g., checkout in retail shopping) with selectable payment terms, letting a Business offer alternative schedules for when payment for the checkout is due, and projects the accepted term onto the resulting Order.", "$defs": { "payment_term": { "$ref": "types/payment_term.json" @@ -54,7 +47,7 @@ "title": "Checkout with Payment Terms", "description": "Checkout extended with selectable payment terms.", "allOf": [ - { "$ref": "checkout.json" }, + { "$ref": "../shopping/checkout.json" }, { "type": "object", "properties": { @@ -75,7 +68,7 @@ "title": "Order with Accepted Payment Term", "description": "Order extended with the payment term accepted at checkout.", "allOf": [ - { "$ref": "order.json" }, + { "$ref": "../shopping/order.json" }, { "type": "object", "properties": { diff --git a/source/schemas/shopping/types/available_payment_instrument.json b/source/schemas/common/types/available_payment_instrument.json similarity index 83% rename from source/schemas/shopping/types/available_payment_instrument.json rename to source/schemas/common/types/available_payment_instrument.json index 9bb8b2c76..088e15edb 100644 --- a/source/schemas/shopping/types/available_payment_instrument.json +++ b/source/schemas/common/types/available_payment_instrument.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/available_payment_instrument.json", + "$id": "https://ucp.dev/schemas/common/types/available_payment_instrument.json", "title": "Available Payment Instrument", "description": "An instrument type available from a payment handler with optional constraints.", "type": "object", @@ -11,7 +11,7 @@ "description": "The instrument type identifier (e.g., 'card', 'gift_card'). References an instrument schema's type constant." }, "constraints": { - "$ref": "../../common/types/constraint_expression.json", + "$ref": "constraint_expression.json", "description": "A Constraint Expression describing the instrument this entry makes available. Keys in `properties` name members of the `constraint_target` declared by the instrument schema for this `type`. Requirements on submitted request data belong in `ucp.request_constraints` instead." } } diff --git a/source/schemas/shopping/types/business_split_payments_config.json b/source/schemas/common/types/business_split_payments_config.json similarity index 91% rename from source/schemas/shopping/types/business_split_payments_config.json rename to source/schemas/common/types/business_split_payments_config.json index 72eaed048..c70239f43 100644 --- a/source/schemas/shopping/types/business_split_payments_config.json +++ b/source/schemas/common/types/business_split_payments_config.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/business_split_payments_config.json", + "$id": "https://ucp.dev/schemas/common/types/business_split_payments_config.json", "title": "Business Split Payments Config", "description": "Business-level configuration for split payments. Declaring the capability means multiple payment instruments are supported; this config declares which combinations are valid.", "type": "object", diff --git a/source/schemas/shopping/types/card_credential.json b/source/schemas/common/types/card_credential.json similarity index 97% rename from source/schemas/shopping/types/card_credential.json rename to source/schemas/common/types/card_credential.json index 4c87b1077..16eb8f7c5 100644 --- a/source/schemas/shopping/types/card_credential.json +++ b/source/schemas/common/types/card_credential.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/card_credential.json", + "$id": "https://ucp.dev/schemas/common/types/card_credential.json", "title": "Card Credential", "description": "Deprecated: use PAN Credential (`pan_credential.json`) or Network Token Credential (`network_token_credential.json`). 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.", "deprecated": true, diff --git a/source/schemas/shopping/types/card_payment_instrument.json b/source/schemas/common/types/card_payment_instrument.json similarity index 97% rename from source/schemas/shopping/types/card_payment_instrument.json rename to source/schemas/common/types/card_payment_instrument.json index 099ceba4b..cf35f228b 100644 --- a/source/schemas/shopping/types/card_payment_instrument.json +++ b/source/schemas/common/types/card_payment_instrument.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/card_payment_instrument.json", + "$id": "https://ucp.dev/schemas/common/types/card_payment_instrument.json", "title": "Card Payment Instrument", "description": "A basic card payment instrument with visible card details. Can be inherited by a handler's instrument schema to define handler-specific display details or more complex credential structures.", "$defs": { diff --git a/source/schemas/shopping/types/instrument_group.json b/source/schemas/common/types/instrument_group.json similarity index 92% rename from source/schemas/shopping/types/instrument_group.json rename to source/schemas/common/types/instrument_group.json index 8501de66c..f6a558240 100644 --- a/source/schemas/shopping/types/instrument_group.json +++ b/source/schemas/common/types/instrument_group.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/instrument_group.json", + "$id": "https://ucp.dev/schemas/common/types/instrument_group.json", "title": "Instrument Group", "description": "A constraint within an allowed combination that defines which instrument types can fill this group and how many are permitted.", "type": "object", diff --git a/source/schemas/shopping/types/network_token_credential.json b/source/schemas/common/types/network_token_credential.json similarity index 96% rename from source/schemas/shopping/types/network_token_credential.json rename to source/schemas/common/types/network_token_credential.json index 02075a3ad..0f398373c 100644 --- a/source/schemas/shopping/types/network_token_credential.json +++ b/source/schemas/common/types/network_token_credential.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/network_token_credential.json", + "$id": "https://ucp.dev/schemas/common/types/network_token_credential.json", "title": "Network Token Credential", "description": "A card-network token credential verified with a transaction cryptogram. The `number` field carries the network token or wallet-provisioned token rather than the underlying FPAN.", "allOf": [ diff --git a/source/schemas/shopping/types/pan_credential.json b/source/schemas/common/types/pan_credential.json similarity index 70% rename from source/schemas/shopping/types/pan_credential.json rename to source/schemas/common/types/pan_credential.json index b392ee522..8642b47e3 100644 --- a/source/schemas/shopping/types/pan_credential.json +++ b/source/schemas/common/types/pan_credential.json @@ -1,8 +1,8 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/pan_credential.json", + "$id": "https://ucp.dev/schemas/common/types/pan_credential.json", "title": "PAN Credential", - "description": "A card credential carrying a funding primary account number (FPAN). Credential selection follows the shape of the value on the wire rather than its provenance: a network token surfaced in PAN form and verified with a `cvc` \u2014 as with credentials where a dynamic verification code proxies the cryptogram \u2014 is carried here, while a token verified with a discrete `cryptogram` uses Network Token Credential. This credential type MUST NOT be used for checkout, only with payment handlers that tokenize or encrypt credentials. CRITICAL: Both parties handling a PAN credential (sender and receiver) MUST be PCI DSS compliant. Transmission MUST use HTTPS/TLS with strong cipher suites.", + "description": "A card credential carrying a funding primary account number (FPAN). Credential selection follows the shape of the value on the wire rather than its provenance: a network token surfaced in PAN form and verified with a `cvc` - as with credentials where a dynamic verification code proxies the cryptogram - is carried here, while a token verified with a discrete `cryptogram` uses Network Token Credential. This credential type MUST NOT be used for checkout, only with payment handlers that tokenize or encrypt credentials. CRITICAL: Both parties handling a PAN credential (sender and receiver) MUST be PCI DSS compliant. Transmission MUST use HTTPS/TLS with strong cipher suites.", "allOf": [ { "$ref": "payment_credential.json" diff --git a/source/schemas/shopping/payment.json b/source/schemas/common/types/payment.json similarity index 78% rename from source/schemas/shopping/payment.json rename to source/schemas/common/types/payment.json index e572e0646..088e859ff 100644 --- a/source/schemas/shopping/payment.json +++ b/source/schemas/common/types/payment.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/payment.json", + "$id": "https://ucp.dev/schemas/common/types/payment.json", "title": "Payment", "description": "Payment configuration containing handlers.", "type": "object", @@ -8,7 +8,7 @@ "instruments": { "type": "array", "items": { - "$ref": "types/payment_instrument.json#/$defs/selected_payment_instrument" + "$ref": "payment_instrument.json#/$defs/selected_payment_instrument" }, "description": "The payment instruments available for this payment. Each instrument is associated with a specific handler via the handler_id field. Handlers can extend the base payment_instrument schema to add handler-specific fields." } diff --git a/source/schemas/shopping/types/payment_credential.json b/source/schemas/common/types/payment_credential.json similarity index 86% rename from source/schemas/shopping/types/payment_credential.json rename to source/schemas/common/types/payment_credential.json index d7be3a0a8..c60e7be49 100644 --- a/source/schemas/shopping/types/payment_credential.json +++ b/source/schemas/common/types/payment_credential.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/payment_credential.json", + "$id": "https://ucp.dev/schemas/common/types/payment_credential.json", "title": "Payment Credential", "description": "The base definition for any payment credential. Handlers define specific credential types.", "type": "object", diff --git a/source/schemas/shopping/types/payment_identity.json b/source/schemas/common/types/payment_identity.json similarity index 86% rename from source/schemas/shopping/types/payment_identity.json rename to source/schemas/common/types/payment_identity.json index 267d3688b..b7b90d1bf 100644 --- a/source/schemas/shopping/types/payment_identity.json +++ b/source/schemas/common/types/payment_identity.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/payment_identity.json", + "$id": "https://ucp.dev/schemas/common/types/payment_identity.json", "title": "Payment Identity", "description": "Identity of a participant for token binding. The access_token uniquely identifies the participant whom tokens should be issued to.", "type": "object", diff --git a/source/schemas/shopping/types/payment_instrument.json b/source/schemas/common/types/payment_instrument.json similarity index 94% rename from source/schemas/shopping/types/payment_instrument.json rename to source/schemas/common/types/payment_instrument.json index 4955d2924..830188577 100644 --- a/source/schemas/shopping/types/payment_instrument.json +++ b/source/schemas/common/types/payment_instrument.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/payment_instrument.json", + "$id": "https://ucp.dev/schemas/common/types/payment_instrument.json", "title": "Payment Instrument", "description": "The base definition for any payment instrument. It links the instrument to a specific payment handler.", "type": "object", @@ -23,7 +23,7 @@ "description": "The broad category of the instrument (e.g., 'card', 'tokenized_card'). Specific schemas will constrain this to a constant value." }, "billing_address": { - "$ref": "../../common/types/postal_address.json", + "$ref": "postal_address.json", "description": "The billing address associated with this payment method." }, "credential": { diff --git a/source/schemas/shopping/types/payment_schedule.json b/source/schemas/common/types/payment_schedule.json similarity index 93% rename from source/schemas/shopping/types/payment_schedule.json rename to source/schemas/common/types/payment_schedule.json index e9bd6ca6f..262ecea96 100644 --- a/source/schemas/shopping/types/payment_schedule.json +++ b/source/schemas/common/types/payment_schedule.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/payment_schedule.json", + "$id": "https://ucp.dev/schemas/common/types/payment_schedule.json", "title": "Payment Schedule", "description": "A single payment that settles part or all of the checkout under a payment term. Timing is stated in buyer-facing text; `type` and `due_at` are supplementary machine-readable signals derived from it.", "type": "object", @@ -21,7 +21,7 @@ "description": "Timing class, drawn from an open vocabulary. `immediate` is the only value with defined meaning: the payment is due when the checkout is completed. Any other value means the payment is not due at completion, and `description` states when it is due. Whether a due payment is authorized, captured, or settled at that moment is payment-handler behavior and outside this extension. Businesses MAY use additional values (e.g. `deferred`, `on_shipment`); Platforms MUST treat unrecognized values as not due at completion." }, "description": { - "$ref": "../../common/types/description.json", + "$ref": "description.json", "description": "Complete buyer-facing statement of when and how this payment is due. Businesses MUST make this field sufficient on its own: a Platform that recognizes no `type` value and reads no other field MUST be able to present this schedule correctly. Platforms MAY use `type` and `due_at` for enhanced presentation, but MUST NOT present derived timing that contradicts this field." }, "due_at": { @@ -30,7 +30,7 @@ "description": "Absolute RFC 3339 date-time when this payment is due, when the Business can determine one at checkout. Supplementary to `description`, never a replacement for it. Omitted when the due date depends on a future event (e.g. 'due on delivery'); the timing is then stated in `description` alone." }, "amount": { - "$ref": "../../common/types/amount.json", + "$ref": "amount.json", "description": "The amount charged when this payment is taken, inclusive of tax and every other charge, in the Checkout currency's minor units (ISO 4217). A schedule states an amount rather than a totals breakdown: the purchase is priced once at the Checkout, and a schedule moves part or all of that price. Where the selected term changes what the purchase costs, that difference appears in `checkout.totals`, not here." } } diff --git a/source/schemas/shopping/types/payment_term.json b/source/schemas/common/types/payment_term.json similarity index 90% rename from source/schemas/shopping/types/payment_term.json rename to source/schemas/common/types/payment_term.json index 372883ca1..efb25f8d0 100644 --- a/source/schemas/shopping/types/payment_term.json +++ b/source/schemas/common/types/payment_term.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/payment_term.json", + "$id": "https://ucp.dev/schemas/common/types/payment_term.json", "title": "Payment Term", "description": "A way of paying for the checkout: one or more payment schedules that together cover its total.", "type": "object", @@ -20,7 +20,7 @@ "description": "Short label that distinguishes this term from its siblings (e.g. 'Pay now', 'Pay in 4', 'Deposit + balance at check-in')." }, "description": { - "$ref": "../../common/types/description.json", + "$ref": "description.json", "description": "Supplementary context for the title (e.g. 'Save 5% by paying today'). Directly renderable; MUST NOT repeat the title." }, "schedules": { diff --git a/source/schemas/shopping/types/token_credential.json b/source/schemas/common/types/token_credential.json similarity index 90% rename from source/schemas/shopping/types/token_credential.json rename to source/schemas/common/types/token_credential.json index aa0cde381..c338e37e1 100644 --- a/source/schemas/shopping/types/token_credential.json +++ b/source/schemas/common/types/token_credential.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ucp.dev/schemas/shopping/types/token_credential.json", + "$id": "https://ucp.dev/schemas/common/types/token_credential.json", "title": "Token Credential", "description": "Base token credential schema. Concrete payment handlers may extend this schema with additional fields and define their own constraints.", "allOf": [ diff --git a/source/schemas/payment_handler.json b/source/schemas/payment_handler.json index 205a8ef76..14ce296e6 100644 --- a/source/schemas/payment_handler.json +++ b/source/schemas/payment_handler.json @@ -17,7 +17,7 @@ "properties": { "available_instruments": { "type": "array", - "items": { "$ref": "shopping/types/available_payment_instrument.json" }, + "items": { "$ref": "common/types/available_payment_instrument.json" }, "description": "Instrument types this handler supports, with optional constraints. When absent, every instrument should be considered available.", "minItems": 1 } diff --git a/source/schemas/shopping/checkout.json b/source/schemas/shopping/checkout.json index 56e889eb5..983e42972 100644 --- a/source/schemas/shopping/checkout.json +++ b/source/schemas/shopping/checkout.json @@ -127,7 +127,7 @@ "ucp_request": "omit" }, "payment": { - "$ref": "payment.json", + "$ref": "../common/types/payment.json", "ucp_request": { "create": "optional", "update": "optional", diff --git a/source/services/shopping/embedded.openrpc.json b/source/services/shopping/embedded.openrpc.json index d9f8a78c2..888347558 100644 --- a/source/services/shopping/embedded.openrpc.json +++ b/source/services/shopping/embedded.openrpc.json @@ -560,7 +560,7 @@ "instruments": { "type": "array", "items": { - "$ref": "../../schemas/shopping/types/payment_instrument.json#/$defs/selected_payment_instrument" + "$ref": "../../schemas/common/types/payment_instrument.json#/$defs/selected_payment_instrument" }, "description": "Available payment instruments." } diff --git a/source/services/shopping/rest.openapi.json b/source/services/shopping/rest.openapi.json index cc28e6a0a..7d6286607 100644 --- a/source/services/shopping/rest.openapi.json +++ b/source/services/shopping/rest.openapi.json @@ -996,7 +996,7 @@ ] }, "payment": { - "$ref": "../../schemas/shopping/payment.json" + "$ref": "../../schemas/common/types/payment.json" }, "ucp": { "$ref": "../../schemas/ucp.json"