@agent-cards/sdk 0.20.0 → 0.22.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.
- package/CHANGELOG.md +51 -0
- package/PREFLIGHT.md +34 -0
- package/README.md +1217 -15
- package/dist/aci.d.ts +173 -0
- package/dist/aci.generated.d.ts +87 -0
- package/dist/aci.generated.js +306 -0
- package/dist/aci.js +371 -0
- package/dist/adyen-merchant-hosted.generated.d.ts +3 -3
- package/dist/adyen-merchant-hosted.generated.js +283 -49
- package/dist/agentcard.d.ts +9 -2
- package/dist/agentcard.js +4 -2
- package/dist/amadeus-checkout.generated.d.ts +57 -0
- package/dist/amadeus-checkout.generated.js +549 -0
- package/dist/amadeus.d.ts +41 -0
- package/dist/amadeus.js +81 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/card-endpoint.d.ts +177 -0
- package/dist/card-endpoint.js +286 -0
- package/dist/card-fields.generated.d.ts +5 -3
- package/dist/card-fields.generated.js +284 -7
- package/dist/cdp.d.ts +6 -1
- package/dist/cdp.js +983 -147
- package/dist/client.d.ts +493 -13
- package/dist/client.js +1100 -82
- package/dist/creditguard.generated.d.ts +79 -0
- package/dist/creditguard.generated.js +662 -0
- package/dist/cse-body.js +11 -1
- package/dist/cybersource-flex.d.ts +183 -0
- package/dist/cybersource-flex.generated.d.ts +92 -0
- package/dist/cybersource-flex.generated.js +689 -0
- package/dist/cybersource-flex.js +275 -0
- package/dist/datatrans.d.ts +96 -0
- package/dist/datatrans.generated.d.ts +64 -0
- package/dist/datatrans.generated.js +426 -0
- package/dist/datatrans.js +178 -0
- package/dist/elavon-converge.d.ts +37 -0
- package/dist/elavon-converge.generated.d.ts +49 -0
- package/dist/elavon-converge.generated.js +439 -0
- package/dist/elavon-converge.js +84 -0
- package/dist/eprotect.d.ts +152 -0
- package/dist/eprotect.generated.d.ts +77 -0
- package/dist/eprotect.generated.js +498 -0
- package/dist/eprotect.js +222 -0
- package/dist/gmo.d.ts +63 -0
- package/dist/gmo.generated.d.ts +60 -0
- package/dist/gmo.generated.js +586 -0
- package/dist/gmo.js +119 -0
- package/dist/hosted-form.d.ts +3 -2
- package/dist/hosted-form.js +3 -2
- package/dist/index.d.ts +19 -3
- package/dist/index.js +6 -1
- package/dist/juspay-gate.d.ts +82 -0
- package/dist/juspay-gate.js +126 -0
- package/dist/juspay.generated.d.ts +89 -0
- package/dist/juspay.generated.js +705 -0
- package/dist/lifecycle.d.ts +62 -6
- package/dist/lifecycle.js +123 -8
- package/dist/merchant-card-endpoints.generated.d.ts +63 -0
- package/dist/merchant-card-endpoints.generated.js +1103 -0
- package/dist/merchant-hosted.d.ts +4 -1
- package/dist/merchant-hosted.js +5 -2
- package/dist/merchant-session-probe.d.ts +48 -0
- package/dist/merchant-session-probe.js +53 -0
- package/dist/merchant-session.generated.d.ts +69 -0
- package/dist/merchant-session.generated.js +919 -0
- package/dist/payrails.d.ts +133 -0
- package/dist/payrails.generated.d.ts +73 -0
- package/dist/payrails.generated.js +596 -0
- package/dist/payrails.js +305 -0
- package/dist/pelecard.d.ts +32 -0
- package/dist/pelecard.generated.d.ts +32 -0
- package/dist/pelecard.generated.js +283 -0
- package/dist/pelecard.js +42 -0
- package/dist/pre-claim.d.ts +84 -3
- package/dist/pre-claim.js +987 -9
- package/dist/preflight-catalog.json +2310 -263
- package/dist/preflight-schemas.json +187 -6
- package/dist/preflight.generated.d.ts +1 -1
- package/dist/preflight.generated.js +247 -4
- package/dist/preparation.d.ts +5 -2
- package/dist/preparation.js +36 -10
- package/dist/prepared-processor.d.ts +86 -5
- package/dist/prepared-processor.js +157 -6
- package/dist/primer.d.ts +53 -0
- package/dist/primer.generated.d.ts +38 -0
- package/dist/primer.generated.js +624 -0
- package/dist/primer.js +82 -0
- package/dist/registry.d.ts +114 -12
- package/dist/registry.js +85 -11
- package/dist/shiji-sts.d.ts +144 -0
- package/dist/shiji-sts.generated.d.ts +72 -0
- package/dist/shiji-sts.generated.js +913 -0
- package/dist/shiji-sts.js +222 -0
- package/dist/stripe-checkout.generated.d.ts +1 -1
- package/dist/stripe-checkout.generated.js +735 -10
- package/dist/stripe-setup.d.ts +16 -0
- package/dist/stripe-setup.js +61 -0
- package/dist/substitutions.generated.js +187 -29
- package/dist/verifone.d.ts +68 -0
- package/dist/verifone.generated.d.ts +51 -0
- package/dist/verifone.generated.js +1401 -0
- package/dist/verifone.js +119 -0
- package/dist/voice-types.d.ts +27 -0
- package/dist/voice.d.ts +6 -1
- package/dist/voice.js +6 -1
- package/dist/wspay.d.ts +41 -0
- package/dist/wspay.generated.d.ts +41 -0
- package/dist/wspay.generated.js +370 -0
- package/dist/wspay.js +65 -0
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- A refused amount names what you passed and each amount it can mean, in the forms the API accepts, so an agent can correct its next call. `authorize()` given the string `"2667"` with `usd` throws `amount is an integer in the currency's smallest unit (2306 for $23.06), or a decimal string in normal units ("23.06"). You passed the string "2667". For 26.67 USD, send the number 2667 or the string "26.67". For 2667.00 USD, send the number 266700 or the string "2667.00".` `prepare()` and `prepareCheckout()` add the same sentences to their `amount_required` message. The first sentence is unchanged, so code that matches on it keeps working. The offers use the decimal places the API reads for each currency: none for JPY and MGA, three for KWD, whose amounts end in 0. A value below zero is never offered back as a positive amount, and a value with more digits than any amount is described and never repeated, so a card number typed into the wrong field stays out of your logs.
|
|
6
|
+
|
|
7
|
+
- **The phone's attestation rides on the key itself** (WP199, 1.3.4). `voice.appKeys.register(key, { user_id })` reads the block from `key.hardware`, where `@agent-cards/voice` 1.9.8's `VoiceHost` puts it, and sends it on as `hardware`; a server that forwards the key description as it came from the phone needs no change. `opts.hardware` still takes a block and wins when both are given. `HardwareAttestation` gains `app_id` (optional), the `<team id>.<bundle id>` an iOS phone names so Agentcard checks the attestation's `rpIdHash` against it; an Android block carries none.
|
|
8
|
+
|
|
9
|
+
- **The phone's hardware key is bound to its app voice key** (WP199). `voice.appKeys.register(key, { user_id, hardware })` takes the phone's hardware attestation as the new `HardwareAttestation` type (`platform`, `key_id`, `attestation` as Android's certificate chain or iOS App Attest's one object, `challenge`) and sends it on as `hardware`, untouched; `RegisteredAppVoiceKey` gains `hardware_proven` and `hardware_level` (`strongbox`, `tee`, `secure_enclave`), what Agentcard made of it. A registration without the block is unchanged. The matching API release is required.
|
|
10
|
+
|
|
11
|
+
- Continue a Stripe card save that tokenized first (Twilio's billing page, and any Payment Element page with `paymentMethodCreation: 'manual'` that calls `createPaymentMethod` and then `confirmSetup`). After a `/v1/payment_methods` approval, the SDK used to abort the page's SetupIntent confirm (`stripe_tokenization_unbound`) and the page reported the card could not be added. Now the SDK asks the API about it (`VaultClient.checkStripeSetupContinuation`, which takes only an answer that names the SetupIntent being confirmed) and continues it once allowed: a card-free confirm paying with the approved method continues untouched, and one that carries the card again (`confirmCardSetup` with the Card Element after `createPaymentMethod`) is sent with every `payment_method_data` field removed and the approved `payment_method` in their place, the exact body the API judged. The event is `stripe_setup_continued` with `{ authorizationId, setupIntentId, rewritten }`: `rewritten` is true when the SDK wrote the approved payment method in place of a card the confirm carried, and false when the page's card-free confirm continued untouched. Either way the SetupIntent saves the approved payment method. The reason is `stripe_setup_continued`. The API allows it only for a company Agentcard turned card-save continuations on for, an approval given on the Vault page, not by voice, with no amount, and a SetupIntent Stripe reports still confirmable on the same Stripe account; everywhere else it answers `continuation_invalid` and the confirm is aborted as before. Requires the API release that judges SetupIntent continuations; an older API refuses the check and nothing changes.
|
|
12
|
+
|
|
13
|
+
- Pause Verifone eCommerce merchants, whose page encrypts the card with verifone.js and posts it to the merchant's own server, through reviewed Verifone profiles (`verifone_card_capture`, off until Agentcard turns Verifone on for your company). `syncRegistry()` declares the capability and arms only the profiles the API serves. A profile in `observe` aborts any request at the merchant that carries a verifone.js blob and reports `verifone_profile_observed`; an enabled one pays its reviewed card request only through `prepare({ psp: 'verifone', merchantProfile })`. The approval is a `cse` replay with `kind: 'verifone'` (`VerifoneReplay`), and `substituteVerifoneBody` writes its blob into the paused request's body. The Container Store (`containerstore_checkout`) ships in `observe`, and Agentcard has reviewed neither its card request nor its key, so nothing pays there yet.
|
|
14
|
+
|
|
15
|
+
- Recognize Worldline MyCheckout's card form, off until Agentcard turns it on for your company. `syncRegistry()` now also declares the `worldline_mycheckout_form` capability (`SUPPORTED_CAPABILITIES`), and the API serves the recognizer only for a company Agentcard enabled. The SDK pauses the page's top-level form POST to `/checkout` on `payment.pay1` or `payment.pay2` under `checkout.worldline-solutions.com` (and their `.preprod` twins) in mode `hosted_form`, as it does Tranzila's: the cardholder's device submits Worldline's form with the approved card, and the paused navigation resolves to the synthetic page. The form names no amount, so the `amount` and `currency` you pass are what the cardholder approves; the API refuses a create without them, or with a zero amount (`amount_required`). A card submit with a checked "remember" box, a Google Pay token or a Click to Pay answer is refused (`invalid_worldline_mycheckout_request`). Google Pay and Click to Pay payments that carry no card number continue untouched, as the page's cancel and its other payment methods on the same URL do, with no authorization and no prompt. Autopilot never pays a MyCheckout payment. Matching API and Vault releases are required.
|
|
16
|
+
|
|
17
|
+
- Pay a Payrails web SDK v6 card save (Blacklane's consumer checkout) behind a dark launch, in the new mode `device_encrypt`. `syncRegistry()` now asks for `modes=token,cse,hosted_form,device_encrypt` and also declares the `payrails_device_encrypt` capability (`SUPPORTED_CAPABILITIES`), and the API serves the Payrails recognizer only to an org Agentcard has enabled for Payrails, so no other org's Payrails requests are read, paused or refused. For an enabled org, both adapters read the Payrails init payload from the page's own XHR and fetch answers (in memory, at most eight sessions for fifteen minutes) and pause the card form's save to `/public/payment/instruments` only once it binds to the one session its token, link, `holderReference` and `providerConfigId` name, seen within nine minutes. That session's key rides on the create (`request.payrails.encryption_public_key`); the cardholder's device encrypts the real card and sends the save itself, and the page receives Payrails' 201 rebuilt from an allow-list (`DeviceEncryptReplay`); anything else throws `PaymentOutcomeUnknownError` with reason `payrails_answer_unconfirmed`. A save that keeps the card on file (`payrails_card_on_file_consent_required`, every Blacklane save today), a `Subscription` save, a body that is not the Payrails SDK's own, and a card-form payment that carries the card inside `paymentComposition` (`unsupported_payrails_card_payment`) are refused before anything is created, and the attachment reads `unsupported` with that reason. A save with no captured session (`payrails_session_unavailable`) or a key the frame did not use is refused alone, with a message to reload the checkout. A `POST` to a Payrails host with no body the SDK can read (none, an empty one or a streamed one) is refused alone on both adapters with a `blocked` event, `unreadable_payrails_request`, except on Payrails' static host, `assets.payrails.io`, which takes no payment. The save names no amount, so it needs `amount` and `currency` or a page total. The matching API, Vault and database releases are required.
|
|
18
|
+
|
|
19
|
+
- Pay a Primer checkout (Printful, GetYourGuide) behind a dark launch. `syncRegistry()` now also declares the `primer_payment_instruments` capability (`SUPPORTED_CAPABILITIES`), and the API serves the Primer recognizer only to an org Agentcard has enabled for Primer, so no other org's Primer requests are paused or refused. For an enabled org, both adapters pause the card tokenization that Primer Web SDK v2's api-controller frame on `sdk.primer.io` sends to `sdk.api.primer.io` or `sdk.api.sandbox.primer.io`: the cardholder's device sends the card to Primer, and the page receives only Primer's single-use card token, rebuilt from an allow-list under a JSON content type; any other answer throws `PaymentOutcomeUnknownError` with reason `primer_token_unconfirmed`. A wallet tokenization with no card and a saved-card exchange continue untouched. A tokenization that asks Primer to save the card is aborted alone (`blocked`, `primer_keep_on_file`) and the next one is judged again. A card request from Primer Checkout (primer-js) or in any shape the v2 frame would not send is aborted before anything is created: the attachment reads `unsupported` with reason `unsupported_primer_sdk` or `unsupported_primer_request`, which the `unsupported_checkout` event also carries. A body the SDK cannot read is aborted alone (`blocked`, `unreadable_primer_request`). The request names no amount, so pass `amount` and `currency` or let the page total name the price; with neither, the API answers 400 `amount_required`. The matching API and Vault releases are required.
|
|
20
|
+
|
|
21
|
+
- Pay CreditGuard's hosted payment page (Hyp PPS, `pps.creditguard.co.il`, which SeboCalm frames) under a prepared checkout: `prepare({ psp: 'creditguard', environment: 'production' | 'sandbox', paymentPageUrl })`, where `paymentPageUrl` is the frame's own address (`https://pps.creditguard.co.il/?txId=...`). Agentcard reads that transaction from CreditGuard before the cardholder is asked; a page the Vault cannot finish is refused as `creditguard_transaction_refused` with CreditGuard's reason in the new `CheckoutPreparationError.detail`. Only the page's own new-card submit for that transaction pauses; the cardholder's device sends the real card, and the page reads CreditGuard's answer as payment-core rebuilds it. A submit with "save my card", installments, currency conversion, an Israeli ID or a saved card is aborted before anything is created (`blocked`, `creditguard_request_unsupported`), and the preparation stays ready. Without a preparation the submit is refused with `PreparationRequiredError`. CreditGuard's own 3-D Secure call to Nuvei, from its page or from any frame inside it, is refused, whether or not CreditGuard is enabled, and the attachment reads `unsupported` with reason `creditguard_three_d_secure`: it is never paused as a Nuvei payment. `syncRegistry()` now also declares the `creditguard_pps_process` capability (`SUPPORTED_CAPABILITIES`), and the API serves, prepares and pays CreditGuard only for a company Agentcard enabled; any other company's build does not recognize the page and leaves it alone, as before. The matching API, Vault and relay releases are required.
|
|
22
|
+
|
|
23
|
+
- Pay an ACI Worldwide COPYandPAY checkout (Halfords) behind a dark launch, through a prepared checkout only. ACI's widget sends one card as several requests to `/v1/checkouts/{id}` (the card number, the CVC and, in SAQ-A mode, the expiry and the holder), then the page posts `/payment`. `syncRegistry()` now also declares the `aci_split_card.v1` capability (`SUPPORTED_CAPABILITIES`), so the API serves the ACI recognizer. `prepare({ psp: 'aci', environment: 'production' | 'sandbox' })` approves before Pay, and both adapters then pause the card-number request, bind it to that preparation and answer it with ACI's rebuilt answer after the cardholder's device sends the real card; hold the page's own CVC and expiry requests and answer them with the same answer, never forwarding them (`aci_leg_absorbed`); let the holder request through; and let `/payment` continue once, only as the widget's frame navigation, with a classic-mode page's placeholder expiry removed (`aci_payment_continued`); `attachToPlaywright` removes it only on Chromium and refuses a classic-mode `/payment` on Firefox or WebKit (`aci_expiry_unstrippable`). A request that asks ACI to keep the card is refused as `aci_card_on_file_refused` and retires a ready preparation; a second card-number request on a checkout whose first one is running or answered (`aci_checkout_reused`), `/payment` before an answered card-number request, a second `/payment`, a `/payment` a page script sends itself, another brand or a return off the merchant is refused (`blocked`; the README lists every code). An unprepared card-number request throws `PreparationRequiredError` before any create. `VaultClient.recognizesProcessor(psp)` says whether the registry serves a processor, and event URLs show ACI checkout ids as `{checkoutId}`. Until Agentcard enables the processor for your org, preparation and create answer `processor_unavailable`. The matching API and Vault releases are required.
|
|
24
|
+
|
|
25
|
+
- Pay a Pelecard hosted payment page (Iframe/Redirect 2.0) with a vaulted card, for an org Agentcard enables for Pelecard, in test mode only. The page on `gateway21.pelecard.biz` (or `gateway20`) sends the card in one XHR to `/PaymentGW/Transaction`; the SDK now pauses it for the cardholder's approval, the phone sends the real card, and the page reads Pelecard's answer. `syncRegistry()` now also declares the `pelecard_transaction` capability (`SUPPORTED_CAPABILITIES`), and the API serves the recognizer only to an enabled org, so every other org's Pelecard requests continue untouched. The request names no amount: pass `amount` and `currency`, or the submission fails with `AmountRequiredError` (terminal) before anything is created, and pass the total the payment page shows as `pageAmount`, or it fails with the new `PageAmountRequiredError` (not terminal: the page's next submission reads the total again). A submission that asks Pelecard to keep the card on file is `blocked` as `pelecard_keep_on_file_unsupported`, and one the device could never fill (a saved token, installments, a buyer-typed total) as `invalid_pelecard_request`, both before any authorization or prompt. The page's card-free tabs (Bit, wallets, the PIN pad, bank transfer) continue untouched. The matching API release is required.
|
|
26
|
+
|
|
27
|
+
- Pause an Authorize.Net Direct Post Method or SIM card form for the cardholder's approval, for an org Agentcard enabled for it. `SUPPORTED_CAPABILITIES`, which `syncRegistry()` declares, now also lists `authorize_net_dpm_form`, and the matching API serves the dark `authorize_net_dpm` entry only to an enabled org; every other org keeps the catalog it had. The form posts one form navigation to `/gateway/transact.dll` on `secure2`, `secure` or `test.authorize.net`, and both adapters handle it in mode `hosted_form`, as for Tranzila: the cardholder's device submits the form, the paused navigation resolves with the synthetic page, and you confirm the order with the merchant. Field names match in any case. SIM's first step, an eCheck and Visa Checkout carry no card and continue untouched. A form whose action carries a query string or a fragment is not recognized (`bareEndpoint`) and continues untouched. A `400 hosted_form_field_refused` with reason `stale_fingerprint` is no longer terminal: `CheckoutApiError.isStaleFingerprint` is true, the adapters quiet the page for `approvalCooldownMs`, and the form the page renders after a reload is judged afresh. Not eligible for auto-approval.
|
|
28
|
+
|
|
29
|
+
- Pay a Datatrans Secure Fields checkout (PCI Proxy, British Airways) behind a dark launch. `syncRegistry()` now also declares the `datatrans_secure_fields_tokenize` capability (`SUPPORTED_CAPABILITIES`), and the matching API serves the Datatrans recognizer only to an org Agentcard has enabled for it; every other org's SDK leaves Datatrans requests alone. Both adapters pause the card-number iframe's TOKENIZE post of a new card, the cardholder's device sends the card to Datatrans, and the iframe receives the token and its `cardInfo`. A post that the iframe would not send for this flow is aborted with a `blocked` event, `invalid_datatrans_request`, and so is a post that asks PCI Proxy to keep the card on file (`usage=REGISTRATION`, which British Airways's Nexus checkout sends for every new card), `datatrans_card_on_file_refused`, while the card-on-file policy the API serves with the recognizer (`cardOnFile`) is `refuse`; both before anything is created, and the page's next post is judged afresh. When the served policy allows card on file, that post pauses like any other, with no SDK release. Wallet, bank-account and CVV-only posts and the BIN lookup continue untouched. Once a post was approved, the page's re-submits of the same form from the same iframe that change only the expiry or the browser details are answered with the same token, with a `repeat_answered` event and no second prompt, while that approval is the checkout's current one, while the form keeps posting (five quiet minutes end it) and for at most the token's 30-minute lifetime. Once the token reached the page, each re-submit is answered only after `resolveMerchantResult` reports the order still `pending`, and an attachment with no resolver asks the cardholder again; a reloaded iframe, another placeholder card or CVV, other contact data, a completed or failed order and a new authorization each make it a new question. Autopilot never pays it.
|
|
30
|
+
|
|
31
|
+
- Read the merchant's cookie jar for a reviewed merchant-session read and create a merchant-session probe, the first step of reading Dunelm's and Cinemark's own checkout total from the cardholder's side. `captureMerchantSession(cdp, sessionId, profile)` reads the jar for the read URL with `Network.getCookies`, drops every bot-manager cookie (`cf_clearance`, `__cf_bm`, `_abck`, `bm_sz`, `ak_bmsc`), and throws `MerchantSessionRefusedError` (reason `signed_in`) for a jar that carries a sign-in token, before anything leaves. `VaultClient.createMerchantSessionProbe({ user, capture })` sends the profile and the kept cookies, runs the same rules again, and returns the Vault link the cardholder opens; `recordMerchantSessionEgress(id, result)` records the same read made from Agentcard's autopilot egress. No card, JWE or payment is involved. The API answers `404` for every organization not on its probe list, which ships empty.
|
|
32
|
+
|
|
33
|
+
- Recognize five reviewed merchants that post the card from their own checkout page to their own server: AT&T, Italo, Universal Orlando, Target Optical and Opus Virtual Offices (mode `card_endpoint`). Every profile ships in observe: the adapters pause each merchant's exact card request and refuse it as `unsupported_checkout`, before any authorization, so the dummy card never reaches the merchant. For a profile that takes payments, the adapters send the paused request's session (the profile's own headers, the endpoint's cookie jar, a checkout-page Referer) with the dummy-card body in the create's `merchant_card_endpoint` member, wait for the cardholder's approval, write the merchant's `Set-Cookie` values Secure and host-only on the endpoint host (a rotation of a cookie the browser holds on a parent domain the merchant names is written there, replacing it), and answer the paused request with the merchant's answer, which the cardholder's device obtained over the checkout relay. An answer the device withheld becomes a fixed `502` error and the outcome is unknown. Every payment needs the cardholder's approval and your `amount`; after the hand-off the page's retry is refused until you reconcile. Events name the profile and the endpoint origin, never the URL, body or session. `CardEndpointRefusedError`, `CardEndpointReplay` and `cardEndpointPatterns()` are exported. Matching API, relay and Vault releases are required before any profile takes a payment.
|
|
34
|
+
|
|
35
|
+
- Pay a Juspay Express Checkout card payment (Swiggy's website) behind a dark launch. `syncRegistry()` now also declares `juspay_txns.v1`, so the API serves the Juspay recognizer to an org Agentcard has enabled. Both adapters answer the page's `/card/tokenize` locally with a stand-in token and refuse its placeholder `/v2/card/fingerprint` lookup, so the placeholder never reaches Juspay and the page never holds a real card token. The `/txns` that carries the stand-in token pauses, the cardholder's device sends both real requests, and the page receives only Juspay's order id, transaction id, status and bank redirect. Saving the card, EMI, a card number in `/txns` and card requests to `api.juspay.io` or `api-ns1.juspay.in` are aborted as `unsupported_checkout` before an authorization exists, and the controller reads `unsupported` with reason `juspay_request_unsupported`. An approval never answers a `/txns` for another order. Until Agentcard enables Juspay for your org, the SDK does not take over Juspay's requests, and a create for one answers `processor_unavailable`. The matching API and Vault releases are required.
|
|
36
|
+
|
|
37
|
+
- Pay a CyberSource Flex Microform checkout (Amtrak, Sonos, Learning Without Tears) behind a dark launch. `syncRegistry()` now declares the `capture_context` capability (`SUPPORTED_CAPABILITIES`), and the API serves the Flex recognizer only to an org Agentcard has enabled for it, so every other org's Microform requests go through untouched, as before. Both adapters read the capture context from the card field iframe's URL, verify it offline against CyberSource's pinned signing keys, and send it with the Microform fields on the create; the cardholder's device seals the real card for CyberSource and the field's paused request is answered with the transient token. Only Microform 2.12.1 card fields pause, and a field counts only once its document has loaded: a check Microform continues, any other request on the tokens URL is aborted as `unsupported_checkout` before an authorization exists, and a field the SDK could not read is refused for that request alone. A retry from either field after the field's 30-second timeout is answered from the same approval, and `prepare({ psp: 'cybersource_flex', environment: 'production' | 'sandbox' })` binds one field request. `vault.placeholderCard({ user, cardId })` returns the test number, security code and real expiry to type so the page's own card facts match the stored card; pin its `cardId` on the attachment so the approval page preselects that card. New exports: `SUPPORTED_CAPABILITIES`, `UnsupportedCapabilityError`, `PlaceholderCardError`, and the types `PlaceholderCard`, `MicroformSidecar` and `MicroformField`. The matching API and Vault releases are required.
|
|
38
|
+
|
|
5
39
|
- Recognize Gravy (Gr4vy) Secure Fields. The registry and the coverage catalog now name the new-card request that updates a checkout session at `/checkout/sessions/<session id>/fields` on the merchant's own `api.<merchant>.gr4vy.app` host, in sandbox and production, with `payment_method.number`, `payment_method.expiration_date` as one `MM/YY` value and `payment_method.security_code`. Gravy publishes this request as an HTTP PUT and the SDK pauses and replays POST requests only, so the recognizer identifies the destination and fills the body but intercepts nothing yet; a PUT on that host continues to Gravy untouched, and the preflight reports Gravy `unsupported` with `request_method_not_supported` in every card scenario until the SDK can intercept that method. The shape follows Gravy's published contract and is not confirmed by a live capture. Updating the session stores the card with Gravy; the merchant creates the transaction on its own server, so a completed request is not a payment. Gravy Embed on `embed.<merchant>.gr4vy.app` is not covered.
|
|
6
40
|
|
|
7
41
|
- Attach in a browser whose default context runs extensions. A browser extension's service worker or background page, at a `chrome-extension://` URL, no longer counts as a site's worker: `attachToPlaywright` and `attachToCdp` attach beside it, and one that starts later leaves the checkout armed, because an extension's worker never serves the merchant's requests. Cloud browsers such as Anchor run their agent, ad blocker and popup blocker as extensions in the default context, and stock Chrome runs its component extensions there, so that context used to be refused with `Service workers are active` or `checkout_attachment_failed`. A site's own service worker, a shared worker, or a worker with no URL still refuses the context.
|
|
8
42
|
|
|
43
|
+
- Pay a GMO Payment Gateway checkout (teamLab's ticket sites) behind a dark launch. `syncRegistry()` now declares the `gmo_shared_pk` capability (`SUPPORTED_CAPABILITIES`, now exported), and the API serves the GMO recognizer only to an org Agentcard has enabled for GMO, so no other org's GMO requests are paused or refused. For an enabled org, both adapters pause `mp-token.js`'s `getToken` for one token on `token.mul-pay.jp` or `stg.token.mul-pay.jp`: the cardholder's device sends the card to GMO, and the page receives only GMO's single-use token, reduced to the fields `mp-token.js` reads; any other answer throws `PaymentOutcomeUnknownError` with reason `gmo_token_unconfirmed`. Any other request to that URL (a merchant-registered key, GMO Elements, several tokens, a shop id that does not match the host) and GMO token v1's script request are aborted before anything is created: the attachment reads `unsupported` with reason `unsupported_gmo_request` or `unsupported_gmo_token_v1`, which the `unsupported_checkout` event also carries. A body the SDK cannot read is aborted alone (`blocked`, `unreadable_gmo_request`). The request names no amount, so pass `amount` and `currency`; without them it throws the new `AmountRequiredError` before anything is created. A retry the page sends after losing its request takes the pending approval only when it names the same shop. The matching API release is required; the Vault's GMO path ships separately.
|
|
44
|
+
|
|
45
|
+
- Pause Elavon Converge's Hosted Payment Page for an org Agentcard enabled for it. NY DMV's payment apps redirect to Converge's own page on `api.convergepay.com` (`api.demo.convergepay.com` for Converge's demo environment), which posts the card as one same-origin JSON request to `/hosted-payments/service/payment/hpp/process`. `syncRegistry()` now declares the `converge_hpp_process` capability, and the API serves the dark recognizer only to an org Agentcard enabled for Converge; every other org's Converge requests continue untouched, as before. A first credit card sale pauses in `token` mode for the cardholder's approval of its own `ssl_amount`, so no `amount` is needed; the cardholder's device sends the real card and the paused request is answered with Converge's approval, rebuilt without the card's expiry, the cardholder's names or any card token. Electronic check and financing payments on the same URL continue untouched. Every other shape is refused in the browser before any create or prompt, with payment-core's own code on the `blocked` event (`ConvergeRefusalReason`): a wallet, the debit, gift card and push-to-card tabs, a follow-up after a 3-D Secure, Pay Defense or surcharge step, a CAPTCHA, a public-sector service fee, recurring or installment fields, card saving (`ssl_get_token`, `ssl_add_token`), a tip or cash back, another currency, and anything that is not the page's own request. A refusal does not hold the attachment, so the page's next payment is judged afresh. Autopilot never pays a Converge payment: it always waits for the cardholder's own approval.
|
|
46
|
+
|
|
47
|
+
- Worldpay eProtect card registration, behind a dark launch, through a prepared checkout only. A registration is not a payment. The matching API, Vault and relay releases are required.
|
|
48
|
+
- What you set: call `prepare({ psp: 'worldpay_eprotect', environment: 'production' | 'sandbox', paypageId })` with the merchant's eProtect paypageId. The attachment must carry a `cardId`. An unprepared registration throws `PreparationRequiredError` before any create.
|
|
49
|
+
- Dark launch: `syncRegistry()` now declares the `worldpay_eprotect_jsonp` capability (`SUPPORTED_CAPABILITIES`). The API serves the eProtect recognizer only to an org Agentcard has enabled. Until then, the SDK leaves eProtect traffic untouched, and preparation and create answer `processor_unavailable`.
|
|
50
|
+
- What the SDK does with a registration: its card request is a GET with the card encrypted in its query. Both adapters pause that GET and bind it to the preparation. They send the create as the URL alone. They read the authorization every 500 ms for 15 seconds. They answer the paused script with the registration, in its own callback, under Worldpay's script type.
|
|
51
|
+
- What the SDK does with other eProtect requests: the vendor's 5-second failover re-send of a registration the attachment saw is aborted quietly. Any other request on `/eProtect/paypage` is aborted as `unsupported_checkout`: the CVV-only, PIN, wallet and private-label variants, and the Mobile API form post. The vendor's give-up report (`/eProtect/ppstats` 900 or 901) ends the running approval as `merchant_request_aborted`. The report itself continues to Worldpay.
|
|
52
|
+
- Shared changes: `isCardRequest` and `checkoutModeOf` now follow each recognizer's request method. `cardUrlPatterns()` arms a recognizer's abort-only hosts. `VaultClient.recognizesProcessor(psp)` says whether the registry serves a processor.
|
|
53
|
+
|
|
54
|
+
- Pay a WSPay Components checkout behind a dark launch. `syncRegistry()` now also declares the `wspay_confirm` capability (`SUPPORTED_CAPABILITIES`, now exported from the package), and the API serves the WSPay recognizer only to an org Agentcard has enabled for WSPay; for every other org the SDK leaves WSPay's requests exactly as before. For an enabled org, both adapters pause the card frame's confirm of a new card for a one-time payment: the cardholder's device sends the card to WSPay and the frame receives WSPay's answer. A confirm with no new card (a saved card, a card tokenized earlier, a card-shaped object the page built) is aborted with a `blocked` event, detail `unsupported_wspay_payment_method`, and one that asks WSPay to keep the card on file with `wspay_keep_on_file_unsupported`, both before anything is created or anyone is prompted. Valamar asks to keep the card on every booking, so its checkouts are refused until the approval can ask the cardholder. The confirm names no amount, so pass `amount` and `currency`; without them it throws the new `AmountRequiredError` before anything is created. WSPay's 3-D Secure step reads as `requires_user_action` with reason `3ds`, since the challenge runs in your browser; that step names no amount, so what WSPay charges after the challenge is never compared with the approved amount (`amountVerified` stays `null`) and only the merchant's order confirms it. `redactUrl` now masks the client_secret in Monri and WSPay payment paths; a string that is not a URL has no host to go by, so any `/payment/<segment>` in it is masked whatever the processor. The matching API and Vault releases are required.
|
|
55
|
+
|
|
56
|
+
- Recognize Shiji STS, the card leg of MyCheck Wallet V3 at La Quinta by Wyndham, behind a dark launch. `syncRegistry()` now declares the `shiji_sts_pinned_key` capability (`SUPPORTED_CAPABILITIES`), and the API serves the recognizer only to an org Agentcard has enabled for it, so no other org's Shiji requests are paused or refused. For an enabled org, both adapters judge every POST to `getTokenId` and `getCvvId` before anything pauses. Today every `getTokenId` is refused in the browser as `unsupported_checkout` with reason `shiji_sts_keep_on_file`, before any create or prompt, because the token a hotel booking mints guarantees the stay and Agentcard cannot yet ask the cardholder to let the hotel keep the card. The swap is built and tested for when that changes: the cardholder's device encrypts the card under the key Agentcard pins, the adapter writes `pan` and `expires` over the page's own at the body root, continues the request, and continues the one `getCvvId` that follows it (same frame, same `accessToken`, a `keySequence` the API reviewed as the page's own `getCvvId` key and served with the approval, within 120 seconds, once) with the device's CVV; every other `getCvvId` is refused, and the CVV ciphertext is dropped once the attachment is cancelled, the page, frame or target that sent the `getTokenId` goes away, or that frame loads a new document. The ciphertext goes only into the `getTokenId` the approval was created from, byte for byte: if the page gives up on it while the cardholder decides, the approval is cancelled (`merchant_request_aborted`) and never answers a later request, since one of the same shape could name another Shiji merchant's session. A Shiji approval whose served set is gone resolves as `PaymentOutcomeUnknownError` with reason `cse_substitutions_expired`, as a Fiserv one does. New export: the `ShijiStsUnsupportedReason` type.
|
|
57
|
+
|
|
58
|
+
- Pay an Amadeus Checkout card step through a prepared checkout, for an org Agentcard enabled for it. Air France and KLM take cards through Amadeus's Checkout Web SDK, whose tunnel iframe posts every action to `paypages.payment.amadeus.com/1ASIATP/ARIAPP/pay`: `load` as the payment step opens, the BIN lookup, and the card `add`. `syncRegistry()` now declares the `amadeus_checkout_actions.v1` capability, and the API serves the dark recognizer only to an enabled org; every other org's Amadeus requests continue untouched, as before. With `prepare({ psp: 'amadeus_checkout', environment: 'production' | 'sandbox' })`, only the add pauses, bound to the prepared page by its `Amadeus-Checkout-Sdk-Host` header. A request the catalog marks as routine without a card now continues before the preparation claim, in both adapters and for every processor, so the page's own `load` no longer spends or blocks a preparation, and Air France's Nuvei payment with a `ccTempToken` after a prepared add continues instead of failing. The tunnel gives up on the add after 30 seconds, so 20 seconds after the pause (`AMADEUS_SEND_WINDOW_MS`) the SDK asks the API to retire the authorization, or, while its create has not answered, the preparation and any request already bound to it (`VaultClient.retirePreparation`). Once the API confirms the card never left the device, the SDK fails the page's request with the controller at `failed` and reason `amadeus_send_window_closed`; when it cannot confirm, the SDK waits for the device's answer. A refused Amadeus request fails as a network error, which the tunnel reports at once, rather than as a cancellation, which it ignores. Air France's and KLM's add is refused before any create or prompt as `amadeus_merchant_held_expiry`, because their own form keeps the expiry, a Data Collection Page store as `amadeus_dcp_field_config_unreviewed`, and an add naming another page as `amadeus_header_binding`, each on the controller's `failed` state. Autopilot never pays an Amadeus payment.
|
|
59
|
+
|
|
9
60
|
## 1.3.2
|
|
10
61
|
|
|
11
62
|
- **`AppVoiceKeyDescription` names no `agreement_public_key`** (WP115, the audit's fourth lane). The key the app copy is sealed for is never a business's to name: the frame mints it and the person's vault proves it at the set-up inside the app. `voice.appKeys.register` sends the signing half alone; the API answers `agreement_key_not_accepted` to a body that still carries one, and `GET /vault/voice/app_copy/:lang` answers `agreement_key_required` until the vault has vouched for the key.
|
package/PREFLIGHT.md
CHANGED
|
@@ -179,12 +179,44 @@ The catalog includes reviewed discovery rules and direct SDK implementation capa
|
|
|
179
179
|
|
|
180
180
|
Fiserv Commerce Hub is not in the table. Agentcard keeps Fiserv off until it turns it on for a company, so the bundled profile declares no Fiserv support. Fiserv's assets still identify `fiserv`: `payment-fields.js` and `checkout.js` on `commercehub-checkout.fiservapps.com` and the card frame on `commercehub-secure-data-capture.fiservapps.com`, with their `-cert` hosts. The result stays `unknown`, and a page that loads a Fiserv asset beside another processor's reads as `ambiguous`. A company that Agentcard turned Fiserv on for pays it through `prepare()`, as the [README](./README.md) describes.
|
|
181
181
|
|
|
182
|
+
Verifone eCommerce is not in the table either, for the same reason. Its `verifone.js` on `us.jsclient.verifone.cloud`, `emea.jsclient.verifone.cloud` and the two sandbox hosts `uscst.jsclient.vficloud.net` and `cst.jsclient.vficloud.net` identifies `verifone`, and the result stays `unknown`. A Verifone page encrypts the card itself and sends it to the merchant's own server, so Agentcard pays it only at a merchant it reviewed.
|
|
183
|
+
|
|
184
|
+
GMO Payment Gateway (`gmo_pg`) is identified from its token v2 script `mp-token.js` on `static.mul-pay.jp` and `stg.static.mul-pay.jp`, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out and a GMO checkout stays `unknown`, even when your SDK build can pay it. GMO token v1 (`ext/js/token.js`), GMO Elements card frames and Link-type payment pages name their processor and return `unknown` with `processor_variant_unverified`. Read the [GMO section of the README](./README.md#pay-a-gmo-payment-gateway-checkout) for what the SDK covers.
|
|
185
|
+
|
|
186
|
+
CyberSource Flex Microform (`cybersource_flex`) is identified from its loader script and its card field iframes on `flex.cybersource.com` and `testflex.cybersource.com`, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out and a Microform checkout stays `unknown`, even when your SDK build can pay it. Read the [CyberSource Flex section of the README](./README.md#pay-a-cybersource-flex-microform-checkout) for what the SDK covers.
|
|
187
|
+
|
|
188
|
+
Juspay (`juspay`) is not in this table. Juspay launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out. Swiggy's website sends its card requests to Juspay from its own code, with no Juspay script or iframe for preflight to find, so a Swiggy checkout stays `unknown` even when your SDK build can pay it. Juspay's hosted payment page (HyperCheckout, at `/orders/:order/payment-page` on `api.juspay.in`, `sandbox.juspay.in` or `api.juspay.io`) identifies Juspay and returns `unknown`, because the Vault does not take over the card request that page sends. Read the [Juspay section of the README](./README.md#pay-a-juspay-checkout) for what the SDK covers.
|
|
189
|
+
|
|
190
|
+
Datatrans Secure Fields (`datatrans`, PCI Proxy) has reviewed discovery rules for its `secure-fields-2.0.0` script and its card iframe on `pay.datatrans.com` and `pay.sandbox.datatrans.com`, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out, its assets are not evidence, and a Datatrans checkout stays `unknown`, even when your SDK build can pay it. A page that loads Secure Fields beside another processor's SDK reads exactly as it did before.
|
|
191
|
+
|
|
192
|
+
ACI Worldwide's COPYandPAY widget (`aci`) is identified from its widget script and its card iframe on `eu-prod.oppwa.com`, `oppwa.com`, `eu-test.oppwa.com` and `test.oppwa.com`, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()`, only through a prepared checkout, and only for an org Agentcard has enabled, so the bundled catalog leaves it out and an ACI checkout stays `unknown`, even when your SDK build can pay it. Read the [ACI section of the README](./README.md#pay-an-aci-copyandpay-checkout) for what the SDK covers.
|
|
193
|
+
|
|
194
|
+
Primer (`primer`) is identified from its Web SDK v2 script `PrimerCoreSDK.min.js` and its `hosted-input.html` and `api-controller.html` card frames on `sdk.primer.io`, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out and a Primer checkout stays `unknown`, even when your SDK build can pay it. Primer Checkout (`@primer-io/primer-js`), whose hosted api-controller lives under `/web/hosted-pages/`, names its processor and returns `unknown` with `processor_variant_unverified`. Read the [Primer section of the README](./README.md#pay-a-primer-checkout) for what the SDK covers.
|
|
195
|
+
|
|
196
|
+
Payrails (`payrails`) is identified from its web SDK v6 script (`assets.payrails.io/web-sdk/v6/payrails.js`) and its secure-frame v6 card fields, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out and a Payrails checkout stays `unknown`, even when your SDK build can pay it. Read the [Payrails section of the README](./README.md#pay-a-payrails-checkout) for what the SDK covers.
|
|
197
|
+
|
|
198
|
+
Worldpay eProtect (`worldpay_eprotect`) is identified from its JS API scripts, its iframe client and its payframe on `request.eprotect.vantivcnp.com` and `request.eprotect.vantivprelive.com`, but it is not in this table. It launches dark: the direct SDK takes it over only after `syncRegistry()`, only through a prepared checkout, and only for an org Agentcard has enabled, so the bundled catalog leaves it out and an eProtect checkout stays `unknown`, even when your SDK build can take it over. The same script served from a merchant-named domain identifies the processor and returns `unknown` with `processor_variant_unverified`. Read the [Worldpay eProtect section of the README](./README.md#prepare-a-worldpay-eprotect-checkout-dark-launch) for what the SDK covers.
|
|
199
|
+
|
|
200
|
+
WSPay Components (`wspay`) is identified from its component scripts and its card frame on `proxy.wspay.biz` and `proxy-test.wspay.biz`, but it is not in this table. It launches dark: the direct SDK pays it only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out and a WSPay checkout stays `unknown`, even when your SDK build can pay it. Monri Components on `ipg.monri.com` and the WSPay Form hosted page on `form.wspay.biz` name their processor and return `unknown` with `processor_variant_unverified`. Read the [WSPay section of the README](./README.md#pay-a-wspay-components-checkout) for what the SDK covers.
|
|
201
|
+
|
|
202
|
+
Shiji STS (`shiji_sts`), the card leg of MyCheck Wallet V3 at La Quinta by Wyndham, is identified from the in-page wallet script `wallet-sdk-v3.mycheckapp.com/{version}/static/js/main.js` (and its `-sandbox` and `-test` hosts) and from Shiji's proxy `cdn.shijipayment.com/sts/sts.proxy.v2.1.js` (and its `cdn.shijipayment.dev` copy), but it is not in this table. It launches dark: the direct SDK acts on it only after `syncRegistry()` and only for an org Agentcard has enabled, and even then it refuses every card request as card on file (`shiji_sts_keep_on_file`) until Agentcard can ask the cardholder to let a hotel keep the card, so the bundled catalog leaves it out and a Shiji checkout stays `unknown`. MyCheck's iframe wallet (`sdk.js`, `wallet-iframe.html`) and Shiji's `shijipayments.latest.min.js` name their processor and return `unknown` with `processor_variant_unverified`. Read the [Shiji STS section of the README](./README.md#shiji-sts-mycheck-wallet-v3).
|
|
203
|
+
|
|
182
204
|
The bundled direct SDK profile declares processor support for `one_time` purchases, with one exception. Gravy Secure Fields sends its card request as an HTTP PUT, and the SDK pauses and replays POST requests only, so a Gravy checkout returns `unsupported` with the reason `request_method_not_supported` in every card scenario until the SDK can intercept that method. 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.
|
|
183
205
|
|
|
184
206
|
The catalog also carries reviewed hosted, regional, and versioned variants observed on live checkouts: Adyen secured fields on the regional live hosts and any release, the Square card element frame, dLocal Smart Fields releases, Mercado Pago secure fields and the guest Checkout Pro card form, and the Rapyd hosted checkout page. A variant the implemented adapter does not admit, such as the Tranzila terminal-root page, the Authorize.Net hosted payment form, or a Worldpay hosted payment page, identifies its processor and returns `unknown` with `processor_variant_unverified`. A new fingerprint never declares payment support by itself.
|
|
185
207
|
|
|
186
208
|
Adyen's `supported` covers the Sessions payment request on Adyen's own hosts. Some Adyen merchants post the four encrypted fields to their own server instead, and their pages load the same secured fields, so an inspection identifies Adyen on both and cannot tell the two flows apart. The SDK pays a merchant's own endpoint only through a merchant profile Agentcard reviewed for it; the reviewed profiles (Dunelm and Cinemark) are in `observe`, so the SDK aborts their card requests and nothing is charged. The `actual_payment_request_validation` requirement is where that difference shows: check the paused request's host before treating an Adyen result as payable.
|
|
187
209
|
|
|
210
|
+
Authorize.Net Direct Post Method and SIM ship dark. The SDK pauses their `transact.dll` card form only for an org Agentcard enabled for them (capability `authorize_net_dpm_form`), and the bundled catalog leaves them out, so the table above does not list them and inspection answers for their forms exactly as it did before: the SIM hosted form on `secure.authorize.net` identifies Authorize.Net and returns `unknown` with `processor_variant_unverified`.
|
|
211
|
+
|
|
212
|
+
The catalog also names Pelecard, which ships dark: the API serves its recognizer only to an org Agentcard has enabled, in test mode only. Pelecard's hosted payment page and its payment scripts on `gateway21.pelecard.biz` and `gateway20.pelecard.biz` identify the processor and return `unknown`, because the bundled direct SDK profile declares no Pelecard support while it ships dark, even though an enabled org's SDK can pay the page's one-time card submission. The legacy 1.0 form on `gateway.pelecard.biz` returns `unknown` with `processor_variant_unverified`.
|
|
213
|
+
|
|
214
|
+
CreditGuard's hosted payment page (Hyp PPS) ships dark and is not in the table. A PPS page or its template script names `creditguard` and the result stays `unknown`; the legacy CGMPI page returns `processor_variant_unverified`. The direct SDK pays CreditGuard only under a prepared checkout, for a company Agentcard enabled for it (the README's "Pay a CreditGuard checkout"), so the bundled profile declares no CreditGuard support yet.
|
|
215
|
+
|
|
216
|
+
The catalog also identifies Elavon Converge's Hosted Payment Page, where NY DMV's payment apps send the browser, on `api.convergepay.com` and its demo host `api.demo.convergepay.com`, along with Converge's Lightbox and Checkout.js as unverified variants. Converge ships dark, so it is not in the table above and the bundled direct SDK profile declares no support for it: a Converge checkout names its processor and stays `unknown`. The SDK pauses Converge's card request only for an org Agentcard has enabled for Converge.
|
|
217
|
+
|
|
218
|
+
Amadeus Checkout (`amadeus_checkout`), which Air France and KLM run, ships dark and is not in the table above. Its Checkout Web SDK script and form-field frames on `prd.payment.amadeus.com` (and the `pdt` and `uat` copies) and its Data Collection Page on `paypages.payment.amadeus.com` name the processor, and the result stays `unknown`. The direct SDK pays an Amadeus card step only through a prepared checkout, for a company Agentcard enabled for it (the README's "Prepare an Amadeus Checkout card step"), and refuses Air France's and KLM's add until their expiry leg is supported, so the bundled profile declares no Amadeus support yet.
|
|
219
|
+
|
|
188
220
|
| Observed checkout | Classification |
|
|
189
221
|
| --- | --- |
|
|
190
222
|
| A compatible Stripe script, `one_time`, direct SDK | `supported` at `processor_integration` scope; `checkout_flow_status` remains `unknown`. |
|
|
@@ -195,6 +227,8 @@ Adyen's `supported` covers the Sessions payment request on Adyen's own hosts. So
|
|
|
195
227
|
| A single processor script during an incomplete scan | `unknown`; `psp` stays `null` and the script remains in `candidates` as `undetermined` until a complete scan confirms it. |
|
|
196
228
|
| Visible card controls in a nested frame on a site no evidenced processor owns | `unknown` with `card_entry_unrecognized`; a co-loaded SDK script is listed as a candidate, not as the processor. |
|
|
197
229
|
|
|
230
|
+
Reviewed merchant card endpoints are not processors. AT&T, Italo, Universal Orlando, Target Optical and Opus Virtual Offices post the card from their own checkout page to their own server, and the catalog carries no discovery rule for them, so an inspection of their checkout pages preserves `unknown`. The payment adapters recognize each merchant's exact card request (mode `card_endpoint`) and, while its profile is in observe, refuse it as `unsupported_checkout` before any authorization. All five are in observe; an `unknown` result there is not a path to payment.
|
|
231
|
+
|
|
198
232
|
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.
|
|
199
233
|
|
|
200
234
|
## Declare native capabilities
|