@agent-cards/sdk 0.23.9 → 0.23.11
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 +48 -0
- package/PREFLIGHT.md +7 -5
- package/README.md +211 -102
- package/dist/aci.d.ts +7 -5
- package/dist/aci.generated.d.ts +2 -1
- package/dist/aci.generated.js +14 -4
- package/dist/aci.js +28 -7
- package/dist/amadeus-checkout.generated.js +2 -2
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/card-fields.generated.js +165 -10
- package/dist/cdp.js +86 -34
- package/dist/client.d.ts +73 -33
- package/dist/client.js +136 -45
- package/dist/creditguard.generated.d.ts +1 -1
- package/dist/creditguard.generated.js +1 -3
- package/dist/cse-body.d.ts +7 -6
- package/dist/cse-body.js +8 -7
- package/dist/datatrans.generated.js +8 -5
- package/dist/elavon-converge.d.ts +5 -2
- package/dist/elavon-converge.generated.js +9 -5
- package/dist/elavon-converge.js +8 -4
- package/dist/fiserv.d.ts +9 -5
- package/dist/fiserv.generated.d.ts +3 -3
- package/dist/fiserv.generated.js +50 -20
- package/dist/fiserv.js +10 -6
- package/dist/lifecycle.d.ts +9 -1
- package/dist/lifecycle.js +34 -0
- package/dist/payrails.d.ts +78 -18
- package/dist/payrails.generated.d.ts +12 -2
- package/dist/payrails.generated.js +213 -18
- package/dist/payrails.js +165 -44
- package/dist/pre-claim.d.ts +7 -0
- package/dist/pre-claim.js +98 -36
- package/dist/preflight-capabilities.generated.d.ts +0 -106
- package/dist/preflight-capabilities.generated.js +0 -153
- package/dist/preflight-catalog.json +61 -181
- package/dist/preflight-schemas.json +6 -6
- package/dist/preflight.generated.d.ts +0 -106
- package/dist/preflight.generated.js +27 -15
- package/dist/preparation.d.ts +2 -0
- package/dist/preparation.js +4 -2
- package/dist/prepared-processor.d.ts +19 -5
- package/dist/prepared-processor.js +21 -5
- package/dist/primer.generated.d.ts +5 -1
- package/dist/primer.generated.js +202 -34
- package/dist/registry.d.ts +18 -12
- package/dist/registry.js +11 -8
- package/dist/shiji-sts.d.ts +24 -22
- package/dist/shiji-sts.generated.d.ts +1 -1
- package/dist/shiji-sts.generated.js +12 -8
- package/dist/shiji-sts.js +49 -46
- package/dist/stripe-checkout.generated.js +157 -49
- package/dist/verifone.generated.js +192 -17
- package/dist/verifone.js +1 -1
- package/dist/worldline-mycheckout.d.ts +27 -0
- package/dist/worldline-mycheckout.generated.d.ts +29 -0
- package/dist/worldline-mycheckout.generated.js +162 -0
- package/dist/worldline-mycheckout.js +93 -0
- package/dist/wspay.d.ts +17 -16
- package/dist/wspay.generated.d.ts +6 -1
- package/dist/wspay.generated.js +13 -3
- package/dist/wspay.js +9 -11
- package/examples/preflight/kernel-native/README.md +1 -1
- package/examples/preflight/kernel-native/inventory.json +1 -19
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Refuse a Worldline MyCheckout card submit whose card product is not the one its page chose. A MyCheckout page that offers several card products asks the shopper to choose one, then looks the typed number's IIN up with Worldline and switches the form to the product the answer names. With the agent's placeholder typed, that answer describes the placeholder: on 2026-10-12 CLZ's page read the Visa placeholder (411111) as Visa Electron (122) and switched the form from the Visa (1) the agent chose, and the cardholder's device, which checks only the card's network, would have submitted a Visa credit card as Visa Electron. Both adapters now remember the product each hosted checkout's select-payment-product step chose (that post carries no card and continues untouched) and abort a card submit that names another, before any create or prompt, with a `blocked` event, `worldline_mycheckout_product_changed`, or `worldline_mycheckout_product_missing` for one that names no product. Like the other per-request refusals it neither holds the attachment nor changes its state. A card-group page, and a hosted checkout whose choice the attachment never saw, are judged as before. `placeholderCard()` also takes `psp`, the processor whose card form the agent types into, so a processor can have its own placeholder for a network; none is set yet, so every processor still gets the network's default. Worldline stays dark for every company Agentcard has not turned it on for. No API or Vault release is needed.
|
|
6
|
+
|
|
7
|
+
- Keep a checkout's outcome when your code cancels the attachment after the checkout ended. `cancel()` rewrote every state: a checkout with an authorization or a card request in flight read `outcome_unknown` with reason `local_cancel`, and any other read `cancelled`, so an integration that cancels at cleanup lost a definite answer. On 2026-10-12 a Rapyd checkout the processor refused read `declined` (`processor_refused`) until the runner's cleanup cancel turned it into `outcome_unknown`; a `completed` checkout would have gone the same way. A checkout that reads `completed`, `declined`, `failed`, `timed_out`, `unsupported`, `cancelled` or `outcome_unknown` now keeps its status and reason through `cancel()` once no card request is in flight, or once the request in flight has its own outcome recorded, so an application that cancels from `onStateChange` or the `failed` event after a processor refusal reads `declined`. `cancel()` still stops polling, aborts any paused request and refuses every later card request, and reports no state change. A checkout still under way is unchanged, and so is one whose card request is still in flight with no outcome of its own, such as a request the page dropped mid-approval, since that authorization can still be approved on the cardholder's device: `outcome_unknown` with reason `local_cancel` once a card request is in flight or an authorization exists, `cancelled` before. No API or Vault release is needed.
|
|
8
|
+
|
|
9
|
+
- Pay IKEA US's ACI checkout as its live payment step sends it. With ACI's ReD Shield screening on, the widget posts the device fingerprint, `customer.browserFingerprint.value` alone, to the checkout's card URL on load, and 0.23.9 refused it as `aci_unsupported_request`. That refusal also failed the checkout's CVC request at once whenever it reached the SDK before the card-number request at Pay, so the widget's Pay failed. The fingerprint now continues untouched, up to the 4,096 characters ACI takes; a longer one is still refused, and a refused request that names no card number no longer fails the checkout's CVC or expiry requests, which wait for the card-number request as before. `/payment` now continues with `shopperResultTarget=_top`, the value IKEA's widget options set and ACI's own default for its final redirect, which 0.23.9 refused after the cardholder's device had already sent the card; any other target is still refused as `aci_unsupported_request`. No API or Vault release is needed.
|
|
10
|
+
|
|
11
|
+
- Pay an APCOA airport drop-off entry on NMI's hosted payment page (`ekashu`). Every APCOA entry carries APCOA's own ASP.NET Core anti-forgery token, `__RequestVerificationToken`, and the API refused it as a field of NMI's card page (`hosted_form_field_refused`, reason `not_an_entry`), so an attached checkout at Heathrow's drop-off could not get past the create. The API now takes the merchant's token and still refuses an entry that carries `ekashu_stage`, `ekashu_context` or `ekashu_submission_id`. No SDK upgrade is needed: the API takes the entry once it deploys, and the cardholder's phone fills NMI's card page from the next Vault release. NMI stays off for every company Agentcard has not turned it on for.
|
|
12
|
+
|
|
13
|
+
- Prepare a CreditGuard page whose merchant turned retries off. CreditGuard's transaction read counts in `remainingSubmitRetries` the submits it still takes after a failed one, and such a merchant reads 0 before anything is submitted, as Dan Hotels' gift voucher page (MID 19006) did on 2026-10-10. The API read that 0 as a spent transaction and refused the preparation as `creditguard_transaction_refused` with the detail `no_retries_left`, before the cardholder was asked. It now prepares the page, whose first submit is the payment, and no refusal names `no_retries_left`. The SDK's copy of the CreditGuard rules changes with it and no SDK call behaves differently; the matching API release is required. Dan Hotels' page is still refused, as `three_d_secure`, and CreditGuard stays dark for every company Agentcard has not turned it on for.
|
|
14
|
+
|
|
15
|
+
- Pause a Datatrans card post whose expiry the merchant's own form keeps. RaiseNow's donation widget (Tamaro, merchant `3000022877`) collects the expiry in its own field and sends it to RaiseNow beside the token, so its card post carries no `expm` or `expy`, and earlier releases refused it in the browser as `invalid_datatrans_request` before any create. The post now pauses like any other, and the cardholder's device writes the card number and CVV and adds no expiry, as the page sent none. Type the card's real expiry (`placeholderCard()`) into the merchant's own expiry field: the merchant charges with the expiry its form holds. A post with only one of the two, or with no expiry while it asks to keep the card on file, is still refused as `invalid_datatrans_request`. Datatrans stays dark for every company Agentcard has not enabled, no live Datatrans merchant is reviewed yet, and a payment also needs the matching API and Vault releases.
|
|
16
|
+
|
|
17
|
+
- Pay Air France's and KLM's Amadeus card step with the expiry your agent typed into the airline's own form. Both airlines keep the card's expiry in a field of their own and send it to their own server, so the Checkout Web SDK's add carries an empty `expmonth` and `expyear`, and 0.23.9 refused that add in the browser with `amadeus_merchant_held_expiry`, before any row or prompt. The add now binds the preparation, and the cardholder's device writes the stored card's own month and year into it beside the real card. Type `placeholderCard()`'s `expiryMonth` and `expiryYear` into the airline's expiry field, and its `number` and `securityCode` into Amadeus's card fields. `prepare({ psp: 'amadeus_checkout' })` now needs `cardId`, the card whose expiry you typed (`card_required`), and the approval is locked to that card; a ready checkout naming another card reads `ready_unconfirmed`. Amadeus stays dark: only a company Agentcard turned it on for is served it.
|
|
18
|
+
|
|
19
|
+
- Read The Container Store's Place Order request (`POST https://www.containerstore.com/checkout/api/submit`, a new card alone in `paymentMethods`) as its reviewed Verifone card request. Its profile (`containerstore_checkout`) stays in `observe` with no key pinned, so for a company Agentcard turned Verifone on for, the adapters still abort that request before it leaves the browser and report `verifone_profile_observed`, now with the reason that Agentcard has not reviewed The Container Store's key. A body with a gift card, a second payment method, a saved card, `defaultWallet` set or a loyalty enrollment is refused by the request's rules, and any other blob-bearing request there aborts as before. Verifone stays off for every other company. The cardholder's device can now encrypt under a Verifone key on secp256k1, the curve The Container Store's live key is on; the SDK itself never encrypts.
|
|
20
|
+
|
|
21
|
+
- Pay a Gravy (Gr4vy) Secure Fields checkout, such as Trek Bicycle's, for a company Agentcard turned Gravy on for (dark launch). Gravy's card request is a `PUT` to `/checkout/sessions/<session id>/fields` on the merchant's own `api.<merchant>.gr4vy.app` (`api.sandbox.<merchant>.gr4vy.app` in test), sent from Secure Fields' hidden controller frame, and earlier releases paused only a `POST`, so that request reached Gravy with the card your agent typed. The sync now also asks for `capabilities=gravy_session_fields_put`, and the API serves Gravy's recognizer, which names its method in `request.method`, only to an enabled company. There both adapters pause the `PUT` from the frame, `authorize()` creates the authorization with it, the cardholder's device sends the card to Gravy as the same `PUT`, and the frame receives Gravy's answer, a `204` with no body, under a CORS answer for its own origin. A `POST` to that URL is not Gravy's card request and continues untouched, and `authorize()` refuses any method but `PUT` there before a call. An update that carries a card anywhere but `payment_method`, or no new card, such as a stored method, fails in the frame before any create, and the API refuses one sent directly as `invalid_gravy_request`. Every other company keeps today's path, where the request continues to Gravy untouched. Gravy's request names no amount, so the cardholder approves the `amount` and `currency` you pass, or else the page total the adapter reads. TypeScript: `Recognizer.request.method` and `recognizerRequestMethod()` can be `PUT`. A payment also needs the matching API and Vault releases.
|
|
22
|
+
|
|
23
|
+
- Name Gravy in a preflight inspection from the script its merchants load, `/secure-fields/latest/secure-fields.js` on `cdn.<merchant>.gr4vy.app` or `cdn.sandbox.<merchant>.gr4vy.app`. The rule read `/secure-fields.js`, a path no Gravy instance serves, so no live Gravy checkout was named. While Gravy ships dark the result is `unknown`, and the bundled profile no longer declares Gravy, so no inspection reads `unsupported` with `request_method_not_supported`. The catalog's `catalog_sha256` changes; `catalog_version` stays `2026-09-15.1`.
|
|
24
|
+
|
|
25
|
+
- Pay a Wyndham hotel booking through Shiji STS (MyCheck Wallet V3), for a company Agentcard turned Shiji STS on for. Wyndham's wallet sends its `getTokenId` with no `keySequence`, because its merchant records hold no `clientKey`, and the SDK refused every Shiji `getTokenId` in the browser as `shiji_sts_keep_on_file` while the API could bind none without a `keySequence`. The SDK now pauses that request for the one prompt, writes the cardholder's `pan` and `expires` over the page's own and continues it, then continues the page's `getCvvId` once with the cardholder's CVV under the key whose SHA-256 the API serves with the approval. That field is now `shiji_sts_companion.key_sequence_sha256` and replaces `key_sequences`: an approval in the old shape resolves as `PaymentOutcomeUnknownError` (`cse_substitutions_malformed`) and nothing continues. The cardholder approves with a card they stored, under a line that says the hotel can keep it on file, and the API refuses a card a company added with `409 card_not_stored`. Shiji STS stays dark for every company Agentcard has not turned on, and a payment also needs the matching API and Vault releases.
|
|
26
|
+
|
|
27
|
+
- Hold a Tranzila card form to one charge that reports to the merchant or to Tranzila, read the way Tranzila's server reads it. Tranzila's own card form, on `direct.tranzila.com` and `directng.tranzila.com`, names its callbacks `success_url`, `fail_url` and `notify_url`, and the API held only the `*_url_address` names the merchant posts to Tranzila to the merchant's host. It now holds all six to the merchant's host or to Tranzila's own result page exactly (`https://direct.tranzila.com/done/`, `https://directng.tranzila.com/process/fail`) and refuses any other with `callback_host`. A form that asks for installments, credit or recurring billing (`cred_type` or `tash` other than 1, `npay` other than 0, any `fpay`, `spay` or `recur_*` value, a checked `make_recur_transaction`) is refused with `special_flow` where it passed as a plain sale. Tranzila's PHP server acts on the last copy of a repeated field and reads `cred.type` as `cred_type`, while the API read the first copy under the name as written, so a second `sum` could charge another amount than the one approved: a field posted twice with different values is now refused with `duplicate_field`, and a name PHP renames with `malformed_field`.
|
|
28
|
+
|
|
29
|
+
- Pay a Tranzila card form that carries Tranzila's own ALTCHA proof of work. Every Tranzila card form read on 2026-10-10 (`iframenew.php` on `direct.tranzila.com` and `directng.tranzila.com`, the legacy `iframe.php` and the terminal page) runs an ALTCHA widget that searches for the number whose SHA-256 with the page's salt is its challenge, writes that proof into `altcha` and only then submits, and the API refused every such form with `hosted_form_gated`. The API now takes that one field, on Tranzila only, when it holds one ALTCHA proof whose hash holds, and the cardholder's device sends it once with the card, as the page wrote it. Anything else in `altcha` is refused with `hosted_form_field_refused`, reason `malformed_field`, and every other filled-in challenge field (reCAPTCHA, hCaptcha, Turnstile, or `altcha` on another processor) is still `hosted_form_gated`. No SDK or Vault release is needed: the API takes the form once it deploys.
|
|
30
|
+
|
|
31
|
+
- Pause an Elavon Converge payment page opened on `www.convergepay.com`, where every Converge Buy Button and pay link sends the buyer, for a company Agentcard turned Converge on for. That page posts the card to its own origin, `https://www.convergepay.com/hosted-payments/service/payment/hpp/process`, and the SDK recognized the process call only on `api.convergepay.com` and the demo host, so the agent's placeholder card reached Converge. `www.convergepay.com` is a production host: a test row never pays there. A Buy Button's page also sends `recurring` as `"false"` in every request; that one-time sale now pauses where it was refused as `converge_recurring_refused`, and `"true"` or any other value is still refused.
|
|
32
|
+
|
|
33
|
+
- Pause an Elavon Converge payment page with its CAPTCHA on once a person solved it, for a company Agentcard turned Converge on for. Every Buy Button and pay link page read so far shows a reCAPTCHA and sends its card request only after it is solved, with the answer in `captchaToken`, and earlier releases refused every such request as `converge_captcha_refused` before any create. The request now pauses like any other, and the cardholder's device sends the answer to Converge unchanged beside the card. A person solves the CAPTCHA in the browser, never your agent, and Google takes the answer once, for two minutes after the solve, so the cardholder approves inside that window. A `captchaToken` that is empty, not text, longer than 4,096 characters, or holds a character other than `A-Z`, `a-z`, `0-9`, `_` and `-` is still refused as `converge_captcha_refused`. A payment also needs the matching API and Vault releases.
|
|
34
|
+
|
|
35
|
+
- Answer a prepared Bambora checkout inside Custom Checkout's 5 seconds. The card frame fails its tokenization request 5 seconds after Pay, and 0.23.9 read a prepared Bambora approval every 2 seconds, so a cardholder's answer that missed the first read waited for the read 4 seconds after the bind, at or past the frame's timer. The SDK now reads it every 100 ms for its first 10 seconds, and the API's bind names that interval on the row, so no read is refused with `slow_down`. When the frame gives up first anyway, the approval now outlives it, as an unprepared one does: once the device answers, the controller reads `ready_to_submit` with reason `awaiting_merchant_retry`, and when the merchant's next Pay click sends the same request again from the same card frame, the SDK answers it from the same approval with no second prompt. The approval stays with that card frame: the SDK refuses the same request from any other frame, and the page removing the card frame stops the attachment, as it does while the request is still paused, so a replacement frame never receives the token. 0.23.9 ended that checkout `outcome_unknown` and needed a new attachment and a second approval. Every other prepared checkout still answers only the request it was bound to. A payment also needs the matching API release.
|
|
36
|
+
|
|
37
|
+
- Finish a prepared Mercado Pago checkout again, with no SDK change. The SDK reads a prepared Mercado Pago approval every 500 ms for its first 10 seconds, and since 2026-09-29 the API answered a read sooner than 2 seconds after the last with 400 `slow_down`, which the SDK reads as a lost poll: the checkout ended `outcome_unknown` with reason `authorization_poll_failed` unless the cardholder's device answered within the first second. The API's bind now names 500 ms on a prepared Mercado Pago row.
|
|
38
|
+
|
|
39
|
+
- Hold every prepared checkout to the card the cardholder approved for it, with no SDK change. The Vault page pays only with that card, but the API's last check before a card leaves took any card the page named, and `voice.authorizations.setCard` moved a prepared checkout to any of the person's cards. So a card a company added could pay, with its number handed to the page, at a merchant that keeps the card on file (Worldpay eProtect, CyberSource Secure Acceptance, Fiserv), without the company's consent. On a prepared checkout, `setCard` and that check now answer 409 `card_not_stored` for a card a company added and 409 `preparation_card_locked` for any other card, before any card leaves, and the checkout stays open for the approved card. It takes effect when the API deploys.
|
|
40
|
+
|
|
41
|
+
- Pay FlixBus's guest checkout through the Payrails card form, for a company Agentcard turned Payrails on for. FlixBus runs Payrails web SDK 5.50.0: its Pay now button posts the card's ciphertext inside `paymentComposition` to the execution's authorize link, `/public/merchant/workflows/payment-acceptance/executions/{id}/authorize`, on FlixBus's own Payrails host, `api-pub.flix.payrails.io`, and its page receives the Payrails session six levels inside `/payment/configuration/list`. 0.23.9 read a session only at the top of an answer or one level down, took only `api-pub.payrails.io` and its two staging hosts, and aborted every card-form payment as `unsupported_payrails_card_payment`. The adapters now read the init payload anywhere in an answer's first eight levels, take a merchant's own `api-pub.<merchant>.payrails.io`, and pause the card form's payment once it binds to the session its token, execution, host and `providerConfigId` name. The create carries the session's key and its `holderReference` (`request.payrails.holder_reference`), which the payment's ciphertext carries, and needs no `amount`, since the payment names it. The cardholder's device encrypts the real card and sends the payment itself, and the page receives Payrails' 202 rebuilt to the authorize action's name, id, time and execution link, which the page's SDK then polls for the issuer's answer, a 3-D Secure challenge included. An action whose execution link names another execution, or this one on another host, never reaches the page, since the page would poll another payment's result: `authorize()` throws `PaymentOutcomeUnknownError` (`payrails_answer_unconfirmed`). A payment that stores the card at the merchant aborts as `payrails_card_on_file_consent_required`, as does one whose `meta.order.processingType` is `CardOnFile` or `UnscheduledCardOnFile`, and one that sets up a subscription (`meta.subscription`, or `processingType: 'Subscription'`) as `payrails_future_usage_refused`. The rest of `meta` is read against an allow-list, with keys compared in any case because Payrails reads them that way: anything but the SDK's `clientContext` facts and fraud session, `risk.threeDSMode: 'Default'`, `risk` skip flags set `false`, an `order` with only `processingType: 'Regular'` and an empty `customer` aborts as `unsupported_payrails_card_payment`, a mail order, a skipped or exempted 3-D Secure challenge, a funds transfer, a split across sub-merchants and a key that differs from another only in case included; a stored card's CVC, a split or installment payment and a preferred scheme still abort as `unsupported_payrails_card_payment`. A payment also needs the matching API and Vault releases.
|
|
42
|
+
|
|
43
|
+
- Pay a hotel's WSPay card guarantee, which keeps the card on file. Valamar's payment step authorizes EUR 1.00 and sets `tokenize_pan: true` on every booking, so WSPay keeps the card for the stay, and 0.23.9 aborted that confirm with a `blocked` event, `wspay_keep_on_file_unsupported`, before anything was created. The adapters now pause it like any other confirm, and the API creates it only as a EUR 1.00 guarantee (`amount: 100, currency: 'eur'`) paid with a card the cardholder stored: any other amount fails the create with `wspay_keep_on_file_unsupported`, and a card a company added with `card_not_stored`. The cardholder's approval says the merchant keeps the card on file, and the frame receives the token WSPay keeps for the merchant (`pan_token`), never the card's expiry or masked number. The API serves WSPay's answer for 15 minutes after the approval, then drops it, and a later read gets `response_expired`. TypeScript: `WspayRefusalReason` is now `unsupported_wspay_payment_method` alone. A payment also needs the matching API release.
|
|
44
|
+
|
|
45
|
+
- Pay a Fiserv checkout at Blinds.com or homedepot.com with `prepare({ psp: 'fiserv', environment: 'production', merchantProfile: 'homedepot_orangepay' })` and `merchant: 'Home Depot'`. Their card frame encrypts under a session key Home Depot's server hands it, a 36-character id that changed twice between 2026-09-30 and 2026-10-11, and the SDK read that key as one nobody pinned, so it refused every such capture. A capture that names Home Depot's Commerce Hub merchant (`TZOPBKED`) under a session key now binds to that preparation, and `substituteFiservEnvelope(body, substitutions, url)`, given the capture's own URL, writes the envelope the cardholder's device sealed under the key Home Depot publishes for that endpoint, that key's id included, over the session's; without the URL it refuses a session's key. A capture under any other 32-character key, or for a merchant no reviewed key lists, is still refused. A payment also needs the matching API and Vault releases.
|
|
46
|
+
|
|
47
|
+
- Take a live NMI entry (`ekashu`) only from a seller Agentcard reviewed, and pay it only with a card the person stored. The entry's terminal id (`ekashu_seller_id`) names the merchant the cardholder approves and the hosts NMI may send them and its result to. Heathrow Drop-off is the one reviewed seller, so a live entry from any other terminal is refused at create with `hosted_form_field_refused`, reason `seller_unreviewed`, and one whose result or callback URL leaves that seller's hosts with reason `callback_host`. The authorization's `merchant` is the seller's name, whatever name you sent, and an authorization whose stored entry the API would now refuse is declined before the cardholder's phone sends anything, with reason `invalid_ekashu_entry`. On NMI's test host a result URL must sit exactly on the host you name as `merchant`; a subdomain of it no longer passes. NMI sends the merchant a reusable card reference with every payment, so a card your company added to the person's Vault cannot pay an NMI checkout: naming one at create, through `voice.authorizations.setCard` or at the cardholder's approval answers 409 `card_not_stored`, and no read offers one. NMI stays off for every company Agentcard has not turned it on for.
|
|
48
|
+
|
|
49
|
+
- Pay Moneris Hosted Tokenization, Raisin's donation card frame, through the checkout relay, for a company Agentcard turns Moneris on for. Moneris's card frame posts the number, expiry and CVD to `request.php` as `input_data`, `input_exp` and `input_cvd` only when the merchant's frame URL sets `enable_exp=1` and `enable_cvd=1`, as Raisin's donation pages do. Earlier releases paused every `request.php` post for every company and asked the cardholder to approve it, and the Vault then refused each one after the approval, because it read neither `input_data` nor `input_cvd` and `request.php` answers no browser origin. Moneris now ships dark: this build declares `moneris_hosted_tokenization` on every sync, and the API serves the Moneris entry only to a company Agentcard turned Moneris on for, so every other company's `request.php` posts go through untouched, as they do for an unsupported processor. For an enabled company the SDK pauses only the body that carries all three card fields, sent to `request.php` on www3, gateway or esqa.moneris.com exactly as the frame sends it, and fails any other `request.php` post in the browser with a `blocked` event, `request_without_card`, before anyone is asked; the API answers its create with `card_fields_missing`, or `invalid_moneris_request` for a URL the relay does not carry. A live payment needs a merchant Agentcard reviewed: the profile id the frame names must be one pinned for the checkout page's origin (Jack.org's Raisin page today), or the create answers `unsupported_checkout`. The cardholder's device sends the card through the checkout relay, and the page gets Moneris's temporary token (`responseCode`, `dataKey`, `bin`, `errorMessage`), which the merchant charges from its own server. Moneris answers a refusal, codes 940 to 945, inside HTTP 200. The refusal declines the approval and fails the paused request, so the frame posts nothing to the merchant's page and the page keeps waiting: reload it and attach again rather than pressing Pay twice. request.php names no price, so `authorize()` refuses a Moneris request without `amount` above zero and `currency` (`AmountRequiredError`), and the API refuses the same create as `amount_required`. A live authorization names the merchant of the reviewed profile, Jack.org, whatever `merchant` you send. A Moneris payment also needs the matching API, Vault and checkout relay releases.
|
|
50
|
+
|
|
51
|
+
- Pay a live Primer checkout. A merchant's client session can save the card after the payment with no sign in the tokenization request, so the API refused every live Primer create (400 `invalid_primer_request`, reason `live_keep_on_file`) and the SDK aborted the request. The API now creates the authorization when the create names the checkout page's https origin (`checkout_origin`, which the SDK sends from the page's origin), and only a card the cardholder stored pays. The cardholder's approval says the merchant keeps the card on file and names it as the `merchant` you sent, which Agentcard cannot confirm, since nothing in the request names the Primer merchant whose session keeps the card. A live create with no https checkout page is refused with reason `checkout_origin_required`, and a card a company added with 409 `card_not_stored`. A tokenization that asks Primer itself to save the card is still aborted as `primer_keep_on_file`. A payment also needs the matching API and Vault releases.
|
|
52
|
+
|
|
5
53
|
- Hand Arrow Electronics' token page to its frame when CyberSource's payment token is numeric. CyberSource gives a merchant set up before 2019 a `payment_token` of 22, 19 or 16 digits, and 0.23.8 judged every token but 32 hex characters as `token_shape`, so an approved Arrow save on 2026-10-10 ended `outcome_unknown` (`secure_acceptance_reply_late`) although CyberSource had answered it. The reply rule now takes each format CyberSource documents; a token of any other length or alphabet still reads `token_shape`. The card-free check skips a numeric token as it skips the instrument identifier, because CyberSource's 16- and 19-digit formats pass the card check digit; the device, which holds the card, still refuses a token equal to the card's number. A payment also needs the matching API and Vault releases.
|
|
6
54
|
|
|
7
55
|
- Pay Arrow Electronics' card save as its live checkout signs it. Arrow's server adds an id of its own, `merchant_defined_data8` (digits), to the form and to the end of `unsigned_field_names` when it signs the save, and 0.23.7 refused that request with `secure_acceptance_unsigned_fields_unreviewed` on 2026-10-10, after the cardholder approved and before any card was sent. The request now passes with that field or without it; a list that names it anywhere but last, names it twice or posts it unlisted is still refused, and a value other than at most 20 digits is refused as `secure_acceptance_merchant_reference`. Nothing else about Arrow's lists changed. A payment also needs the matching API and Vault releases.
|
package/PREFLIGHT.md
CHANGED
|
@@ -172,10 +172,8 @@ The catalog includes reviewed discovery rules and direct SDK implementation capa
|
|
|
172
172
|
| Paysafe | `token` |
|
|
173
173
|
| Recurly | `token` |
|
|
174
174
|
| Spreedly | `token` |
|
|
175
|
-
| Moneris | `token` |
|
|
176
175
|
| Bambora | `token` |
|
|
177
176
|
| Global Payments | `token` |
|
|
178
|
-
| Gravy | `token`, reported `unsupported` |
|
|
179
177
|
|
|
180
178
|
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
179
|
|
|
@@ -183,6 +181,8 @@ NMI's hosted payment page (formerly eKashu) is not in the table either. Agentcar
|
|
|
183
181
|
|
|
184
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.
|
|
185
183
|
|
|
184
|
+
Moneris Hosted Tokenization (`moneris`) is identified from its card frame, `/HPPtoken/index.php` on `www3.moneris.com` and `esqa.moneris.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 Moneris checkout stays `unknown`, even when your SDK build can pay it. The frame on `mpg1t.moneris.io` names its processor and returns `unknown` with `processor_variant_unverified`.
|
|
185
|
+
|
|
186
186
|
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.
|
|
187
187
|
|
|
188
188
|
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.
|
|
@@ -203,7 +203,9 @@ WSPay Components (`wspay`) is identified from its component scripts and its card
|
|
|
203
203
|
|
|
204
204
|
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).
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
Gravy Secure Fields (`gravy`) is identified from the loader its merchants load, `/secure-fields/latest/secure-fields.js` on `cdn.<merchant>.gr4vy.app` (or `cdn.sandbox.<merchant>.gr4vy.app`), but it is not in this table. It launches dark: the direct SDK pauses Gravy's card request, a `PUT` from Gravy's controller frame, only after `syncRegistry()` and only for an org Agentcard has enabled, so the bundled catalog leaves it out and a Gravy checkout stays `unknown`.
|
|
207
|
+
|
|
208
|
+
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.
|
|
207
209
|
|
|
208
210
|
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.
|
|
209
211
|
|
|
@@ -219,9 +221,9 @@ The catalog also names Pelecard, which ships dark: the API serves its recognizer
|
|
|
219
221
|
|
|
220
222
|
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.
|
|
221
223
|
|
|
222
|
-
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.
|
|
224
|
+
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`, and on `www.convergepay.com`, where every Converge Buy Button and pay link opens it, 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.
|
|
223
225
|
|
|
224
|
-
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
|
|
226
|
+
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 locked to its card, for a company Agentcard enabled for it (the README's "Prepare an Amadeus Checkout card step"), and Air France and KLM take the expiry the agent typed into their own form. It ships dark, so the bundled profile declares no Amadeus support yet.
|
|
225
227
|
|
|
226
228
|
| Observed checkout | Classification |
|
|
227
229
|
| --- | --- |
|