@agent-cards/checkout 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/PREFLIGHT.md +294 -0
  3. package/README.md +16 -3
  4. package/dist/braintree.d.ts +2 -10
  5. package/dist/braintree.generated.d.ts +10 -0
  6. package/dist/braintree.generated.js +302 -0
  7. package/dist/braintree.js +2 -302
  8. package/dist/builtin-registry.generated.d.ts +2 -0
  9. package/dist/builtin-registry.generated.js +1 -0
  10. package/dist/cdp.d.ts +4 -2
  11. package/dist/cdp.js +38 -6
  12. package/dist/client.d.ts +13 -4
  13. package/dist/client.js +80 -8
  14. package/dist/index.d.ts +1 -1
  15. package/dist/lifecycle.d.ts +1 -0
  16. package/dist/lifecycle.js +27 -1
  17. package/dist/owned-shop.generated.d.ts +24 -0
  18. package/dist/owned-shop.generated.js +108 -0
  19. package/dist/playwright.d.ts +3 -0
  20. package/dist/playwright.js +3 -0
  21. package/dist/preflight-capabilities.generated.d.ts +1165 -0
  22. package/dist/preflight-capabilities.generated.js +1799 -0
  23. package/dist/preflight-catalog.json +3892 -0
  24. package/dist/preflight-playwright.d.ts +34 -0
  25. package/dist/preflight-playwright.js +262 -0
  26. package/dist/preflight-schemas.json +1063 -0
  27. package/dist/preflight.d.ts +1 -0
  28. package/dist/preflight.generated.d.ts +1867 -0
  29. package/dist/preflight.generated.js +482 -0
  30. package/dist/preflight.js +2 -0
  31. package/dist/registry.d.ts +2 -19
  32. package/dist/registry.js +3 -188
  33. package/dist/substitute.d.ts +5 -9
  34. package/dist/substitute.js +5 -69
  35. package/dist/substitutions.generated.d.ts +10 -0
  36. package/dist/substitutions.generated.js +66 -0
  37. package/examples/preflight/classify-direct.mjs +21 -0
  38. package/examples/preflight/classify-kernel.mjs +30 -0
  39. package/examples/preflight/inspect-browser.mjs +44 -0
  40. package/examples/preflight/kernel-profile.empty.json +11 -0
  41. package/examples/preflight/mollie-hosted.observations.json +23 -0
  42. package/examples/preflight/mollie-hosted.result.json +103 -0
  43. package/examples/preflight/stripe-script.direct.result.json +92 -0
  44. package/examples/preflight/stripe-script.observations.json +16 -0
  45. package/examples/preflight/stripe-script.result.json +87 -0
  46. package/package.json +16 -7
package/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.9.0
4
+
5
+ - Inspect checkout assets before entering card details with `collectCheckoutSignals` and `inspectCheckout`, or assess sanitized observations with `assessCheckoutSupport`. Results identify the PSP, retain evidence and report `supported`, `unsupported` or `unknown` for the selected integration.
6
+ - Build a Kernel native integration against exported JSON schemas, a versioned capability profile and runnable local examples before deployment. Missing native capabilities remain `unknown`; direct SDK coverage does not establish native coverage.
7
+ - Detect all 23 registered PSPs and report processor implementation support separately from checkout-flow identification. `support_scope` states what `status` covers; `checkout_flow_status` preserves unknown or ambiguous flow evidence. The bundled profile covers one-time processor requests, while flow-specific support requires matching evidence.
8
+ - Keep inspection advisory and read-only. Known payment-format exclusions and integration-specific limitations remain visible. Existing authorization and payment request checks still apply; the helper does not establish merchant purchase success.
9
+
10
+ ## 0.8.0
11
+
12
+ - Clear an earlier failure or authentication reason when the merchant confirms a completed order. The final checkout state retains the authorization, order and payment mode without carrying a stale error.
13
+
14
+ - Pass execution routing metadata through authorization and browser attachment with `executionMode`, `grantId` and `merchantOrigin`. The exported `ExecutionMetadata` type describes the result; the matching API and Vault determine whether the user approves the purchase or an existing grant applies. Autopilot execution remains limited to the configured controlled Stripe test flow, with production Autopilot disabled.
15
+ - Share generated processor metadata with the payment core while keeping the published SDK free of runtime package dependencies.
16
+
17
+ ## 0.7.0
4
18
 
5
19
  - A company can put rules on the Vault purchases it chooses (a merchant list, a currency, a spend cap, a time window) by attaching a named preset to a stored card. A purchase the rules refuse now surfaces as `PresetRefusedError`, a typed decline: at stage `create` no authorization exists and nobody was asked; at stage `pre_replay` the authorization is `declined` with the rule's reason. It carries `code`, `presetName`, `rule`, `preset`, `attachment` (the card with its last four digits) and the rule's own statement; when several presets refuse the same purchase, `refusals` names every one and the other fields are the first. The adapters quiet the page's retry as for any decline, and a create-time refusal is never treated as a permanent misconfiguration.
6
20
  - Requires the matching API and Vault release.
package/PREFLIGHT.md ADDED
@@ -0,0 +1,294 @@
1
+ # Check checkout support
2
+
3
+ Inspect a loaded checkout before entering card details or submitting payment. The preflight helper identifies payment processors from page assets and reports what the selected integration can support. Each result distinguishes processor support from an identified checkout flow, so your agent can show the available integration without promising a successful purchase.
4
+
5
+ The helper works locally without Agentcard credentials or an approval. The classifier makes no network requests. The browser collector reads checkout assets without filling fields, clicking Pay, or installing payment interception.
6
+
7
+ ## Install checkout inspection
8
+
9
+ Use Node.js 22 or later. Install `@agent-cards/checkout@0.9.0` in a separate project:
10
+
11
+ ```bash
12
+ mkdir checkout-preflight-example
13
+ cd checkout-preflight-example
14
+ npm init -y
15
+ npm install --save-exact @agent-cards/checkout@0.9.0
16
+ node node_modules/@agent-cards/checkout/examples/preflight/classify-kernel.mjs
17
+ ```
18
+
19
+ The example identifies a Stripe script and returns `unknown` for Kernel native. The included native profile has no capability entries. No deployment, Agentcard account, card, or merchant account is needed.
20
+
21
+ Compare the same observation against the direct SDK:
22
+
23
+ ```bash
24
+ node node_modules/@agent-cards/checkout/examples/preflight/classify-direct.mjs
25
+ ```
26
+
27
+ The direct example returns `supported` with `support_scope: "processor_integration"` and `checkout_flow_status: "unknown"`. The result means the SDK implements Stripe card requests; the observed script has not established which Stripe checkout flow the merchant uses. The [recorded direct result](./examples/preflight/stripe-script.direct.result.json) comes from running the example against the built package.
28
+
29
+ The package includes `PREFLIGHT.md`, runnable examples, TypeScript declarations, and JSON contract files:
30
+
31
+ | Package export | Contents |
32
+ | --- | --- |
33
+ | `@agent-cards/checkout/preflight` | Browser-independent normalization and assessment functions. |
34
+ | `@agent-cards/checkout/playwright` | Read-only collection and inspection functions, plus the existing Playwright exports. |
35
+ | `@agent-cards/checkout/preflight/catalog.json` | Versioned detection rules, processor capabilities, flow capabilities, and exclusions. |
36
+ | `@agent-cards/checkout/preflight/schemas.json` | JSON schemas for observations, snapshots, capability profiles, options, and results. |
37
+
38
+ ## Build a local preview
39
+
40
+ For an unpublished change, build an optional preview archive from its source checkout:
41
+
42
+ ```bash
43
+ cd apps/agent-cards/packages/checkout
44
+ npm run pack:preview -- --out /tmp/checkout-preflight-preview
45
+ ```
46
+
47
+ The packaging command rebuilds the SDK and refuses uncommitted changes by default. Add `--allow-dirty` only when testing a local working copy; the manifest marks that archive accordingly. The command packages files locally and does not publish to npm or deploy a service.
48
+
49
+ Install the resulting archive in your test project. Replace the path below with the archive's actual location:
50
+
51
+ ```bash
52
+ npm install --save-exact /absolute/path/to/agent-cards-checkout-preview.tgz
53
+ ```
54
+
55
+ Retain the archive and its `preview-manifest.json`. The manifest records its source commit, archive checksum, and whether it includes uncommitted changes. A local preview is not a production release. Share the archive and manifest directly when the recipient cannot access the repository's build artifacts.
56
+
57
+ ## Use your own observations
58
+
59
+ Kernel can keep its existing browser inspection and feed asset observations to the classifier. The pure JSON example runs with its included fixture, or accepts observation and profile file paths followed by the actual adapter version:
60
+
61
+ ```bash
62
+ node node_modules/@agent-cards/checkout/examples/preflight/classify-kernel.mjs observations.json kernel-profile.json kernel-adapter-1
63
+ ```
64
+
65
+ Use the functions directly from JavaScript:
66
+
67
+ ```js
68
+ import {
69
+ normalizeCheckoutSignals,
70
+ assessCheckoutSupport,
71
+ } from '@agent-cards/checkout/preflight';
72
+
73
+ const snapshot = normalizeCheckoutSignals(observations);
74
+ const result = assessCheckoutSupport(snapshot, {
75
+ scenario: 'one_time',
76
+ integration: { id: 'kernel_native', version: adapterVersion },
77
+ profile: kernelProfile,
78
+ });
79
+ ```
80
+
81
+ Pass the adapter version from the running integration, separately from the profile. The version comparison cannot detect an outdated profile if the caller copies the profile's version into the runtime options without checking the actual adapter.
82
+
83
+ The included [raw observations](./examples/preflight/stripe-script.observations.json) are synthetic input. The included [recorded result](./examples/preflight/stripe-script.result.json) comes from running the example against the built package. The query string in the input is absent from the normalized snapshot and result.
84
+
85
+ The [Mollie fixture](./examples/preflight/mollie-hosted.observations.json) identifies an active hosted Components page. Its [recorded native result](./examples/preflight/mollie-hosted.result.json) still returns `unknown` with `integration_flow_undeclared` because the native profile has no entry for that flow.
86
+
87
+ | Observation field | Meaning |
88
+ | --- | --- |
89
+ | `signals[].kind` | `document`, `frame`, `script`, `iframe`, or `form`. |
90
+ | `signals[].url` | The observed document or asset location; normalize locally before sharing or logging. |
91
+ | `signals[].frame_id` | A stable integer for the containing frame during this scan. Use `0` for the top document. |
92
+ | `signals[].parent_frame_id` | The parent frame's identifier, or `null` for the top document. |
93
+ | `signals[].visible` | `true`, `false`, or `null` when visibility is undetermined. Do not mark scripts active merely because they loaded. |
94
+ | `observation.complete` | Whether the scan finished without missing observations. |
95
+ | `observation.truncated` | Whether a collection limit discarded observations. |
96
+ | `observation.reasons` | Documented collection reason codes for an incomplete observation. |
97
+
98
+ The normalized snapshot contains `schema_version: 1`, `catalog_version`, rule identifiers, frame relationships, and collection status. Raw URLs do not survive normalization. The assessment returns PSP candidates with reviewed evidence, support status and its scope, any identified flow, reason codes, and limitations. `scenario_defaulted` records whether the caller omitted the scenario and accepted `one_time`.
99
+
100
+ ## Inspect an existing page
101
+
102
+ Call the collector with a Playwright page that your agent already owns:
103
+
104
+ ```js
105
+ import { inspectCheckout } from '@agent-cards/checkout/playwright';
106
+
107
+ const result = await inspectCheckout(page, {
108
+ scenario: 'one_time',
109
+ integration: { id: 'kernel_native', version: adapterVersion },
110
+ profile: kernelProfile,
111
+ });
112
+ ```
113
+
114
+ For a checkout that will use the direct SDK, omit the native integration and profile:
115
+
116
+ ```js
117
+ const result = await inspectCheckout(page, { scenario: 'one_time' });
118
+ ```
119
+
120
+ The [existing-browser example](./examples/preflight/inspect-browser.mjs) connects to a CDP browser and inspects its selected tab. Supply the browser connection URL through `CHECKOUT_CDP_URL` using your normal secret configuration; do not log the URL.
121
+
122
+ ```bash
123
+ npm install playwright-core
124
+ node node_modules/@agent-cards/checkout/examples/preflight/inspect-browser.mjs
125
+ ```
126
+
127
+ | Environment variable | Meaning |
128
+ | --- | --- |
129
+ | `CHECKOUT_CDP_URL` | Required connection URL for an existing Chromium browser. |
130
+ | `CHECKOUT_PAGE_INDEX` | Tab index in the first browser context; defaults to `0`. |
131
+ | `CHECKOUT_INTEGRATION` | `kernel_native` by default, or `direct_sdk` when the SDK handles payment. |
132
+ | `CHECKOUT_ADAPTER_VERSION` | The running Kernel native adapter version. Missing versions preserve `unknown`. |
133
+ | `CHECKOUT_PROFILE` | Optional path to the trusted native capability profile JSON. An absent profile preserves `unknown`. |
134
+
135
+ The example disconnects its inspection connection afterward. The existing agent keeps ownership of its browser session. No Agentcard payment interceptor is installed.
136
+
137
+ ## Choose the payment integration
138
+
139
+ | Integration | Choose when | Capability source |
140
+ | --- | --- | --- |
141
+ | `direct_sdk` | Your checkout uses `@agent-cards/checkout`, including when the SDK connects to a Kernel browser over CDP. | Capabilities bundled with the installed SDK. |
142
+ | `kernel_native` | Your checkout uses Kernel's native Agentcard integration. | A versioned profile supplied by your application. |
143
+
144
+ Kernel native support remains `unknown` until a compatible profile explicitly declares the detected processor or identified flow. The direct SDK's coverage does not establish Kernel native coverage. The detector can identify the PSP before that profile exists, so Kernel can build its result display and observation collector immediately.
145
+
146
+ The direct SDK result uses `integration.version: "bundled"` to name the capabilities shipped with this helper. `bundled` is not a version claim about a different SDK installation. Use the helper from the same package that handles payment, or provide an explicit profile for the implementation you run.
147
+
148
+ ## Check processor coverage
149
+
150
+ The catalog includes reviewed discovery rules and direct SDK implementation capabilities for every processor in the canonical checkout registry:
151
+
152
+ | Processor | Payment mode |
153
+ | --- | --- |
154
+ | Shopify | `token` |
155
+ | Stripe | `token` |
156
+ | Braintree | `token` |
157
+ | Checkout.com | `token` |
158
+ | Adyen | `cse` |
159
+ | Tranzila | `hosted_form` |
160
+ | Square | `token` |
161
+ | Authorize.Net | `token` |
162
+ | Worldpay | `token` |
163
+ | Nuvei | `token` |
164
+ | Airwallex | `token` |
165
+ | Rapyd | `token` |
166
+ | dLocal | `token` |
167
+ | EBANX | `token` |
168
+ | Mercado Pago | `token` |
169
+ | PayU | `token` |
170
+ | Razorpay | `token` |
171
+ | Mollie | `token` |
172
+ | Paysafe | `token` |
173
+ | Recurly | `token` |
174
+ | Moneris | `token` |
175
+ | Bambora | `token` |
176
+ | Global Payments | `token` |
177
+
178
+ The bundled direct SDK profile declares processor support for `one_time` purchases. The catalog carries each processor's request limitations and known exclusions. A detection rule does not cover every product or regional variant sold under the processor's name. For example, Moneris Hosted Tokenization and Moneris Checkout use different payment paths; the implemented adapter covers Hosted Tokenization.
179
+
180
+ | Observed checkout | Classification |
181
+ | --- | --- |
182
+ | A compatible Stripe script, `one_time`, direct SDK | `supported` at `processor_integration` scope; `checkout_flow_status` remains `unknown`. |
183
+ | Active Mollie hosted Components checkout with its component script, `one_time`, direct SDK | `supported` at `checkout_flow` scope; `checkout_flow_status` is `identified`. |
184
+ | A detected processor with an empty Kernel native profile | `unknown`; the native adapter has not declared processor or flow support. |
185
+ | Competing processors without enough evidence to select one | `unknown`, with `checkout_flow_status: "ambiguous"`. |
186
+ | An incomplete observation | `unknown`; inspect again after the checkout settles. |
187
+
188
+ Processor support does not establish which payment method the merchant selected. Many SDKs also load wallets or fraud checks before a card form appears. Read `checkout_flow_status` and the returned limitations alongside `status`; never present `supported` alone as a promise that a merchant purchase will succeed.
189
+
190
+ ## Declare native capabilities
191
+
192
+ Start with the [empty native profile](./examples/preflight/kernel-profile.empty.json). Keep `entries` and `processor_entries` empty until you have verified the adapter's payment behavior. An empty profile exercises the contract while preserving `unknown`. An omitted processor or flow declaration is not an explicit exclusion.
193
+
194
+ Supply profiles from trusted application configuration. A merchant page must never choose its own capabilities or claim a supported flow. A native profile cannot override a shared Vault exclusion.
195
+
196
+ | Profile field | What the caller supplies |
197
+ | --- | --- |
198
+ | `schema_version` | The contract schema version expected by the installed classifier. |
199
+ | `profile_version` | A revision that changes when the profile's declarations change. |
200
+ | `catalog_version` | The exact compatible catalog version from the installed package. |
201
+ | `integration.id` | `kernel_native` for Kernel's native Agentcard integration. |
202
+ | `integration.version` | The adapter version whose behavior the profile declares. |
203
+ | `entries` | Explicit flow, operation revision, mode, scenario, status, and optional limitations. |
204
+ | `processor_entries` | Optional declarations with `psp`, `mode`, `scenario`, `status`, and optional `limitations`. Missing or empty declarations preserve `unknown` for processor-only evidence. |
205
+ | `expires_at` | Optional expiration time for a time-bounded profile. |
206
+
207
+ Declare processor support and flow support separately. A flow entry cannot establish support for a generic script whose flow remains unidentified. A processor entry permits a result at `processor_integration` scope; the entry does not turn an unidentified checkout into an identified flow.
208
+
209
+ Take PSP identifiers, payment modes, flow identifiers, operation identifiers, and operation revisions from the packaged catalog. Verify each combination against the named adapter version before adding a `supported` entry. Use `unsupported` only for a known exclusion. A profile with a wrong schema, incompatible catalog, mismatched adapter version, or expired timestamp preserves `unknown`.
210
+
211
+ The JSON contract uses `schema_version: 1`. The catalog bundled with this release uses `catalog_version: "2026-09-11.2"`. Keep the snapshot, classifier, and profile on the same catalog version. Re-normalize observations with the installed package after changing the catalog. Review the adapter declarations before issuing a compatible profile; changing the version string alone does not validate new behavior.
212
+
213
+ Kernel can integrate the JSON contract immediately and supply its validated native capabilities later. No deployed Agentcard endpoint or payment request is required for that work.
214
+
215
+ ## Interpret the result
216
+
217
+ | Status | Meaning | Next step |
218
+ | --- | --- | --- |
219
+ | `supported` | The selected integration supports the detected processor or identified flow for the scenario named in the result. | Read `support_scope`, `checkout_flow_status`, and the limitations, then continue through normal approval and request checks. |
220
+ | `unsupported` | Shared constraints or the selected profile explicitly exclude the identified processor, flow, or scenario. | Read the reason and choose another payment flow or integration. |
221
+ | `unknown` | The observation or integration capabilities cannot establish support. | Inspect again after the payment method loads or changes. Preserve `unknown` if the evidence remains insufficient. |
222
+
223
+ | Result field | Meaning |
224
+ | --- | --- |
225
+ | `support_scope: "processor_integration"` | The status describes the processor implementation. The merchant's exact checkout flow can remain unknown. |
226
+ | `support_scope: "checkout_flow"` | The status describes the identified flow and its declared operation. |
227
+ | `support_scope: null` | The evidence or capability profile cannot establish a support classification. |
228
+ | `checkout_flow_status: "identified"` | The observations identify one reviewed checkout flow. Check `status` to learn whether the selected integration supports that flow. |
229
+ | `checkout_flow_status: "unknown"` | The observations do not identify the exact checkout flow. Processor support can still be known. |
230
+ | `checkout_flow_status: "ambiguous"` | Competing evidence prevents a single flow assessment. Inspect after the payment method is selected. |
231
+
232
+ A loaded PSP script establishes a possible processor, not necessarily the active card flow. The helper returns candidates rather than picking the first script. A missing fingerprint does not establish lack of support.
233
+
234
+ Every assessment is an advisory hint. The existing payment request checks still apply. A supported flow can require authentication or merchant configuration, and only the merchant's payment result establishes whether a purchase succeeded.
235
+
236
+ ## Handle assessment reasons
237
+
238
+ | Reason code | Meaning and next step |
239
+ | --- | --- |
240
+ | `processor_supported_by_integration` | The selected integration declares this processor and scenario. The result covers the implementation; check the flow status before continuing. |
241
+ | `integration_processor_unsupported` | The selected adapter explicitly excludes this processor and scenario. Choose another integration or payment method. |
242
+ | `integration_processor_undeclared` | The profile makes no processor-level claim for this scenario. Preserve `unknown` until the adapter capability is validated. |
243
+ | `processor_variant_unverified` | The detected SDK variant has no verified match to the implemented processor adapter. Preserve `unknown` and validate that variant before proceeding. |
244
+ | `payment_signal_inactive` | The matching evidence belongs to hidden or inactive payment content. Inspect the visible checkout. |
245
+ | `hosted_form_plain_sale_only` | The hosted form supports a one-time sale, not card storage or a subscription setup. Use a one-time sale or another supported integration. |
246
+ | `renewal_managed_by_merchant` | The merchant charges recurring renewals outside the Vault checkout. Verify the merchant's billing and payment outcome. |
247
+ | `flow_supported_by_integration` | The selected integration declares this flow and scenario. Continue through normal authorization and request checks. |
248
+ | `vault_flow_unsupported` | The shared Vault constraints exclude this flow. Choose another flow. |
249
+ | `integration_flow_unsupported` | The selected adapter explicitly excludes this flow and scenario. Choose another integration or flow. |
250
+ | `integration_flow_undeclared` | The profile makes no claim about this flow and scenario. Preserve `unknown` until the adapter behavior is validated. |
251
+ | `checkout_flow_unidentified` | PSP evidence does not establish the active card flow. Inspect again after the relevant payment controls load. |
252
+ | `flow_corroboration_missing` | A hosted payment location lacks the required matching component evidence in that document. Inspect after the component loads; the result remains `unknown` while that required evidence is missing. |
253
+ | `psp_not_detected` | No reviewed fingerprint matched. Preserve `unknown`; absence of a match is not proof of lack of support. |
254
+ | `ambiguous_checkout` | The observations identify competing candidates or flows. Inspect after the payment method is selected. |
255
+ | `observation_incomplete` | The scan missed observations or reached a limit. Read `observation.reasons`, then inspect again. |
256
+ | `integration_version_missing` | The caller did not identify the running adapter version. Supply that version. |
257
+ | `integration_profile_missing` | The selected integration has no profile. Supply a compatible profile after validating its declarations. |
258
+ | `integration_profile_invalid` | The profile is malformed or contains conflicting entries. Validate the profile against the packaged schema and classifier. |
259
+ | `integration_profile_incompatible` | The profile names an incompatible catalog, flow, operation, or mode. Review its declarations against the installed catalog. |
260
+ | `integration_profile_mismatch` | The profile describes a different integration or adapter version. Use the profile for the running adapter. |
261
+ | `integration_profile_expired` | The profile's expiration has passed. Revalidate and replace the profile. |
262
+ | `catalog_incompatible` | The snapshot uses a different catalog. Normalize the observations again with the installed helper. |
263
+ | `invalid_snapshot` | The snapshot does not match the supported contract. Regenerate it through `normalizeCheckoutSignals`. |
264
+ | `invalid_options` | Assessment options are malformed or include unsupported fields. Validate against the packaged options schema. |
265
+
266
+ Collection reasons explain why an observation is partial:
267
+
268
+ | Collection reason | Next step |
269
+ | --- | --- |
270
+ | `collection_timeout` | Inspect after the checkout settles, or increase the time budget within the supported limit. |
271
+ | `frame_limit` | Preserve `unknown` when the page has more frames than the configured limit. |
272
+ | `signal_limit` | Preserve `unknown` when the page exceeds the observation limit. |
273
+ | `snapshot_limit` | Preserve `unknown` when the observations exceed the size budget. |
274
+ | `frame_unavailable` | Inspect again after the frame is available. |
275
+ | `navigation_changed` | Inspect the new checkout state after navigation finishes. |
276
+ | `invalid_observation` | Validate raw observations against the packaged schema. |
277
+ | `invalid_url` | Correct the malformed or oversized asset location before normalization. |
278
+ | `collection_incomplete` | Inspect again after the underlying collection problem is resolved. |
279
+
280
+ ## Keep observations current
281
+
282
+ Inspect the checkout after its payment controls load. Inspect again after navigation, a payment-method switch, or a checkout refresh. The first release collects one snapshot per call and does not monitor the page continuously.
283
+
284
+ Incomplete frame inspection and collection limits remain visible in the result. Hidden or unused payment assets cannot establish an active supported flow. The collector does not inspect closed shadow roots or controls that have not loaded.
285
+
286
+ Collect only the documented asset observations when using your own browser tools. Do not include card input values, cookies, script bodies, page HTML, or arbitrary JavaScript globals. Keep full checkout URLs and their query strings out of logs and shared fixtures. The public evidence uses reviewed rule identifiers and sanitized asset locations.
287
+
288
+ The default collection budget is `1500` milliseconds, with at most `64` frames, `2048` signals, and `262144` serialized snapshot bytes. Set lower bounds through `collection.timeoutMs`, `collection.maxFrames`, `collection.maxSignals`, or `collection.maxSnapshotBytes` on `inspectCheckout`. The maximum time budget is `10000` milliseconds; the remaining limits cannot exceed their defaults. The minimum snapshot budget is `512` bytes.
289
+
290
+ ## Validate without a purchase
291
+
292
+ The included fixture is synthetic and contains no card information. Fixture classifications validate the detector contract; they are not evidence of a real payment or of a merchant's coverage.
293
+
294
+ Kernel can compare its own browser observations with the same fixture results before configuring native capabilities. Record a real checkout's preflight result only during a separately authorized checkout, then compare the naturally observed payment request. No card submission is needed to exercise the preflight helper itself.
package/README.md CHANGED
@@ -33,6 +33,10 @@ npm i @agent-cards/checkout
33
33
  Upgrading from 0.2.x? Read the [migration notes](./CHANGELOG.md), especially
34
34
  the unknown-outcome, cancellation and browser-context requirements.
35
35
 
36
+ To inspect a checkout before card entry with SDK `0.9.0` or later, read [Check checkout support](./PREFLIGHT.md).
37
+ The read-only helper detects all 23 registered PSPs and reports processor support separately
38
+ from an identified checkout flow. Kernel native coverage requires its own capability profile.
39
+
36
40
  ## Use it
37
41
 
38
42
  Two lines against a CDP session you already have:
@@ -56,7 +60,7 @@ await attachToCdp(cdp, pageSessionId, {
56
60
  merchant: 'vanman.shop',
57
61
  amount: 583, // your hint, an integer in the currency's smallest unit (or a decimal string: '5.83')
58
62
  currency: 'usd', // "$5.83" is derived for the approval screen
59
- onApprovalUrl: (url) => sendToUser(url), // iMessage, SMS, push, your call
63
+ onApprovalUrl: (url) => sendToUser(url), // SMS, push, email, iMessage: your call
60
64
  });
61
65
  ```
62
66
 
@@ -427,7 +431,7 @@ const preparation = await checkout.prepare({
427
431
  await page.getByRole('button', { name: 'Pay', exact: true }).click();
428
432
  ```
429
433
 
430
- `prepare()` is available on both Playwright and raw CDP controllers. It requires `amount` and `currency`, must precede the first recognized card request, and returns only when the cardholder's device is ready. It delivers the preparation URL through `onApprovalUrl` and `onUserAction`; binding the subsequent authorization sends no second approval link or SMS. The phone page must stay open. Its selected card, merchant origin, declared merchant, amount, currency, processor and environment bind one fresh request. The amount's authority is `agent`; a card token does not enforce the merchant's eventual charge amount.
434
+ `prepare()` is available on both Playwright and raw CDP controllers. It requires `amount` and `currency`, must precede the first recognized card request, and returns only when the cardholder's device is ready. It delivers the preparation URL through `onApprovalUrl` and `onUserAction`; binding the subsequent authorization sends no second approval link or SMS. The approval page on the cardholder's device must stay open. Its selected card, merchant origin, declared merchant, amount, currency, processor and environment bind one fresh request. The amount's authority is `agent`; a card token does not enforce the merchant's eventual charge amount.
431
435
 
432
436
  | Processor | `environment` | Fresh native request |
433
437
  | --- | --- | --- |
@@ -443,7 +447,7 @@ Braintree's native `ClientConfiguration` GraphQL query can run before, during or
443
447
 
444
448
  Readiness lasts up to 30 seconds (`preparation.expiresAt`) and appears as `ready_to_submit`, with `paymentStatus: 'not_started'`. Trigger the caller-owned Pay action immediately after the promise resolves. Expiry, navigation, cancellation, an early request or a changed checkout fails closed. A preparation and its attachment are single use; reconcile any bound authorization before creating a new attachment. The SDK never clicks Pay, reuses a stale request, changes native request deadlines, or automatically retries a failed prepared checkout.
445
449
 
446
- After Pay, the processor's native deadline still covers fresh authorization binding, device replay and token handoff. A disconnected/backgrounded phone or slow transport can still miss it. A subsequent SCA challenge has its own lifetime after token handoff. If the merchant request aborts or its frame closes, the attachment blocks further requests and tries to retire the pre-replay authorization; a started replay or unconfirmed cancellation remains unknown. Without `prepare()`, approval loading and human interaction still share the native deadline, so delayed approval cannot finish that request.
450
+ After Pay, the processor's native deadline still covers fresh authorization binding, device replay and token handoff. A disconnected or backgrounded cardholder device, or a slow transport, can still miss it. A subsequent SCA challenge has its own lifetime after token handoff. If the merchant request aborts or its frame closes, the attachment blocks further requests and tries to retire the pre-replay authorization; a started replay or unconfirmed cancellation remains unknown. Without `prepare()`, approval loading and human interaction still share the native deadline, so delayed approval cannot finish that request.
447
451
 
448
452
  Lost authorization polling, local approval timeouts, or interrupted browser
449
453
  handoffs produce `outcome_unknown` and block automatic retry. The thrown
@@ -517,3 +521,12 @@ coverage classifications, `recognized_traffic_share` is traffic-weighted, and
517
521
  `purchase_success_rate` stays null without observed merchant outcomes. Do not
518
522
  substitute the assessor for a browser/merchant validation run or use native
519
523
  Kernel adapter coverage as evidence for this SDK's coverage.
524
+ ### Autopilot execution metadata
525
+
526
+ When the cardholder has enabled an eligible spending rule in their vault, the same authorization can run through autopilot. The SDK keeps polling the existing authorization and returns optional `executionMode: 'autopilot' | 'user_approval'` and `grantId` metadata. Older API responses remain supported.
527
+
528
+ `authorize()` accepts optional `executionMode` and `grantId` routing hints, sent as `execution_mode` and `grant_id`. These never establish permission to spend; the protected payment service checks the cardholder's signed rule. Autopilot suppresses `onApprovalUrl` while it is executing. A definite fallback to user approval delivers the existing authorization's URL once. A lost outcome remains `PaymentOutcomeUnknownError`; it does not create or submit a second payment.
529
+
530
+ Use `executionMode: 'user_approval'` to require the existing confirmation flow. Without a selected card or grant, the backend can use exactly one eligible rule; ambiguous card selection keeps confirmation. A `grantId` restricts selection to that rule. The initial executor supports only the configured controlled Stripe test flow, and production remains disabled.
531
+
532
+ The adapters also send the observed top-level HTTPS `merchantOrigin`, such as `https://shop.example`, without a path, query or trailing slash. Direct `authorize()` callers can supply that origin explicitly. It is a routing hint; the protected adapter independently verifies the processor account, payee and amount. If a browser cannot provide its top-level URL, an explicit `merchantOrigin` option can supply the hint; otherwise the regular approval path remains available.
@@ -1,10 +1,2 @@
1
- /** Classify native Braintree GraphQL requests without changing their bytes. */
2
- export type BraintreeEnvironment = 'production' | 'sandbox';
3
- export type BraintreeRequestKind = 'configuration' | 'tokenization' | 'invalid';
4
- export declare function braintreeEnvironment(url: string): BraintreeEnvironment | undefined;
5
- /** Bounded duplicate-aware JSON for fresh-card preparation bodies. */
6
- export declare function readTokenizationJson(body: string | null): Record<string, unknown> | null;
7
- /** Undefined belongs to another processor; invalid Braintree requests stay blocked. */
8
- export declare function classifyBraintreeRequest(url: string, method: string, body: string | null): BraintreeRequestKind | undefined;
9
- /** Preparation accepts guest tokenization only; ordinary interception stays broader. */
10
- export declare function isPreparedBraintreeRequest(body: string | null): boolean;
1
+ export { braintreeEnvironment, classifyBraintreeRequest, isPreparedBraintreeRequest, readTokenizationJson } from './braintree.generated.js';
2
+ export type { BraintreeEnvironment, BraintreeRequestKind } from './braintree.generated.js';
@@ -0,0 +1,10 @@
1
+ /** Classify native Braintree GraphQL requests without changing their bytes. */
2
+ export type BraintreeEnvironment = 'production' | 'sandbox';
3
+ export type BraintreeRequestKind = 'configuration' | 'tokenization' | 'invalid';
4
+ export declare function braintreeEnvironment(url: string): BraintreeEnvironment | undefined;
5
+ /** Bounded duplicate-aware JSON for fresh-card preparation bodies. */
6
+ export declare function readTokenizationJson(body: string | null): Record<string, unknown> | null;
7
+ /** Undefined belongs to another processor; invalid Braintree requests stay blocked. */
8
+ export declare function classifyBraintreeRequest(url: string, method: string, body: string | null): BraintreeRequestKind | undefined;
9
+ /** Preparation accepts guest tokenization only; ordinary interception stays broader. */
10
+ export declare function isPreparedBraintreeRequest(body: string | null): boolean;