@agent-cards/sdk 0.20.0 → 0.21.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 +4 -0
- package/PREFLIGHT.md +4 -0
- package/README.md +153 -0
- package/dist/cdp.d.ts +2 -1
- package/dist/cdp.js +161 -31
- package/dist/client.d.ts +97 -1
- package/dist/client.js +172 -5
- 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/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/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/lifecycle.d.ts +8 -3
- package/dist/lifecycle.js +6 -2
- package/dist/pre-claim.d.ts +12 -1
- package/dist/pre-claim.js +135 -9
- package/dist/preflight-catalog.json +116 -0
- package/dist/preflight-schemas.json +8 -0
- package/dist/preflight.generated.js +15 -1
- package/dist/prepared-processor.d.ts +4 -2
- package/dist/prepared-processor.js +12 -2
- package/dist/registry.d.ts +17 -7
- package/dist/stripe-checkout.generated.js +37 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- 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.
|
|
6
|
+
|
|
5
7
|
- 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
8
|
|
|
7
9
|
- 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
10
|
|
|
11
|
+
- 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.
|
|
12
|
+
|
|
9
13
|
## 1.3.2
|
|
10
14
|
|
|
11
15
|
- **`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,6 +179,10 @@ 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
|
+
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.
|
|
183
|
+
|
|
184
|
+
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.
|
|
185
|
+
|
|
182
186
|
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
187
|
|
|
184
188
|
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.
|
package/README.md
CHANGED
|
@@ -238,6 +238,8 @@ Coverage is specific to the processor request format, merchant setup, browser tr
|
|
|
238
238
|
| Tranzila | supported (mode `hosted_form`): the cardholder finishes on Tranzila's own page; the paused form navigation resolves to a synthetic page, and you poll the merchant's order state |
|
|
239
239
|
| Fiserv Commerce Hub | implemented (mode `cse`, prepared checkout only) and off until Agentcard turns it on for your company: the card frame's card capture on `connect.fiservapis.com` (or `connect-cert.fiservapis.com` in the sandbox), with the approved card encrypted on the cardholder's device under a key Agentcard reviewed for the merchant. A merchant whose frame posts to Fiserv's `payment-link` endpoint is not recognized. No live merchant purchase is verified yet |
|
|
240
240
|
| Gravy (Gr4vy) Secure Fields | not supported: recognized, not intercepted, and the preflight reports `unsupported` with `request_method_not_supported`. The card request is Secure Fields' update of a checkout session: a JSON body to `/checkout/sessions/<session id>/fields` on the merchant's own host `api.<merchant>.gr4vy.app` (sandbox: `api.sandbox.<merchant>.gr4vy.app`), carrying `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 today the SDK recognizes the destination but the request continues to Gravy untouched. The shape follows Gravy's published Secure Fields contract and is not confirmed by a capture from a live merchant form. Updating the session stores the card with Gravy; the merchant creates the transaction from the session on its own server, so a completed request is not a payment. Gravy Embed, the hosted frame on `embed.<merchant>.gr4vy.app`, is not covered |
|
|
241
|
+
| GMO Payment Gateway | dark launch (mode `token`): only for an org Agentcard has enabled; see [Pay a GMO Payment Gateway checkout](#pay-a-gmo-payment-gateway-checkout) |
|
|
242
|
+
| CyberSource Flex Microform | dark launch: Microform 2.12.1 card fields only, after `vault.syncRegistry()`, and only for an org Agentcard has enabled. For any other org the API does not serve the recognizer, so nothing pauses there. The cardholder's device seals the card for CyberSource and the card field receives the transient token. Validated in local Chromium; no live merchant purchase yet. See [Pay a CyberSource Flex Microform checkout](#pay-a-cybersource-flex-microform-checkout) |
|
|
241
243
|
|
|
242
244
|
The recognizer list, and the status of each reviewed Adyen merchant profile on
|
|
243
245
|
your client, are fetched from the API at runtime (`agentcard.checkout.syncRegistry()`),
|
|
@@ -338,6 +340,11 @@ three; the difference matters if you drive `authorize()` yourself.
|
|
|
338
340
|
`syncRegistry()` asks the API for `SUPPORTED_MODES` only
|
|
339
341
|
(`token,cse,hosted_form`), so a processor whose flow this build cannot finish
|
|
340
342
|
is never paused; the API serves `hosted_form` entries only to callers that ask.
|
|
343
|
+
It also declares `SUPPORTED_CAPABILITIES` (`capture_context`), the dark-launch
|
|
344
|
+
half of the same negotiation: a processor gated behind a capability is served
|
|
345
|
+
only to a build that declares it and never sits in the built-in list, so it is
|
|
346
|
+
paused only after a sync. A registry entry naming a capability this build does
|
|
347
|
+
not declare throws `UnsupportedCapabilityError` before creation.
|
|
341
348
|
A registry mode this SDK cannot finish throws `UnsupportedModeError` before
|
|
342
349
|
creation. An approval returned in an unexpected mode has an unknown outcome
|
|
343
350
|
and holds the attachment for reconciliation. The `authorized` event's detail names
|
|
@@ -421,6 +428,10 @@ one. `amountAuthority` on every replay is `stripe_payment_intent`,
|
|
|
421
428
|
that is not turned on, not offered to your account, or whose key or checkout
|
|
422
429
|
page changed, throws `CheckoutPreparationError` with the API's code as its
|
|
423
430
|
`reason`.
|
|
431
|
+
- `AmountRequiredError` (`code: 'amount_required'`): the processor's request
|
|
432
|
+
names no amount (GMO) and you passed none, so there is nothing for the
|
|
433
|
+
cardholder to approve. Thrown before anything is created; terminal for that
|
|
434
|
+
page. Pass `amount` and `currency`.
|
|
424
435
|
- `CardEncryptedError`: this processor encrypts the card in-page and its
|
|
425
436
|
registry entry does not (yet) say the vault can produce that ciphertext;
|
|
426
437
|
route the purchase to an Agentcard-issued card instead.
|
|
@@ -432,6 +443,20 @@ one. `amountAuthority` on every replay is `stripe_payment_intent`,
|
|
|
432
443
|
was created and nothing was charged; call `prepareCheckout()` first. The
|
|
433
444
|
adapters refuse such a request before it pauses, with the controller reason
|
|
434
445
|
`preparation_required`.
|
|
446
|
+
- `UnsupportedCapabilityError`: the registry entry is gated behind a
|
|
447
|
+
dark-launch capability this build does not declare. Only a hand-built
|
|
448
|
+
registry can hold one. Upgrade.
|
|
449
|
+
- CyberSource Flex refusals at create, all terminal for that page:
|
|
450
|
+
`CheckoutApiError` with `code` `processor_unavailable` (403, not enabled for
|
|
451
|
+
your org), `capture_context_required`, `capture_context_invalid` (with a
|
|
452
|
+
`reason`), `capture_context_mismatch`, `cybersource_environment_mismatch` (a
|
|
453
|
+
test capture context from a live client, or the reverse),
|
|
454
|
+
`microform_unsupported` or `invalid_cybersource_request` (400). An approved
|
|
455
|
+
Flex authorization whose answer is not a transient token raises
|
|
456
|
+
`PaymentOutcomeUnknownError` with reason `cybersource_flex_token_unconfirmed`.
|
|
457
|
+
- `PlaceholderCardError`: `placeholderCard()` found no such stored card
|
|
458
|
+
(`card_not_found`), no placeholder for its network (`brand_unsupported`), or
|
|
459
|
+
no expiry on it (`expiry_unknown`). Nothing was created.
|
|
435
460
|
- `SubstitutionError`: a `cse` approval could not be written into the paused
|
|
436
461
|
body (the four encrypted fields were not there). The request is failed and
|
|
437
462
|
the next one is judged afresh.
|
|
@@ -668,6 +693,7 @@ await page.getByRole('button', { name: 'Pay', exact: true }).click();
|
|
|
668
693
|
| Spreedly | `shared` | Native iframe JSON POST to `/v1/payment_methods/restricted.json` on `core.spreedly.com` |
|
|
669
694
|
| Adyen | `production` or `sandbox` | The Sessions `/checkoutshopper/v1/sessions/{id}/payments` POST on the matching Adyen host family (`sandbox` is `checkoutshopper-test.adyen.com` with a `test_` client key; `production` is the live hosts with a `live_` key), carrying a fresh card's four encrypted fields |
|
|
670
695
|
| Fiserv | `production` or `sandbox`, with `merchantProfile` | The card frame's `/ch/payments-vas/v1/card-capture` POST on `connect.fiservapis.com` (`production`) or `connect-cert.fiservapis.com` (`sandbox`), carrying a new card's envelope under the key `merchantProfile` names |
|
|
696
|
+
| CyberSource Flex | `production` or `sandbox` | A Microform 2.12.1 card field's `application/jwt` POST to `/flex/v2/tokens` on `flex.cybersource.com` (`production`) or `testflex.cybersource.com` (`sandbox`), sealed under the capture context the field was loaded with |
|
|
671
697
|
|
|
672
698
|
Use `environment: 'shared'` for Bambora, Mercado Pago, Recurly and Spreedly because the same endpoint serves test and live requests. Agentcard cannot establish the processor's test mode from that URL or a credential prefix. Configure test mode through the merchant's processor account when testing. Agentcard's own `sandbox` flag remains separate. Prepared Worldpay, Bambora, Mercado Pago and Recurly requests reject saved-card and recurring request bodies; a refused request retires the local preparation. Reconcile any existing merchant attempt before creating a new attachment.
|
|
673
699
|
|
|
@@ -779,6 +805,133 @@ On a client that declares a profile, that profile id names the declaration: `pre
|
|
|
779
805
|
|
|
780
806
|
A raw CDP runtime arms `vault.merchantProfileUrlPatterns()` after `syncRegistry()`, beside `vault.cardUrlPatterns()`, reads `vault.merchantProfileOf(url)` and `classifyMerchantRequest(profile, url, method, body)` for each paused request, and writes a merchant-hosted approval with `substituteMerchantHostedBody(body, replay)`. Never continue a card body, or a body you could not read, to a profile's endpoint that `authorize()` did not pay.
|
|
781
807
|
|
|
808
|
+
### Pay a GMO Payment Gateway checkout
|
|
809
|
+
|
|
810
|
+
GMO Payment Gateway (PG Multipayment) launches dark: `syncRegistry()` declares
|
|
811
|
+
the `gmo_shared_pk` capability (`SUPPORTED_CAPABILITIES`), and the API serves
|
|
812
|
+
the GMO recognizer only to an org Agentcard has enabled for GMO. For every other
|
|
813
|
+
org nothing changes: GMO's requests are never paused and never refused.
|
|
814
|
+
|
|
815
|
+
For an enabled org, the SDK pauses one request: `mp-token.js`'s `getToken` after
|
|
816
|
+
`Multipayment.init(shopId)` with one argument, as teamLab's ticket sites call
|
|
817
|
+
it. That is a `POST` to `https://token.mul-pay.jp/payment/CreateToken.json` (test
|
|
818
|
+
host `stg.token.mul-pay.jp`) with `X-MP-Client-Type: js-legacy` and one token.
|
|
819
|
+
The card inside it is encrypted in the page, so the SDK sends the paused
|
|
820
|
+
envelope as it is; the cardholder's device builds GMO's envelope with the real
|
|
821
|
+
card and sends it to GMO itself. The page receives only GMO's answer: one
|
|
822
|
+
single-use token, valid 30 minutes and spendable only by the shop's own site.
|
|
823
|
+
The SDK hands the page nothing but that token answer under a JSON content type;
|
|
824
|
+
any other answer on an approved authorization throws `PaymentOutcomeUnknownError`
|
|
825
|
+
with reason `gmo_token_unconfirmed`.
|
|
826
|
+
|
|
827
|
+
```ts
|
|
828
|
+
await vault.syncRegistry();
|
|
829
|
+
const controller = await attachToPlaywright(page, {
|
|
830
|
+
vault, user: 'usr_123', merchant: 'teamLab Borderless',
|
|
831
|
+
amount: 3800, currency: 'jpy', // required: GMO's token request names no amount
|
|
832
|
+
});
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
GMO's request names no amount, so pass `amount` and `currency`: they are what
|
|
836
|
+
the cardholder approves. Without them the request throws `AmountRequiredError`
|
|
837
|
+
before anything is created. The merchant's server charges the token after you
|
|
838
|
+
confirm the order, for the amount it decides, and a 3-D Secure challenge that
|
|
839
|
+
follows runs in your browser: call `requestUserAction('3ds')` when you see one.
|
|
840
|
+
|
|
841
|
+
Every other request to that URL is aborted before anything is created, and the
|
|
842
|
+
attachment reads `unsupported` with the reason, also on the
|
|
843
|
+
`unsupported_checkout` event:
|
|
844
|
+
|
|
845
|
+
- `unsupported_gmo_request`: a GMO request the vault cannot pay, such as
|
|
846
|
+
`init(shopId, publicKey)` (a merchant-registered key), GMO Elements, more than
|
|
847
|
+
one token, or a shop id that does not match the host (`tshop` ids belong on
|
|
848
|
+
the test host).
|
|
849
|
+
- `unsupported_gmo_token_v1`: GMO token v1 (`ext/js/token.js`), which sends the
|
|
850
|
+
card in a script request.
|
|
851
|
+
|
|
852
|
+
A request whose body the SDK cannot read is aborted alone with a `blocked`
|
|
853
|
+
event, `unreadable_gmo_request`, and the next one is judged again.
|
|
854
|
+
|
|
855
|
+
### Pay a CyberSource Flex Microform checkout
|
|
856
|
+
|
|
857
|
+
Amtrak, Sonos and Learning Without Tears take cards in CyberSource Flex
|
|
858
|
+
Microform. Each card field is CyberSource's own iframe, and on createToken the
|
|
859
|
+
field seals what the agent typed into a JWE under a capture context the merchant
|
|
860
|
+
minted for this checkout. Nothing in that body can be swapped, so the
|
|
861
|
+
cardholder's device seals the real card under the same context and sends it to
|
|
862
|
+
CyberSource itself; the SDK answers the field's paused request with the
|
|
863
|
+
transient token CyberSource returned.
|
|
864
|
+
|
|
865
|
+
```ts
|
|
866
|
+
await vault.syncRegistry(); // the Flex recognizer is never in the built-in list
|
|
867
|
+
const card = await vault.placeholderCard({ user: 'your-user-id' }); // what the agent types
|
|
868
|
+
const checkout = await attachToPlaywright(page, {
|
|
869
|
+
vault, user: 'your-user-id', merchant: 'Example merchant', amount: 4210, currency: 'USD',
|
|
870
|
+
cardId: card.cardId, // the approval page preselects the card the placeholder describes
|
|
871
|
+
});
|
|
872
|
+
// Type card.number and card.securityCode into the Microform fields, and pick
|
|
873
|
+
// card.expiryMonth and card.expiryYear in the merchant's own expiry fields.
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
- **Dark launch.** `syncRegistry()` declares the `capture_context` capability,
|
|
877
|
+
and the API serves the Flex recognizer only to an org Agentcard has enabled
|
|
878
|
+
for CyberSource Flex. For any other org the SDK never recognizes a Flex
|
|
879
|
+
request, so the card field's request goes through untouched, as it did
|
|
880
|
+
before this release. The create checks the org again and answers
|
|
881
|
+
`403 processor_unavailable` if Agentcard turned the processor off after your
|
|
882
|
+
last sync.
|
|
883
|
+
- **The capture context.** Both adapters read it from the card field iframe's
|
|
884
|
+
URL, verify it offline against CyberSource's pinned signing keys, and send it
|
|
885
|
+
on the create as `request.capture_context` with `request.microform` (the
|
|
886
|
+
field iframe's version, the fields that loaded, and the one that sent the
|
|
887
|
+
request). The API and the cardholder's device verify it again. It never
|
|
888
|
+
appears in events.
|
|
889
|
+
- **What pauses.** Only a POST to `/flex/v2/tokens` from a Microform 2.12.1
|
|
890
|
+
card field whose loaded document this attachment read, sealed under that
|
|
891
|
+
field's capture context. A check (eCheck) Microform continues untouched.
|
|
892
|
+
Microform v0.x, Flex API direct traffic or any request from a frame that is
|
|
893
|
+
no Microform 2 field, another field-iframe version, or fields the
|
|
894
|
+
cardholder's device cannot rebuild is aborted as `unsupported_checkout` with `reason`
|
|
895
|
+
`microform_request_unrecognized`, `microform_version_unreviewed` or
|
|
896
|
+
`microform_fields_unsupported`; the controller reads `unsupported` with
|
|
897
|
+
reason `microform_unsupported` and nothing is created. A capture context that
|
|
898
|
+
does not verify, has expired, or did not seal the request, or a card field
|
|
899
|
+
the SDK could not read in time, is refused for that request alone (`blocked`
|
|
900
|
+
with `capture_context_invalid`, `capture_context_mismatch` or
|
|
901
|
+
`microform_frame_unread`), so the page's next request can pass. Every Flex
|
|
902
|
+
request the SDK refuses, and one whose approval ends in a decline or an API
|
|
903
|
+
refusal, fails in the page as a network error: the field's createToken
|
|
904
|
+
reports `CREATE_TOKEN_XHR_ERROR` at once, and the merchant's own error
|
|
905
|
+
handling runs (a message, a retry, or a reload under a new capture context).
|
|
906
|
+
- **Page facts.** The card field detects the brand from the number the agent
|
|
907
|
+
typed, and the merchant posts that brand and its own expiry fields beside the
|
|
908
|
+
token, while the token carries the real card. `placeholderCard()` reads the
|
|
909
|
+
stored card's network and expiry from `GET /api/v2/vault_cards` and returns a
|
|
910
|
+
documented test number of that network (Visa, Mastercard, Amex, Discover or
|
|
911
|
+
JCB), a placeholder security code of that network's length, and the real
|
|
912
|
+
expiry. Without a `cardId` it describes the user's most recently added card.
|
|
913
|
+
Pass the returned `cardId` to the attachment so the approval page preselects
|
|
914
|
+
that card; without it the page picks its own, which can be another card.
|
|
915
|
+
After `prepare()`, pass the prepared checkout's `cardId` instead: the
|
|
916
|
+
cardholder already approved that card. The facts hold only while the
|
|
917
|
+
cardholder pays with that card. Another network throws
|
|
918
|
+
`PlaceholderCardError`.
|
|
919
|
+
- **30 seconds.** The field iframe gives up on its request after 30 seconds.
|
|
920
|
+
Pass `amount` and `currency`: the page's next createToken for the same
|
|
921
|
+
purchase, from either field under the same capture context, is then answered
|
|
922
|
+
from the same approval. Fields the page reloads under a new capture context
|
|
923
|
+
ask the cardholder again. A page
|
|
924
|
+
that tokenizes on its own once the fields are valid (no Pay click) needs
|
|
925
|
+
`prepare({ psp: 'cybersource_flex', environment: 'production' })` before the
|
|
926
|
+
agent types the last card field; `sandbox` is `testflex.cybersource.com` with
|
|
927
|
+
CyberSource's test keys, and a test capture context pays only from a test
|
|
928
|
+
client.
|
|
929
|
+
- **One createToken per purchase.** A prepared approval binds one request. On
|
|
930
|
+
Amtrak, leave "add to profile" unticked or check out as a guest: that box
|
|
931
|
+
calls createToken a second time before Pay.
|
|
932
|
+
- Autopilot never pays a Flex checkout; the cardholder approves each one on
|
|
933
|
+
their device.
|
|
934
|
+
|
|
782
935
|
### Unsupported endpoints
|
|
783
936
|
|
|
784
937
|
`paymentEndpoints` is an explicit list supplied by the integrator after observing
|
package/dist/cdp.d.ts
CHANGED
|
@@ -127,7 +127,8 @@ export interface AttachOptions extends LifecycleOptions, ExecutionMetadata {
|
|
|
127
127
|
* AuthorizeInput.amount: the processor's own amount is the higher authority
|
|
128
128
|
* and is read right before the card is sent; a hint lets a bad purchase be
|
|
129
129
|
* refused the moment it opens, and one that disagrees with the processor is
|
|
130
|
-
* refused with nothing charged.
|
|
130
|
+
* refused with nothing charged. Required for GMO, whose card token request
|
|
131
|
+
* names no amount: without it a GMO request fails with AmountRequiredError.
|
|
131
132
|
*/
|
|
132
133
|
amount?: number | string;
|
|
133
134
|
currency?: string;
|