|
| 1 | +<!-- |
| 2 | + Copyright 2026 UCP Authors |
| 3 | +
|
| 4 | + Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + you may not use this file except in compliance with the License. |
| 6 | + You may obtain a copy of the License at |
| 7 | +
|
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | + Unless required by applicable law or agreed to in writing, software |
| 11 | + distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + See the License for the specific language governing permissions and |
| 14 | + limitations under the License. |
| 15 | +--> |
| 16 | + |
| 17 | +# Payment Device Data Collection Action |
| 18 | + |
| 19 | +This specification defines the device data collection Action type declared by |
| 20 | +the [Payment Authentication extension](../payment-authentication.md): |
| 21 | + |
| 22 | +```text |
| 23 | +dev.ucp.payment.device_data_collection |
| 24 | +``` |
| 25 | + |
| 26 | +It asks the Platform to run a scoped, invisible browser-capable surface associated |
| 27 | +with a payment instrument or attempt. |
| 28 | + |
| 29 | +## Purpose and Scope |
| 30 | + |
| 31 | +Device data collection lets a Business, payment handler, PSP, or 3DS provider |
| 32 | +collect device or browser data before payment processing continues. UCP does not |
| 33 | +carry the collected data. The loaded surface sends provider-specific data directly |
| 34 | +to the Business or payment provider through its own integration. |
| 35 | + |
| 36 | +For EMV 3DS, this Action represents only the Platform-facing instruction to |
| 37 | +mount the collection surface. UCP does not define how a Business maps ACS method |
| 38 | +availability, method timeouts, or collection outcomes into EMVCo state such as |
| 39 | +`threeDSCompInd`. If a provider or Business skips collection, including when an |
| 40 | +ACS supplies no method URL, the Business does not emit this Action. |
| 41 | + |
| 42 | +## Emission and Gated Effect |
| 43 | + |
| 44 | +A Business **MAY** emit this type from a Create, Update, or Complete Checkout |
| 45 | +response after it can associate collection with a payment instrument and |
| 46 | +negotiated payment handler. `config.payment_instrument_id` identifies that |
| 47 | +instrument. |
| 48 | + |
| 49 | +The Action gates advancement of the associated payment attempt while the |
| 50 | +occurrence remains outstanding in the authoritative Checkout. A terminal surface |
| 51 | +event starts reconciliation; it does not itself lift the gate or assert that |
| 52 | +collection succeeded. If collection is merely an optimization that the Business |
| 53 | +will not wait for, the Business **MUST NOT** emit an Action. |
| 54 | + |
| 55 | +## Runtime Shape |
| 56 | + |
| 57 | +The Action is emitted under its type key: |
| 58 | + |
| 59 | +<!-- ucp:example schema=shopping/payment_authentication def=dev.ucp.shopping.checkout extract=$.actions target=$.actions op=read --> |
| 60 | +```json |
| 61 | +{ |
| 62 | + "actions": { |
| 63 | + "dev.ucp.payment.device_data_collection": [ |
| 64 | + { |
| 65 | + "id": "ddc-1", |
| 66 | + "config": { |
| 67 | + "payment_instrument_id": "instrument_1", |
| 68 | + "url": "https://payments.example.com/ucp/payment/ddc/session_123" |
| 69 | + } |
| 70 | + } |
| 71 | + ] |
| 72 | + } |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +The config shape is defined inline by the |
| 77 | +[Payment Authentication extension schema](site:schemas/shopping/payment_authentication.json). |
| 78 | + |
| 79 | +| Field | Type | Required | Notes | |
| 80 | +| :---- | :--- | :------- | :---- | |
| 81 | +| `payment_instrument_id` | string | ✓ | ID of the associated instrument in the containing Checkout. | |
| 82 | +| `url` | string | ✓ | Absolute HTTPS URL for the invisible collection surface. | |
| 83 | + |
| 84 | +The Business **SHOULD** provide a Business- or provider-operated wrapper URL that |
| 85 | +owns any provider-specific POST, such as posting `threeDSMethodData` to an ACS |
| 86 | +method URL. The Platform performs an ordinary navigation to `config.url`. |
| 87 | + |
| 88 | +## Platform Behavior |
| 89 | + |
| 90 | +The Platform **MUST**: |
| 91 | + |
| 92 | +1. validate the URL according to the Payment Authentication contract, the |
| 93 | + payment handler and instrument context, and Platform policy; |
| 94 | +2. load the URL in an isolated, invisible browser-capable surface; |
| 95 | +3. complete the `action.ready` handshake before allowing collection to begin; |
| 96 | +4. correlate embedded notifications with both this Action occurrence and the |
| 97 | + mounted surface; and |
| 98 | +5. unmount the surface after `action.done`, `action.error`, load failure, or |
| 99 | + timeout. |
| 100 | + |
| 101 | +Mounting the surface **MUST** follow the shared |
| 102 | +[Payment Authentication rendering contract](../payment-authentication.md#surface-rendering-and-notifications) |
| 103 | +and [Embedded Protocol security requirements](../embedded-protocol.md#security). |
| 104 | + |
| 105 | +On the web the surface is typically a hidden iframe. A native Platform may use |
| 106 | +an isolated webview or equivalent browser surface. It must not be visible to the |
| 107 | +Buyer or request Buyer interaction. |
| 108 | + |
| 109 | +The Platform distinguishes only whether its surface finished or could not |
| 110 | +continue. It does not determine whether device data was collected successfully, |
| 111 | +whether an ACS method timed out, or whether 3DS authentication should proceed. |
| 112 | + |
| 113 | +## Embedded Notifications |
| 114 | + |
| 115 | +After completing the shared |
| 116 | +[`action.ready` handshake](../payment-authentication.md#ready-handshake), the |
| 117 | +surface sends JSON-RPC 2.0 notifications defined by the |
| 118 | +[payment Action embedded contract](../payment-authentication.md#surface-rendering-and-notifications). |
| 119 | + |
| 120 | +### Done |
| 121 | + |
| 122 | +When the Platform-facing collection step is finished, the surface **MUST** send: |
| 123 | + |
| 124 | +<!-- ucp:example schema=transports/jsonrpc def=request op=read --> |
| 125 | +```json |
| 126 | +{ |
| 127 | + "jsonrpc": "2.0", |
| 128 | + "method": "action.done", |
| 129 | + "params": { |
| 130 | + "id": "ddc-1" |
| 131 | + } |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +The surface may send `action.done` when handler-owned logic determines that the |
| 136 | +Platform should close the surface. The notification does not reveal whether |
| 137 | +collection succeeded, was unavailable, was skipped, or mapped to a particular |
| 138 | +provider completion indicator. |
| 139 | + |
| 140 | +### Error |
| 141 | + |
| 142 | +If the surface cannot continue from the Platform-facing transport perspective, |
| 143 | +it **MAY** send: |
| 144 | + |
| 145 | +<!-- ucp:example schema=transports/jsonrpc def=request op=read --> |
| 146 | +```json |
| 147 | +{ |
| 148 | + "jsonrpc": "2.0", |
| 149 | + "method": "action.error", |
| 150 | + "params": { |
| 151 | + "id": "ddc-1", |
| 152 | + "error": { |
| 153 | + "ucp": { "version": "{{ ucp_version }}", "status": "error" }, |
| 154 | + "messages": [ |
| 155 | + { |
| 156 | + "type": "error", |
| 157 | + "code": "action_unavailable", |
| 158 | + "content": "Device data collection could not start.", |
| 159 | + "severity": "recoverable" |
| 160 | + } |
| 161 | + ] |
| 162 | + } |
| 163 | + } |
| 164 | +} |
| 165 | +``` |
| 166 | + |
| 167 | +Recommended surface-level codes are `action_unavailable` when initialization |
| 168 | +fails, `action_expired` when the surface's session expired, and `action_failed` |
| 169 | +for another terminal surface error. These are diagnostic codes, not EMV 3DS or |
| 170 | +payment outcomes. A provider-domain timeout or unavailable method that the |
| 171 | +handler can safely continue past should normally result in `action.done`, with |
| 172 | +the Business and provider recording the domain outcome server-side. After either |
| 173 | +notification, the Platform follows the shared Payment Authentication |
| 174 | +reconciliation contract. |
| 175 | + |
| 176 | +## Deadline and Fallback |
| 177 | + |
| 178 | +[EMV 3-D Secure Protocol and Core Functions v2.3.1.1](https://www.emvco.com/specifications/emv-3-d-secure-protocol-and-core-functions-specification-6/){ target="_blank" } |
| 179 | +requires the 3DS Server to set `threeDSCompInd` to `N` when the 3DS Method does |
| 180 | +not complete within five seconds (Req 315). That provider-domain timer begins |
| 181 | +when the method is invoked and remains owned by the Business and provider; the |
| 182 | +Platform **MUST NOT** derive it from the outer surface's load event. |
| 183 | + |
| 184 | +The Platform applies a bounded outer-surface deadline defined by the handler or |
| 185 | +Platform policy, measured from navigation and capped by Checkout `expires_at`. |
| 186 | +That deadline controls only how long the Platform keeps the UCP surface mounted; |
| 187 | +it does not set `threeDSCompInd` or another provider outcome. |
| 188 | + |
| 189 | +If no valid `action.done` or `action.error` arrives before the outer deadline, |
| 190 | +the Platform **MUST** unmount the surface, treat the interaction as timed out, |
| 191 | +and follow the non-successful surface reconciliation path. It may unmount sooner |
| 192 | +after load failure or a valid terminal notification. The Platform **MUST NOT** |
| 193 | +remount the same Action type and `id`; an unchanged occurrence follows the |
| 194 | +parent Checkout Actions fallback, handoff, and cancellation rules. |
| 195 | + |
| 196 | +## Security |
| 197 | + |
| 198 | +The common [Payment Authentication security requirements](../payment-authentication.md#security-and-data-handling) |
| 199 | +apply. In addition: |
| 200 | + |
| 201 | +- The handler's trust policy **MUST** authorize the initial and redirect origins |
| 202 | + before the Platform loads them. |
| 203 | +- The surface **MUST NOT** receive Platform credentials or access Platform |
| 204 | + storage. |
| 205 | +- Provider payloads and collected device data **MUST NOT** be copied into the |
| 206 | + Action, notification params, Checkout, or payment instrument. |
| 207 | +- `action.done` and `action.error` are advisory surface signals. A later |
| 208 | + Checkout response, based on Business/provider state, remains authoritative. |
0 commit comments