@agent-cards/sdk 0.23.28 → 0.24.1
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 +84 -0
- package/PREFLIGHT.md +7 -1
- package/README.md +197 -102
- package/dist/aci.d.ts +52 -22
- package/dist/aci.js +79 -15
- package/dist/adyen-merchant-hosted.generated.d.ts +2 -2
- package/dist/adyen-merchant-hosted.generated.js +586 -55
- package/dist/agent-amount.generated.js +1 -1
- package/dist/agentcard.d.ts +4 -5
- package/dist/agentcard.js +4 -5
- package/dist/amadeus.d.ts +9 -3
- package/dist/amadeus.js +33 -4
- package/dist/api-module.d.ts +1 -7
- package/dist/api-module.js +3 -5
- package/dist/{voice-retry.js → api-retry.js} +1 -1
- package/dist/api-types.d.ts +53 -0
- package/dist/{voice-types.js → api-types.js} +7 -2
- package/dist/approvals.d.ts +166 -0
- package/dist/approvals.js +213 -0
- package/dist/aurus.d.ts +33 -0
- package/dist/aurus.js +75 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/buy.d.ts +20 -101
- package/dist/buy.js +19 -74
- package/dist/capabilities.generated.js +1 -1
- package/dist/card-fields.generated.js +2864 -249
- package/dist/cardlink-vpos.d.ts +43 -0
- package/dist/cardlink-vpos.js +90 -0
- package/dist/cdp.d.ts +3 -13
- package/dist/cdp.js +244 -175
- package/dist/checkout-com.generated.js +5 -1
- package/dist/client.d.ts +170 -22
- package/dist/client.js +281 -40
- package/dist/creditguard.generated.d.ts +4 -4
- package/dist/cybersource-flex.generated.d.ts +39 -1
- package/dist/cybersource-flex.generated.js +100 -11
- package/dist/datatrans.generated.js +22 -1
- package/dist/eghl.d.ts +40 -0
- package/dist/eghl.js +72 -0
- package/dist/elavon-converge.generated.js +5 -3
- package/dist/gmo.generated.js +7 -2
- package/dist/hold.d.ts +8 -0
- package/dist/hold.js +43 -2
- package/dist/hosted-entry.js +4 -0
- package/dist/index.d.ts +9 -15
- package/dist/index.js +6 -10
- package/dist/lifecycle.d.ts +9 -61
- package/dist/lifecycle.js +24 -10
- package/dist/merchant-card-endpoints.generated.d.ts +6 -1
- package/dist/merchant-card-endpoints.generated.js +344 -19
- package/dist/merchant-hosted.d.ts +8 -1
- package/dist/nike-order.d.ts +51 -0
- package/dist/nike-order.js +81 -0
- package/dist/oceanpayment.d.ts +38 -0
- package/dist/oceanpayment.js +70 -0
- package/dist/paddle-tokenex.generated.js +111 -11
- package/dist/payplug.d.ts +41 -0
- package/dist/payplug.js +71 -0
- package/dist/payrails.generated.js +33 -8
- package/dist/pre-claim.d.ts +11 -0
- package/dist/pre-claim.js +130 -7
- package/dist/preflight-capabilities.generated.d.ts +0 -4
- package/dist/preflight-capabilities.generated.js +0 -5
- package/dist/preflight-catalog.json +200 -6
- package/dist/preflight-playwright.d.ts +2 -2
- package/dist/preflight-playwright.js +63 -14
- package/dist/preflight-schemas.json +18 -0
- package/dist/preflight.generated.d.ts +5 -4
- package/dist/preflight.generated.js +63 -3
- package/dist/preparation.d.ts +7 -0
- package/dist/preparation.js +21 -0
- package/dist/prepared-processor.d.ts +18 -5
- package/dist/prepared-processor.js +48 -8
- package/dist/primer.generated.js +2889 -268
- package/dist/processout.generated.d.ts +61 -0
- package/dist/processout.generated.js +577 -0
- package/dist/requests.js +1 -1
- package/dist/shiji-sts.generated.js +111 -11
- package/dist/stripe-checkout.generated.js +2761 -319
- package/dist/substitutions.generated.js +553 -26
- package/dist/tap-payments.generated.js +111 -11
- package/dist/twoc2p.generated.js +111 -11
- package/dist/url-masks/bluesnap.d.ts +2 -0
- package/dist/url-masks/bluesnap.js +15 -0
- package/dist/url-masks/oceanpayment.d.ts +2 -0
- package/dist/url-masks/oceanpayment.js +13 -0
- package/dist/url-masks/payplug.d.ts +2 -0
- package/dist/url-masks/payplug.js +13 -0
- package/dist/url-masks/vtex_payments.d.ts +2 -0
- package/dist/url-masks/vtex_payments.js +12 -0
- package/dist/url-masks.generated.d.ts +1 -1
- package/dist/url-masks.generated.js +6 -2
- package/dist/verifone.generated.js +42 -2
- package/dist/vtex-payments.generated.d.ts +127 -0
- package/dist/vtex-payments.generated.js +544 -0
- package/dist/webhooks.d.ts +2 -2
- package/dist/webhooks.js +2 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +6 -8
- package/dist/languages.d.ts +0 -23
- package/dist/languages.js +0 -76
- package/dist/voice-pkce.d.ts +0 -49
- package/dist/voice-pkce.js +0 -147
- package/dist/voice-stream.generated.d.ts +0 -118
- package/dist/voice-stream.generated.js +0 -170
- package/dist/voice-types.d.ts +0 -735
- package/dist/voice.d.ts +0 -373
- package/dist/voice.js +0 -815
- package/readme.test.mjs +0 -53
- /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
|
@@ -385,6 +385,7 @@
|
|
|
385
385
|
"mollie-components-v1-script",
|
|
386
386
|
"mollie-hosted-credit-card",
|
|
387
387
|
"braintree-web-sdk",
|
|
388
|
+
"braintree-web-wallet",
|
|
388
389
|
"braintree-hosted-fields",
|
|
389
390
|
"paysafe-js",
|
|
390
391
|
"worldpay-checkout-sdk",
|
|
@@ -466,6 +467,8 @@
|
|
|
466
467
|
"mercado-pago-checkout-pro-card-form",
|
|
467
468
|
"gravy-secure-fields-script",
|
|
468
469
|
"gravy-secure-fields-script-sandbox",
|
|
470
|
+
"bambora-na-custom-checkout-fields",
|
|
471
|
+
"worldpay-wpg-hosted-payment-page",
|
|
469
472
|
"paypal-hosted-fields-payments-sdk",
|
|
470
473
|
"paypal-card-fields-v5",
|
|
471
474
|
"paypal-card-fields-v6",
|
|
@@ -481,6 +484,10 @@
|
|
|
481
484
|
"gmo-link-hosted-page",
|
|
482
485
|
"cybersource-flex-microform-script",
|
|
483
486
|
"cybersource-flex-microform-field",
|
|
487
|
+
"cybersource-unified-checkout-script",
|
|
488
|
+
"cybersource-unified-checkout-frame",
|
|
489
|
+
"aurus-ecom-iframe",
|
|
490
|
+
"aurus-ecom-init-script",
|
|
484
491
|
"juspay-hypercheckout-payment-page",
|
|
485
492
|
"pelecard-payment-page",
|
|
486
493
|
"pelecard-payment-script",
|
|
@@ -524,6 +531,8 @@
|
|
|
524
531
|
"gmo-link-hosted-page-test",
|
|
525
532
|
"cybersource-flex-microform-script-test",
|
|
526
533
|
"cybersource-flex-microform-field-test",
|
|
534
|
+
"cybersource-unified-checkout-script-test",
|
|
535
|
+
"cybersource-unified-checkout-frame-test",
|
|
527
536
|
"cybersource-secure-acceptance-silent-order-post-test",
|
|
528
537
|
"cybersource-secure-acceptance-silent-order-post-in",
|
|
529
538
|
"worldpay-eprotect-js-api-prelive",
|
|
@@ -1021,6 +1030,7 @@
|
|
|
1021
1030
|
"mollie-components-v1-script",
|
|
1022
1031
|
"mollie-hosted-credit-card",
|
|
1023
1032
|
"braintree-web-sdk",
|
|
1033
|
+
"braintree-web-wallet",
|
|
1024
1034
|
"braintree-hosted-fields",
|
|
1025
1035
|
"paysafe-js",
|
|
1026
1036
|
"worldpay-checkout-sdk",
|
|
@@ -1102,6 +1112,8 @@
|
|
|
1102
1112
|
"mercado-pago-checkout-pro-card-form",
|
|
1103
1113
|
"gravy-secure-fields-script",
|
|
1104
1114
|
"gravy-secure-fields-script-sandbox",
|
|
1115
|
+
"bambora-na-custom-checkout-fields",
|
|
1116
|
+
"worldpay-wpg-hosted-payment-page",
|
|
1105
1117
|
"paypal-hosted-fields-payments-sdk",
|
|
1106
1118
|
"paypal-card-fields-v5",
|
|
1107
1119
|
"paypal-card-fields-v6",
|
|
@@ -1117,6 +1129,10 @@
|
|
|
1117
1129
|
"gmo-link-hosted-page",
|
|
1118
1130
|
"cybersource-flex-microform-script",
|
|
1119
1131
|
"cybersource-flex-microform-field",
|
|
1132
|
+
"cybersource-unified-checkout-script",
|
|
1133
|
+
"cybersource-unified-checkout-frame",
|
|
1134
|
+
"aurus-ecom-iframe",
|
|
1135
|
+
"aurus-ecom-init-script",
|
|
1120
1136
|
"juspay-hypercheckout-payment-page",
|
|
1121
1137
|
"pelecard-payment-page",
|
|
1122
1138
|
"pelecard-payment-script",
|
|
@@ -1160,6 +1176,8 @@
|
|
|
1160
1176
|
"gmo-link-hosted-page-test",
|
|
1161
1177
|
"cybersource-flex-microform-script-test",
|
|
1162
1178
|
"cybersource-flex-microform-field-test",
|
|
1179
|
+
"cybersource-unified-checkout-script-test",
|
|
1180
|
+
"cybersource-unified-checkout-frame-test",
|
|
1163
1181
|
"cybersource-secure-acceptance-silent-order-post-test",
|
|
1164
1182
|
"cybersource-secure-acceptance-silent-order-post-in",
|
|
1165
1183
|
"worldpay-eprotect-js-api-prelive",
|
|
@@ -148,6 +148,11 @@ export declare function getCheckoutPreflightCatalog(): {
|
|
|
148
148
|
path_pattern: string;
|
|
149
149
|
flow?: string;
|
|
150
150
|
variant_unverified?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Why the asset never takes a card: a wallet button, a fraud collector, or the client those load. When no card frame
|
|
153
|
+
* is active and scripts alone name several processors, one whose every asset says this is not the card form's.
|
|
154
|
+
*/
|
|
155
|
+
card_free?: string;
|
|
151
156
|
}[];
|
|
152
157
|
processors: readonly [{
|
|
153
158
|
readonly psp: "spreedly";
|
|
@@ -1340,10 +1345,6 @@ export declare function getCheckoutPreflightCatalog(): {
|
|
|
1340
1345
|
readonly psp: "vgs";
|
|
1341
1346
|
readonly reason: "iframe_bound_tokenization";
|
|
1342
1347
|
readonly action: "human_checkout";
|
|
1343
|
-
}, {
|
|
1344
|
-
readonly psp: "bluesnap";
|
|
1345
|
-
readonly reason: "multi_request_tokenization_not_supported";
|
|
1346
|
-
readonly action: "human_checkout";
|
|
1347
1348
|
}, {
|
|
1348
1349
|
readonly psp: "stripe";
|
|
1349
1350
|
readonly reason: "unbound_token_to_payment_intent_continuation";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
2
|
-
// source-sha256:
|
|
2
|
+
// source-sha256: 1ac6ffa819d0bb72040d0a95cac79f780aeae4f5dea22599fbc4c5ec6c6c8687
|
|
3
3
|
import { CHECKOUT_PREFLIGHT_CAPABILITIES } from './preflight-capabilities.generated.js';
|
|
4
4
|
/** Advisory page discovery. These rules never admit a payment destination. */
|
|
5
5
|
export const CHECKOUT_PREFLIGHT_VERSION = '1';
|
|
@@ -23,7 +23,13 @@ const RULES = [
|
|
|
23
23
|
// A braintree-web build whose version carries -payments-sdk (3.32.0-payments-sdk-dev) is PayPal's
|
|
24
24
|
// (paypal-hosted-fields-payments-sdk below): its card goes to PayPal, never to Braintree, so neither
|
|
25
25
|
// Braintree rule takes one.
|
|
26
|
-
{ id: 'braintree-web-sdk', psp: 'braintree', kinds: ['script'], hostname: /^js\.braintreegateway\.com$/, pathname: /^\/web\/(?![^/]*-payments-sdk)[^/]+\/js
|
|
26
|
+
{ id: 'braintree-web-sdk', psp: 'braintree', kinds: ['script'], hostname: /^js\.braintreegateway\.com$/, pathname: /^\/web\/(?![^/]*-payments-sdk)[^/]+\/js\/(?!(?:client|paypal|paypal-checkout|venmo|apple-pay|google-payment|data-collector|local-payment)(?:\.min)?\.js$)/, origin: 'https://js.braintreegateway.com', path_pattern: '/web/:version/js/*' },
|
|
27
|
+
// braintree-web's client and its wallet and fraud components take no card: a page that loads only these runs a
|
|
28
|
+
// PayPal, Venmo, Apple Pay or Google Pay button through Braintree, and its card boxes belong to another processor.
|
|
29
|
+
// AutoZone's checkout loads client, paypal-checkout and data-collector 3.125.0 beside Worldpay eProtect's JS API, whose
|
|
30
|
+
// script reads the card from the page's own fields (2026-10-31).
|
|
31
|
+
{ id: 'braintree-web-wallet', psp: 'braintree', kinds: ['script'], hostname: /^js\.braintreegateway\.com$/, pathname: /^\/web\/(?![^/]*-payments-sdk)[^/]+\/js\/(?:client|paypal|paypal-checkout|venmo|apple-pay|google-payment|data-collector|local-payment)(?:\.min)?\.js$/, origin: 'https://js.braintreegateway.com', path_pattern: '/web/:version/js/{client,paypal,paypal-checkout,venmo,apple-pay,google-payment,data-collector,local-payment}[.min].js',
|
|
32
|
+
card_free: 'braintree-web\'s client, wallet and fraud components collect no card; Hosted Fields and Drop-in do.' },
|
|
27
33
|
{ id: 'braintree-hosted-fields', psp: 'braintree', kinds: ['frame', 'iframe'], hostname: /^assets\.braintreegateway\.com$/, pathname: /^\/web\/(?![^/]*-payments-sdk)/, origin: 'https://assets.braintreegateway.com', path_pattern: '/web/*' },
|
|
28
34
|
{ id: 'paysafe-js', psp: 'paysafe', kinds: ['script', 'frame', 'iframe'], hostname: /^hosted\.paysafe\.com$/, pathname: /^\/(?:js|checkout)\//, origin: 'https://hosted.paysafe.com', path_pattern: '/{js,checkout}/*' },
|
|
29
35
|
{ id: 'worldpay-checkout-sdk', psp: 'worldpay', kinds: ['script', 'frame', 'iframe'], hostname: /^access\.worldpay\.com$/, pathname: /^\/access-checkout\//, origin: 'https://access.worldpay.com', path_pattern: '/access-checkout/*' },
|
|
@@ -69,6 +75,29 @@ RULES.push({ id: 'tranzila-terminal-hosted-page', psp: 'tranzila', kinds: ['docu
|
|
|
69
75
|
{ id: 'gravy-secure-fields-script', psp: 'gravy', kinds: ['script'], hostname: /^cdn\.[a-z0-9-]+\.gr4vy\.app$/, pathname: GRAVY_SECURE_FIELDS_SCRIPT, origin: 'https://cdn.:merchant.gr4vy.app', path_pattern: '/secure-fields/{latest,:version}/secure-fields.js',
|
|
70
76
|
sources: GRAVY_SOURCES }, { id: 'gravy-secure-fields-script-sandbox', psp: 'gravy', kinds: ['script'], hostname: /^cdn\.sandbox\.[a-z0-9-]+\.gr4vy\.app$/, pathname: GRAVY_SECURE_FIELDS_SCRIPT, origin: 'https://cdn.sandbox.:merchant.gr4vy.app', path_pattern: '/secure-fields/{latest,:version}/secure-fields.js',
|
|
71
77
|
sources: GRAVY_SOURCES });
|
|
78
|
+
// Card frames the catalog scan of 2026-10-23 read at stores' card forms (no card typed, nothing paid). Each
|
|
79
|
+
// rule names its processor from a frame on the processor's own host. A file on the store's own host that only
|
|
80
|
+
// carries the processor's name, such as the copy of Bambora's customcheckout.js that Kent serves itself, names
|
|
81
|
+
// nothing.
|
|
82
|
+
const catalogScan = (reference) => ({ kind: 'saved_observation', reference: `catalog-psp-scan-2026-10-23:${reference}`, reviewed_on: '2026-10-23' });
|
|
83
|
+
RULES.push(
|
|
84
|
+
// Bambora Custom Checkout draws each card field as an iframe from the release its library was built for:
|
|
85
|
+
// /customcheckout/1/customcheckout.js draws 1.0.5-39 (the reviewed rule above), and Kent's own copy draws
|
|
86
|
+
// 1.0.2. The release names the frame and nothing more. Payment-core's bambora entry matches the card request
|
|
87
|
+
// on its own (/scripts/tokenization/tokens), so a release whose frame sent the card anywhere else would send
|
|
88
|
+
// only the placeholder card the agent typed.
|
|
89
|
+
{ id: 'bambora-na-custom-checkout-fields', psp: 'bambora', kinds: ['frame', 'iframe', 'document'], hostname: /^libs\.na\.bambora\.com$/,
|
|
90
|
+
pathname: /^\/customcheckout\/1\.[0-9]{1,3}\.[0-9]{1,3}(?:-[0-9]{1,4})?\/iframe\.html$/, origin: 'https://libs.na.bambora.com', path_pattern: '/customcheckout/1.:minor.:patch{,-:build}/iframe.html',
|
|
91
|
+
sources: [{ kind: 'primary_source', reference: 'https://docs.na.worldline-solutions.com/build-your-integration/checkout-form/custom-checkout/reference', reviewed_on: '2026-09-11' },
|
|
92
|
+
catalogScan('kent-ca-custom-checkout-1.0.2-card-fields')] },
|
|
93
|
+
// Worldpay's hosted payment pages on payments.worldpay.com: Razer's checkout opens
|
|
94
|
+
// /app/hpp-iframe/integration/wpg/corporate in an iframe, which lands on /app/hpp/<build>/payment/start, where
|
|
95
|
+
// the shopper types the card on Worldpay's own page. The SDK's worldpay entry takes over Access Checkout's card
|
|
96
|
+
// session only, so the page names worldpay and stays unknown, as the secure.worldpay.com/wcc pages do.
|
|
97
|
+
{ id: 'worldpay-wpg-hosted-payment-page', psp: 'worldpay', kinds: ['document', 'frame', 'iframe'], hostname: /^payments\.worldpay\.com$/,
|
|
98
|
+
pathname: /^\/app\/hpp(?:-iframe)?\//, origin: 'https://payments.worldpay.com', path_pattern: '/app/{hpp,hpp-iframe}/*',
|
|
99
|
+
sources: [catalogScan('razer-worldpay-hosted-payment-page')],
|
|
100
|
+
variant_unverified: 'The implemented Worldpay adapter covers Access Checkout card sessions; Worldpay hosted payment pages under payments.worldpay.com/app/hpp take the card on Worldpay\'s own page and are not admitted.' });
|
|
72
101
|
// PayPal's legacy Hosted Fields (its JS SDK's components=hosted-fields), reviewed 2026-10-07 from Planet Golf
|
|
73
102
|
// UK's payment step (read live 2026-10-06, SDK 5.0.580) and the two frame files it loads. The SDK renders each
|
|
74
103
|
// card field as braintree-web's 3.32.0-payments-sdk-dev hosted-fields-input-frame.min.html (sha256
|
|
@@ -174,6 +203,27 @@ const cybersourceSources = [
|
|
|
174
203
|
RULES.push({ id: 'cybersource-flex-microform-script', psp: 'cybersource_flex', kinds: ['script'], hostname: /^flex\.cybersource\.com$/, pathname: /^\/microform\/bundle\/v2(?:\.[0-9]+\.[0-9]+)?\/flex-microform\.min\.js$/, origin: 'https://flex.cybersource.com', path_pattern: '/microform/bundle/v2{,.:minor.:patch}/flex-microform.min.js',
|
|
175
204
|
sources: cybersourceSources }, { id: 'cybersource-flex-microform-field', psp: 'cybersource_flex', kinds: ['frame', 'iframe', 'document'], hostname: /^flex\.cybersource\.com$/, pathname: /^\/microform\/bundle\/v2\.[0-9]+\.[0-9]+\/iframe\.html$/, origin: 'https://flex.cybersource.com', path_pattern: '/microform/bundle/v:version/iframe.html',
|
|
176
205
|
sources: cybersourceSources });
|
|
206
|
+
// CyberSource Unified Checkout v1 sends the card to the same Flex v2 tokens URL, sealed by its orchestrator frame
|
|
207
|
+
// under the capture context (cybersource-unified-checkout.js), so its script and frames name cybersource_flex too.
|
|
208
|
+
// Reviewed 2026-10-31 from napaonline.com's checkout (UnifiedCheckout.js v1.8.2), with no card sent.
|
|
209
|
+
const unifiedCheckoutSources = [
|
|
210
|
+
{ kind: 'saved_observation', reference: 'napaonline-2026-10-31:unified-checkout-v1.8.2-mce-orc-ga-frames', reviewed_on: '2026-10-31' },
|
|
211
|
+
{ kind: 'official_documentation', reference: 'https://developer.cybersource.com/docs/cybs/en-us/unified-checkout/developer/all/rest/unified-checkout/uc-intro.html', reviewed_on: '2026-10-31' },
|
|
212
|
+
];
|
|
213
|
+
RULES.push({ id: 'cybersource-unified-checkout-script', psp: 'cybersource_flex', kinds: ['script'], hostname: /^up\.cybersource\.com$/, pathname: /^\/uc\/v1\/assets\/[A-Za-z0-9_-]{16,1024}\/UnifiedCheckout\.js$/, origin: 'https://up.cybersource.com', path_pattern: '/uc/v1/assets/:asset/UnifiedCheckout.js',
|
|
214
|
+
sources: unifiedCheckoutSources }, { id: 'cybersource-unified-checkout-frame', psp: 'cybersource_flex', kinds: ['frame', 'iframe', 'document'], hostname: /^up\.cybersource\.com$/, pathname: /^\/uc\/v1\/assets\/[A-Za-z0-9_-]{16,1024}\/(?:mce\/mce|orc\/orc|ga\/ga)\.html$/, origin: 'https://up.cybersource.com', path_pattern: '/uc/v1/assets/:asset/{mce,orc,ga}/*.html',
|
|
215
|
+
sources: unifiedCheckoutSources });
|
|
216
|
+
// Aurus Pay's ecom card frame (processors/aurus.js): the store frames /storeservices/ecom/getiframe on
|
|
217
|
+
// pecst<NN>.aurusepay.com, the card fields sit inside it, and its own ecominitjs sends the sealed card to
|
|
218
|
+
// /storeservices/ecom/oneTimeToken on the same host. Reviewed 2026-10-31 at oreillyauto.com's payment step, with every
|
|
219
|
+
// aurusepay.com request but a GET aborted and only a public test card typed. Aurus is served dark, so no catalog
|
|
220
|
+
// processor entry backs the candidate and the result stays unknown unless the caller is served Aurus.
|
|
221
|
+
const aurusSources = [
|
|
222
|
+
{ kind: 'saved_observation', reference: 'oreillyauto-2026-10-31:aurus-ecom-getiframe-oneTimeToken', reviewed_on: '2026-10-31' },
|
|
223
|
+
];
|
|
224
|
+
RULES.push({ id: 'aurus-ecom-iframe', psp: 'aurus', kinds: ['frame', 'iframe', 'document'], hostname: /^pecst[0-9]{2}\.aurusepay\.com$/, pathname: /^\/storeservices\/ecom\/getiframe$/, origin: 'https://pecst01.aurusepay.com', path_pattern: '/storeservices/ecom/getiframe',
|
|
225
|
+
sources: aurusSources }, { id: 'aurus-ecom-init-script', psp: 'aurus', kinds: ['script'], hostname: /^pecst[0-9]{2}\.aurusepay\.com$/, pathname: /^\/storeservices\/ecom\/ecominitjs$/, origin: 'https://pecst01.aurusepay.com', path_pattern: '/storeservices/ecom/ecominitjs',
|
|
226
|
+
sources: aurusSources });
|
|
177
227
|
// Juspay HyperCheckout: Juspay's own hosted payment page (the Session API's payment_links.web),
|
|
178
228
|
// which a merchant embeds in an iframe (IndiGo's payment step). The card request that page makes
|
|
179
229
|
// has not been observed, so the Vault does not take it over, and the rule tells the agent so
|
|
@@ -359,6 +409,8 @@ for (const [baseId, suffix, hostname, origin] of [
|
|
|
359
409
|
['gmo-link-hosted-page', 'test', /^pt01\.mul-pay\.jp$/, 'https://pt01.mul-pay.jp'],
|
|
360
410
|
['cybersource-flex-microform-script', 'test', /^testflex\.cybersource\.com$/, 'https://testflex.cybersource.com'],
|
|
361
411
|
['cybersource-flex-microform-field', 'test', /^testflex\.cybersource\.com$/, 'https://testflex.cybersource.com'],
|
|
412
|
+
['cybersource-unified-checkout-script', 'test', /^testup\.cybersource\.com$/, 'https://testup.cybersource.com'],
|
|
413
|
+
['cybersource-unified-checkout-frame', 'test', /^testup\.cybersource\.com$/, 'https://testup.cybersource.com'],
|
|
362
414
|
// Secure Acceptance's test host and its production host in India serve the same /silent/ paths.
|
|
363
415
|
['cybersource-secure-acceptance-silent-order-post', 'test', /^testsecureacceptance\.cybersource\.com$/, 'https://testsecureacceptance.cybersource.com'],
|
|
364
416
|
['cybersource-secure-acceptance-silent-order-post', 'in', /^secureacceptance\.in\.cybersource\.com$/, 'https://secureacceptance.in.cybersource.com'],
|
|
@@ -765,19 +817,27 @@ export function assessCheckoutSupport(input, options = {}) {
|
|
|
765
817
|
result.candidates = [...candidates.values()].sort((a, b) => a.psp.localeCompare(b.psp));
|
|
766
818
|
if (missingCorroboration && activeFlows.size === 0)
|
|
767
819
|
result.reason_codes.push('flow_corroboration_missing');
|
|
820
|
+
// Scripts alone naming several processors: one whose every asset is card-free (a wallet button, a fraud collector)
|
|
821
|
+
// is not the card form's. When exactly one other is left, the page's card form is that one's.
|
|
822
|
+
const cardCapable = activePsps.size === 0 && candidates.size > 1
|
|
823
|
+
? [...candidates.values()].filter(candidate => candidate.evidence.some(evidence => !RULE_BY_ID.get(evidence.rule_id).card_free))
|
|
824
|
+
: [];
|
|
825
|
+
const cardFormPsp = cardCapable.length === 1 ? cardCapable[0].psp : null;
|
|
768
826
|
if (activePsps.size === 1)
|
|
769
827
|
result.psp = [...activePsps][0];
|
|
770
828
|
// Script-only evidence names the processor only when the scan saw everything. On a partial scan
|
|
771
829
|
// the sole candidate stays listed as undetermined instead of becoming the selected route.
|
|
772
830
|
else if (activePsps.size === 0 && candidates.size === 1 && result.observation.complete)
|
|
773
831
|
result.psp = [...candidates.keys()][0];
|
|
832
|
+
else if (cardFormPsp !== null && result.observation.complete)
|
|
833
|
+
result.psp = cardFormPsp;
|
|
774
834
|
if (!result.observation.complete)
|
|
775
835
|
result.reason_codes.push('observation_incomplete');
|
|
776
836
|
if (!input.signals.length) {
|
|
777
837
|
result.reason_codes.push('psp_not_detected');
|
|
778
838
|
result.missing_evidence.push('payment_page_signal');
|
|
779
839
|
}
|
|
780
|
-
if (activePsps.size > 1 || activeFlows.size > 1 || activeFlowFrames.size > 1 || activePsps.size === 0 && candidates.size > 1)
|
|
840
|
+
if (activePsps.size > 1 || activeFlows.size > 1 || activeFlowFrames.size > 1 || activePsps.size === 0 && candidates.size > 1 && cardFormPsp === null)
|
|
781
841
|
result.reason_codes.push('ambiguous_checkout');
|
|
782
842
|
if (activeFlows.size !== 1 || result.psp === null) {
|
|
783
843
|
result.reason_codes.push('checkout_flow_unidentified');
|
package/dist/preparation.d.ts
CHANGED
|
@@ -25,6 +25,13 @@ export declare class PreparationGate {
|
|
|
25
25
|
* own method is what binds: a POST for most processors, the registration GET for Worldpay eProtect.
|
|
26
26
|
*/
|
|
27
27
|
claim(requestUrl: string, requestMethod: string, requestBody?: string | null, requestHeaders?: Record<string, string>): PreparedCheckout | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Whether a same-document navigation of the prepared page to `url` leaves the document this
|
|
30
|
+
* preparation read: the same origin, path and query, whatever the fragment. A single-page checkout
|
|
31
|
+
* that calls history.replaceState with its own URL after each server action (Al's on VTEX) keeps
|
|
32
|
+
* its preparation; a history update to another path or query does not.
|
|
33
|
+
*/
|
|
34
|
+
keepsDocument(url: unknown): boolean;
|
|
28
35
|
assertDocument(): Promise<void>;
|
|
29
36
|
private readDocument;
|
|
30
37
|
isEngaged(): boolean;
|
package/dist/preparation.js
CHANGED
|
@@ -3,6 +3,17 @@ import { amountRefusal, validAmountInput } from './client.js';
|
|
|
3
3
|
import { matchesPreparation, validPreparationEnvironment, preparationEndpoint, preparationBindsByShape, preparationRequestMethod, preparedRequestRefusal } from './prepared-processor.js';
|
|
4
4
|
import { SECURE_ACCEPTANCE_PSP, secureAcceptanceCheckoutProfile } from './cybersource-secure-acceptance.js';
|
|
5
5
|
import { creditguardPageProcessUrl, creditguardProcessTxId } from './creditguard.generated.js';
|
|
6
|
+
/** A page URL without its fragment, or undefined when it does not parse. */
|
|
7
|
+
function documentWithoutFragment(url) {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = new URL(url);
|
|
10
|
+
parsed.hash = '';
|
|
11
|
+
return parsed.href;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
6
17
|
/** A local, one-use rendezvous. It never starts or retries a merchant request. */
|
|
7
18
|
export class PreparationGate {
|
|
8
19
|
opts;
|
|
@@ -195,6 +206,16 @@ export class PreparationGate {
|
|
|
195
206
|
clearTimeout(this.expiryTimer);
|
|
196
207
|
return prepared;
|
|
197
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Whether a same-document navigation of the prepared page to `url` leaves the document this
|
|
211
|
+
* preparation read: the same origin, path and query, whatever the fragment. A single-page checkout
|
|
212
|
+
* that calls history.replaceState with its own URL after each server action (Al's on VTEX) keeps
|
|
213
|
+
* its preparation; a history update to another path or query does not.
|
|
214
|
+
*/
|
|
215
|
+
keepsDocument(url) {
|
|
216
|
+
const kept = typeof url === 'string' ? documentWithoutFragment(url) : undefined;
|
|
217
|
+
return kept !== undefined && this.documentUrl !== '' && kept === documentWithoutFragment(this.documentUrl);
|
|
218
|
+
}
|
|
198
219
|
async assertDocument() {
|
|
199
220
|
if (this.documentUrl && await this.readDocument() !== this.documentUrl)
|
|
200
221
|
throw new CheckoutPreparationError(this.prepared?.id ?? null, 'merchant_document_changed');
|
|
@@ -37,8 +37,20 @@
|
|
|
37
37
|
* approval after Pay. Its environments are its API hosts: api.openpay.<mx|co|pe> (production) and
|
|
38
38
|
* sandbox-api.openpay.<mx|co|pe> (sandbox). The token URL names the merchant in its path, so no URL is
|
|
39
39
|
* prepared in advance: the claim binds the request by its host's environment and its shape, as ACI's.
|
|
40
|
+
*
|
|
41
|
+
* vtex_payments: prepared only. Ollie's headless checkout aborts its card post to the store's VTEX vault 12 seconds after
|
|
42
|
+
* it starts it, too soon for an approval after Pay. Its one environment is production: VTEX has no test host. The card
|
|
43
|
+
* URL names the store's account in its host and VTEX's transaction in its path, neither known before Pay, so the claim
|
|
44
|
+
* binds the request by its shape, as Openpay's. Ollie sends the same post again on a non-OK answer or a network error,
|
|
45
|
+
* then once more to api.vtexvault.com: the first post spends the approval, and each later one is refused like any
|
|
46
|
+
* request on a spent preparation, so one approval is one card use.
|
|
47
|
+
*
|
|
48
|
+
* processout: prepared only. ProcessOut.js gives its card frame 20 seconds from the tokenize message before it calls
|
|
49
|
+
* the page's error callback, too soon for an approval after the shop's continue press. Its environments share one
|
|
50
|
+
* host, api.processout.com: the project id in the card URL's query names them, proj_ (production) and test-proj_
|
|
51
|
+
* (sandbox), so the claim binds the request by its project's environment and its shape, as Openpay's.
|
|
40
52
|
*/
|
|
41
|
-
export type PreparationProcessor = 'square' | 'braintree' | 'worldpay' | 'bambora' | 'mercado_pago' | 'recurly' | 'spreedly' | 'adyen' | 'checkout_com' | 'paysafe' | 'fiserv' | 'cybersource_flex' | 'aci' | 'creditguard' | 'worldpay_eprotect' | 'amadeus_checkout' | 'verifone' | 'cybersource_secure_acceptance' | 'paddle_vgs' | 'wix_payments' | 'paygent' | 'hipay' | 'openpay_bbva';
|
|
53
|
+
export type PreparationProcessor = 'square' | 'braintree' | 'worldpay' | 'bambora' | 'mercado_pago' | 'recurly' | 'spreedly' | 'adyen' | 'checkout_com' | 'paysafe' | 'fiserv' | 'cybersource_flex' | 'aci' | 'creditguard' | 'worldpay_eprotect' | 'amadeus_checkout' | 'verifone' | 'cybersource_secure_acceptance' | 'paddle_vgs' | 'wix_payments' | 'paygent' | 'hipay' | 'openpay_bbva' | 'vtex_payments' | 'processout';
|
|
42
54
|
export type PreparationEnvironment = 'production' | 'sandbox' | 'shared';
|
|
43
55
|
/**
|
|
44
56
|
* How the approved card reaches the processor: the device's own request (token), or
|
|
@@ -77,7 +89,8 @@ export declare function preparedApprovalAnswersRetry(psp: string): boolean;
|
|
|
77
89
|
* live, testsecureacceptance is test. So are Paddle VGS's two card URLs: vault is live,
|
|
78
90
|
* sandbox-vault is test. So are Paygent's two token hosts: token is live, sandbox is test. So are
|
|
79
91
|
* HiPay's two vault hosts: secure2-vault is live, stage-secure2-vault is test. So are Openpay's API
|
|
80
|
-
* hosts: api.openpay.<mx|co|pe> is live, sandbox-api.openpay.<mx|co|pe> is test.
|
|
92
|
+
* hosts: api.openpay.<mx|co|pe> is live, sandbox-api.openpay.<mx|co|pe> is test. ProcessOut's share
|
|
93
|
+
* one host, and the card URL's project id attests them: proj_ is live, test-proj_ is test.
|
|
81
94
|
*/
|
|
82
95
|
export declare function validPreparationEnvironment(psp: string, environment: string): boolean;
|
|
83
96
|
/**
|
|
@@ -90,9 +103,9 @@ export declare function aciPreparationUrl(environment: PreparationEnvironment):
|
|
|
90
103
|
/**
|
|
91
104
|
* A processor whose card request names an id the merchant mints only at Pay time (ACI's checkout
|
|
92
105
|
* id), or the merchant's own id (Openpay's token URL carries the merchant id in its path and the
|
|
93
|
-
* country in its host
|
|
94
|
-
*
|
|
95
|
-
* only names the preparation.
|
|
106
|
+
* country in its host, ProcessOut's card URL the project id in its query), so no URL can be prepared
|
|
107
|
+
* in advance: whether the adapters can intercept it is asked of the registry
|
|
108
|
+
* (VaultClient.recognizesProcessor), not of the prepared endpoint, which only names the preparation.
|
|
96
109
|
*/
|
|
97
110
|
export declare function preparationBindsByShape(psp: string): boolean;
|
|
98
111
|
/**
|
|
@@ -18,6 +18,8 @@ import { WIX_PAYMENTS_TOKENIZE_URL, isPreparedWixPaymentsRequest } from './wix-p
|
|
|
18
18
|
import { paygentEnvironment, paygentPreparationUrl, paygentRequestRefusal } from './paygent.generated.js';
|
|
19
19
|
import { HIPAY_TOKEN_URLS, hipayRequestRefusal, hipayTokenEnvironment, isPreparedHipayRequest } from './hipay.generated.js';
|
|
20
20
|
import { OPENPAY_PREPARATION_URLS, isPreparedOpenpayRequest, openpayRequestRefusal, openpayTokenEnvironment } from './openpay.generated.js';
|
|
21
|
+
import { VTEX_PAYMENTS_PREPARATION_URL, isPreparedVtexPaymentsRequest, vtexPaymentsCardTarget, vtexPaymentsRequestRefusal } from './vtex-payments.generated.js';
|
|
22
|
+
import { PROCESSOUT_PREPARATION_URLS, isPreparedProcessoutRequest, processoutEnvironment, processoutRequestRefusal } from './processout.generated.js';
|
|
21
23
|
export function preparationMode(psp) {
|
|
22
24
|
return psp === 'adyen' || psp === 'fiserv' || psp === 'verifone' ? 'cse' : 'token';
|
|
23
25
|
}
|
|
@@ -54,16 +56,17 @@ export function preparedApprovalAnswersRetry(psp) {
|
|
|
54
56
|
* live, testsecureacceptance is test. So are Paddle VGS's two card URLs: vault is live,
|
|
55
57
|
* sandbox-vault is test. So are Paygent's two token hosts: token is live, sandbox is test. So are
|
|
56
58
|
* HiPay's two vault hosts: secure2-vault is live, stage-secure2-vault is test. So are Openpay's API
|
|
57
|
-
* hosts: api.openpay.<mx|co|pe> is live, sandbox-api.openpay.<mx|co|pe> is test.
|
|
59
|
+
* hosts: api.openpay.<mx|co|pe> is live, sandbox-api.openpay.<mx|co|pe> is test. ProcessOut's share
|
|
60
|
+
* one host, and the card URL's project id attests them: proj_ is live, test-proj_ is test.
|
|
58
61
|
*/
|
|
59
62
|
export function validPreparationEnvironment(psp, environment) {
|
|
60
63
|
if (psp === 'bambora' || psp === 'mercado_pago' || psp === 'recurly' || psp === 'spreedly')
|
|
61
64
|
return environment === 'shared';
|
|
62
|
-
// Wix Payments has production alone: its tokenizer has no test host.
|
|
63
|
-
if (psp === 'wix_payments')
|
|
65
|
+
// Wix Payments has production alone: its tokenizer has no test host. VTEX Payments too: every store's vault is live.
|
|
66
|
+
if (psp === 'wix_payments' || psp === 'vtex_payments')
|
|
64
67
|
return environment === 'production';
|
|
65
68
|
return ['square', 'braintree', 'worldpay', 'adyen', 'checkout_com', 'paysafe', 'fiserv', 'cybersource_flex', 'aci', 'creditguard', 'worldpay_eprotect', 'amadeus_checkout', 'verifone',
|
|
66
|
-
'cybersource_secure_acceptance', 'paddle_vgs', 'paygent', 'hipay', 'openpay_bbva'].includes(psp) && ['production', 'sandbox'].includes(environment);
|
|
69
|
+
'cybersource_secure_acceptance', 'paddle_vgs', 'paygent', 'hipay', 'openpay_bbva', 'processout'].includes(psp) && ['production', 'sandbox'].includes(environment);
|
|
67
70
|
}
|
|
68
71
|
/**
|
|
69
72
|
* ACI's prepared endpoint, the literal the API names (backend checkout-prepared-processor.ts): its
|
|
@@ -77,12 +80,12 @@ export function aciPreparationUrl(environment) {
|
|
|
77
80
|
/**
|
|
78
81
|
* A processor whose card request names an id the merchant mints only at Pay time (ACI's checkout
|
|
79
82
|
* id), or the merchant's own id (Openpay's token URL carries the merchant id in its path and the
|
|
80
|
-
* country in its host
|
|
81
|
-
*
|
|
82
|
-
* only names the preparation.
|
|
83
|
+
* country in its host, ProcessOut's card URL the project id in its query), so no URL can be prepared
|
|
84
|
+
* in advance: whether the adapters can intercept it is asked of the registry
|
|
85
|
+
* (VaultClient.recognizesProcessor), not of the prepared endpoint, which only names the preparation.
|
|
83
86
|
*/
|
|
84
87
|
export function preparationBindsByShape(psp) {
|
|
85
|
-
return psp === 'aci' || psp === 'openpay_bbva';
|
|
88
|
+
return psp === 'aci' || psp === 'openpay_bbva' || psp === 'vtex_payments' || psp === 'processout';
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
88
91
|
* The endpoint a CreditGuard preparation stands for, per environment, as the API advertises it: the
|
|
@@ -124,6 +127,15 @@ export function preparationEndpoint(psp, environment) {
|
|
|
124
127
|
// and the claim binds the real token URL by environment and shape (matchesPreparedRequest), as ACI's.
|
|
125
128
|
if (psp === 'openpay_bbva')
|
|
126
129
|
return OPENPAY_PREPARATION_URLS[environment];
|
|
130
|
+
// VTEX Payments: the literal that only names the preparation. Its "prepared" is no transaction id, so no card request
|
|
131
|
+
// is ever sent to it, and the claim binds the store's own card post by its shape (matchesPreparedRequest).
|
|
132
|
+
if (psp === 'vtex_payments')
|
|
133
|
+
return VTEX_PAYMENTS_PREPARATION_URL;
|
|
134
|
+
// ProcessOut: the literal the API names (backend checkout-prepared-processor.ts). It only names the preparation and its
|
|
135
|
+
// environment: its "prepared" is shorter than any project id, so no card request is ever sent to it, and the claim binds
|
|
136
|
+
// the real card URL by its project's environment and its shape (matchesPreparedRequest), as Openpay's.
|
|
137
|
+
if (psp === 'processout')
|
|
138
|
+
return PROCESSOUT_PREPARATION_URLS[environment];
|
|
127
139
|
// A Verifone endpoint is its reviewed profile's leg, never one per environment (verifone.ts).
|
|
128
140
|
if (psp === 'verifone')
|
|
129
141
|
throw new Error('unsupported_preparation_processor');
|
|
@@ -304,6 +316,19 @@ export function matchesPreparedRequest(psp, environment, requestUrl, method, bod
|
|
|
304
316
|
// merchant a later release reviews needs no new build of this library.
|
|
305
317
|
if (psp === 'openpay_bbva')
|
|
306
318
|
return isPreparedOpenpayRequest(requestUrl, method, body ?? null, environment, headers ?? {});
|
|
319
|
+
// VTEX Payments: a post to a store's own vault and payment-core's whole request rule (Ollie's JSON content type and
|
|
320
|
+
// one credit card line for the URL's transaction), the rule the API and the Vault bind with too. Ollie's resend to
|
|
321
|
+
// api.vtexvault.com never binds. Which store a request may reach is the API's to judge at the bind and the Vault's
|
|
322
|
+
// before it writes the card, against the reviewed pins each holds, so a store a later release reviews needs no new SDK.
|
|
323
|
+
if (psp === 'vtex_payments')
|
|
324
|
+
return isPreparedVtexPaymentsRequest(requestUrl, method, body ?? null, environment, headers ?? {});
|
|
325
|
+
// ProcessOut: a card URL whose project names the environment and payment-core's whole request rule (the JSON content
|
|
326
|
+
// type, the API version, the URL's own project credential and tokenizeCard's body), the rule the API and the Vault bind
|
|
327
|
+
// with too. Which project a live request may name is the API's to judge at the bind and the Vault's before it writes
|
|
328
|
+
// the card, against the reviewed pin each of them holds for the approved checkout origin, so a store a later release
|
|
329
|
+
// reviews needs no new build of this library.
|
|
330
|
+
if (psp === 'processout')
|
|
331
|
+
return isPreparedProcessoutRequest(requestUrl, method, body ?? null, environment, headers ?? {});
|
|
307
332
|
if (psp === 'creditguard')
|
|
308
333
|
return matchesPreparedCreditguard(environment, requestUrl, body, headers, binding);
|
|
309
334
|
// A Verifone request is judged only through the profile its preparation names (matchesPreparation).
|
|
@@ -479,6 +504,21 @@ export function preparedRequestRefusal(psp, environment, requestUrl, body, heade
|
|
|
479
504
|
return 'checkout_changed';
|
|
480
505
|
return openpayRequestRefusal({ url: requestUrl, method: 'POST', headers, body: body ?? null }) ?? 'checkout_changed';
|
|
481
506
|
}
|
|
507
|
+
// A VTEX post on a vault host names what payment-core's request rule refused (vtex_payments_fallback_refused for
|
|
508
|
+
// Ollie's resend to api.vtexvault.com, vtex_payments_installments, ...); any other request is `checkout_changed`.
|
|
509
|
+
if (psp === 'vtex_payments') {
|
|
510
|
+
if (environment !== 'production' || vtexPaymentsCardTarget(requestUrl) === null)
|
|
511
|
+
return 'checkout_changed';
|
|
512
|
+
return vtexPaymentsRequestRefusal({ url: requestUrl, method: 'POST', headers, body: body ?? null }) ?? 'checkout_changed';
|
|
513
|
+
}
|
|
514
|
+
// A ProcessOut card request whose project names the prepared environment names what payment-core's request rule
|
|
515
|
+
// refused (processout_headers_refused, processout_body_unsupported); the other environment's project, another query
|
|
516
|
+
// or path, or any other request is `checkout_changed`.
|
|
517
|
+
if (psp === 'processout') {
|
|
518
|
+
if (processoutEnvironment(requestUrl) !== environment)
|
|
519
|
+
return 'checkout_changed';
|
|
520
|
+
return processoutRequestRefusal({ url: requestUrl, method: 'POST', headers, body: body ?? null }) ?? 'checkout_changed';
|
|
521
|
+
}
|
|
482
522
|
if (psp !== 'amadeus_checkout' || amadeusEnvironment(requestUrl) !== environment)
|
|
483
523
|
return 'checkout_changed';
|
|
484
524
|
const merchantHost = merchantHostOf(merchantOrigin);
|