@agent-cards/checkout 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/PREFLIGHT.md +294 -0
  3. package/README.md +16 -3
  4. package/dist/braintree.d.ts +2 -10
  5. package/dist/braintree.generated.d.ts +10 -0
  6. package/dist/braintree.generated.js +302 -0
  7. package/dist/braintree.js +2 -302
  8. package/dist/builtin-registry.generated.d.ts +2 -0
  9. package/dist/builtin-registry.generated.js +1 -0
  10. package/dist/cdp.d.ts +4 -2
  11. package/dist/cdp.js +38 -6
  12. package/dist/client.d.ts +13 -4
  13. package/dist/client.js +80 -8
  14. package/dist/index.d.ts +1 -1
  15. package/dist/lifecycle.d.ts +1 -0
  16. package/dist/lifecycle.js +27 -1
  17. package/dist/owned-shop.generated.d.ts +24 -0
  18. package/dist/owned-shop.generated.js +108 -0
  19. package/dist/playwright.d.ts +3 -0
  20. package/dist/playwright.js +3 -0
  21. package/dist/preflight-capabilities.generated.d.ts +1165 -0
  22. package/dist/preflight-capabilities.generated.js +1799 -0
  23. package/dist/preflight-catalog.json +3892 -0
  24. package/dist/preflight-playwright.d.ts +34 -0
  25. package/dist/preflight-playwright.js +262 -0
  26. package/dist/preflight-schemas.json +1063 -0
  27. package/dist/preflight.d.ts +1 -0
  28. package/dist/preflight.generated.d.ts +1867 -0
  29. package/dist/preflight.generated.js +482 -0
  30. package/dist/preflight.js +2 -0
  31. package/dist/registry.d.ts +2 -19
  32. package/dist/registry.js +3 -188
  33. package/dist/substitute.d.ts +5 -9
  34. package/dist/substitute.js +5 -69
  35. package/dist/substitutions.generated.d.ts +10 -0
  36. package/dist/substitutions.generated.js +66 -0
  37. package/examples/preflight/classify-direct.mjs +21 -0
  38. package/examples/preflight/classify-kernel.mjs +30 -0
  39. package/examples/preflight/inspect-browser.mjs +44 -0
  40. package/examples/preflight/kernel-profile.empty.json +11 -0
  41. package/examples/preflight/mollie-hosted.observations.json +23 -0
  42. package/examples/preflight/mollie-hosted.result.json +103 -0
  43. package/examples/preflight/stripe-script.direct.result.json +92 -0
  44. package/examples/preflight/stripe-script.observations.json +16 -0
  45. package/examples/preflight/stripe-script.result.json +87 -0
  46. package/package.json +16 -7
@@ -0,0 +1,482 @@
1
+ // Generated from @agent-cards/payment-core. Do not edit.
2
+ // source-sha256: ced5aecd22684c680a53b9e33dff1c5333cd36823f6fe3b4b8e84f10f6f73c53
3
+ import { CHECKOUT_PREFLIGHT_CAPABILITIES } from './preflight-capabilities.generated.js';
4
+ /** Advisory page discovery. These rules never admit a payment destination. */
5
+ export const CHECKOUT_PREFLIGHT_VERSION = '1';
6
+ export const CHECKOUT_PREFLIGHT_CATALOG_VERSION = '2026-09-11.2';
7
+ export const CHECKOUT_PREFLIGHT_LIMITS = Object.freeze({ frames: 64, signals: 2048, snapshot_bytes: 262144, url_length: 4096 });
8
+ // Identification-only IDs, checked against the canonical catalog by the core tests.
9
+ // No card destination, request method, or request body pattern lives here.
10
+ const KNOWN_PSPS = CHECKOUT_PREFLIGHT_CAPABILITIES.processors.map(processor => processor.psp);
11
+ const PROCESSOR_BY_ID = new Map(CHECKOUT_PREFLIGHT_CAPABILITIES.processors.map(processor => [processor.psp, processor]));
12
+ const KINDS = ['document', 'frame', 'script', 'iframe', 'form'];
13
+ const SCENARIOS = ['one_time', 'save_card', 'subscription_initial', 'subscription_renewal'];
14
+ const OBSERVATION_REASONS = ['collection_timeout', 'frame_limit', 'signal_limit', 'snapshot_limit', 'frame_unavailable', 'navigation_changed', 'invalid_observation', 'invalid_url', 'collection_incomplete'];
15
+ const RULES = [
16
+ { id: 'stripe-js-v3', psp: 'stripe', kinds: ['script', 'frame', 'iframe'], hostname: /^js\.stripe\.com$/, pathname: /^\/v3(?:\/|$)/, origin: 'https://js.stripe.com', path_pattern: '/v3/*' },
17
+ { id: 'square-web-sdk', psp: 'square', kinds: ['script', 'frame', 'iframe'], hostname: /^web\.squarecdn\.com$/, pathname: /^\/v1\/square\.js$/, origin: 'https://web.squarecdn.com', path_pattern: '/v1/square.js' },
18
+ { id: 'mollie-components-script', psp: 'mollie', kinds: ['script'], hostname: /^js\.mollie\.com$/, pathname: /^\/v2\/mollie\.js$/, origin: 'https://js.mollie.com', path_pattern: '/v2/mollie.js' },
19
+ { id: 'mollie-components-v1-script', psp: 'mollie', kinds: ['script'], hostname: /^js\.mollie\.com$/, pathname: /^\/v1\/mollie\.js$/, origin: 'https://js.mollie.com', path_pattern: '/v1/mollie.js' },
20
+ { id: 'mollie-hosted-credit-card', psp: 'mollie', kinds: ['document', 'frame', 'iframe'], hostname: /^www\.mollie\.com$/, pathname: /^\/checkout\/credit-card\/session\/[A-Za-z0-9_-]+\/?$/, origin: 'https://www.mollie.com', path_pattern: '/checkout/credit-card/session/:session', flow: 'mollie.hosted_components' },
21
+ { id: 'braintree-web-sdk', psp: 'braintree', kinds: ['script'], hostname: /^js\.braintreegateway\.com$/, pathname: /^\/web\/[^/]+\/js\//, origin: 'https://js.braintreegateway.com', path_pattern: '/web/:version/js/*' },
22
+ { id: 'braintree-hosted-fields', psp: 'braintree', kinds: ['frame', 'iframe'], hostname: /^assets\.braintreegateway\.com$/, pathname: /^\/web\//, origin: 'https://assets.braintreegateway.com', path_pattern: '/web/*' },
23
+ { 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}/*' },
24
+ { 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/*' },
25
+ { id: 'authorize-net-accept', psp: 'authorize_net', kinds: ['script'], hostname: /^js\.authorize\.net$/, pathname: /^\/v[13]\/Accept(?:UI)?\.js$/, origin: 'https://js.authorize.net', path_pattern: '/v{1,3}/Accept{UI}.js' },
26
+ { id: 'razorpay-checkout-script', psp: 'razorpay', kinds: ['script'], hostname: /^checkout\.razorpay\.com$/, pathname: /^\/v1\/checkout\.js$/, origin: 'https://checkout.razorpay.com', path_pattern: '/v1/checkout.js' },
27
+ { id: 'vgs-collect-script', psp: 'vgs', kinds: ['script'], hostname: /^js\.verygoodvault\.com$/, pathname: /^\/vgs-collect\//, origin: 'https://js.verygoodvault.com', path_pattern: '/vgs-collect/*' },
28
+ { id: 'vgs-collect-frame', psp: 'vgs', kinds: ['frame', 'iframe'], hostname: /^[a-z0-9-]+\.(?:live|sandbox)\.verygoodproxy\.com$/, pathname: /^\//, origin: 'https://:tenant.:environment.verygoodproxy.com', path_pattern: '/*' },
29
+ ];
30
+ // SDK/page fingerprints identify implemented processor families, not an active payment operation.
31
+ RULES.push({ "id": "checkout-frames-v2-script", "psp": "checkout_com", "kinds": ["script"], "origin": "https://cdn.checkout.com", "path_pattern": "^/js/framesv2\\.min\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://checkoutdocs.readme.io/docs/frames-reference", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://cdn.checkout.com/js/framesv2.min.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^cdn\\.checkout\\.com$"), pathname: new RegExp("^/js/framesv2\\.min\\.js$") }, { "id": "adyen-web-legacy-live", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-live.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/web-best-practices/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-secured-fields-live", "psp": "adyen", "kinds": ["frame", "iframe", "document"], "origin": "https://checkoutshopper-live.adyen.com", "path_pattern": "^/checkoutshopper/securedfields/[^/]+/5\\.5\\.1/securedFields\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/sdk/6.11.0/adyen.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/securedfields/[^/]+/5\\.5\\.1/securedFields\\.html$") }, { "id": "adyen-web-legacy-test", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-test.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/web-best-practices/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-test\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-secured-fields-test", "psp": "adyen", "kinds": ["frame", "iframe", "document"], "origin": "https://checkoutshopper-test.adyen.com", "path_pattern": "^/checkoutshopper/securedfields/[^/]+/5\\.5\\.1/securedFields\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/sdk/6.11.0/adyen.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-test\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/securedfields/[^/]+/5\\.5\\.1/securedFields\\.html$") }, { "id": "stripe-js-named", "psp": "stripe", "kinds": ["script"], "origin": "https://js.stripe.com", "path_pattern": "^/(?:acacia|basil|clover|dahlia)/stripe\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.stripe.com/sdks/stripejs-versioning", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.stripe.com/sdks/stripejs-versioning?locale=en-GB", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.stripe.com/checkout/elements-with-checkout-sessions-api/changelog?locale=en-GB", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.stripe\\.com$"), pathname: new RegExp("^/(?:acacia|basil|clover|dahlia)/stripe\\.js$") }, { "id": "shopify-card-fields-script", "psp": "shopify", "kinds": ["script"], "origin": "https://checkout.pci.shopifyinc.com", "path_pattern": "^/build/[a-f0-9]+/card_fields\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://checkout.pci.shopifyinc.com/build/04ed4e1/card_fields.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\.pci\\.shopifyinc\\.com$"), pathname: new RegExp("^/build/[a-f0-9]+/card_fields\\.js$") }, { "id": "shopify-card-number-frame", "psp": "shopify", "kinds": ["frame", "iframe", "document"], "origin": "https://checkout.pci.shopifyinc.com", "path_pattern": "^/build/[a-f0-9]+/number-(?:ltr|rtl)\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://checkout.pci.shopifyinc.com/build/04ed4e1/card_fields.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\.pci\\.shopifyinc\\.com$"), pathname: new RegExp("^/build/[a-f0-9]+/number-(?:ltr|rtl)\\.html$") }, { "id": "shopify-card-fields-legacy-script", "psp": "shopify", "kinds": ["script"], "origin": "https://checkout.shopifycs.com", "path_pattern": "^/dist/card_fields\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://checkout.shopifycs.com/dist/card_fields.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\.shopifycs\\.com$"), pathname: new RegExp("^/dist/card_fields\\.js$") }, { "id": "stripe-js-script", "psp": "stripe", "kinds": ["script"], "origin": "https://js.stripe.com", "path_pattern": "^/v3/?$", "sources": [{ "kind": "primary_source", "reference": "https://docs.stripe.com/js/including", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.stripe\\.com$"), pathname: new RegExp("^/v3/?$") }, { "id": "braintree-dropin-script", "psp": "braintree", "kinds": ["script"], "origin": "https://js.braintreegateway.com", "path_pattern": "^/web/dropin/[0-9]+\\.[0-9]+\\.[0-9]+/js/dropin(?:\\.min)?\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.paypal.com/braintree/docs/start/hello-client/javascript/v3/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.braintreegateway\\.com$"), pathname: new RegExp("^/web/dropin/[0-9]+\\.[0-9]+\\.[0-9]+/js/dropin(?:\\.min)?\\.js$") }, { "id": "checkout-flow-script", "psp": "checkout_com", "kinds": ["script"], "origin": "https://checkout-web-components.checkout.com", "path_pattern": "^/index\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://www.checkout.com/docs/get-started", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://checkout-web-components.checkout.com/index.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\-web\\-components\\.checkout\\.com$"), pathname: new RegExp("^/index\\.js$") }, { "id": "checkout-flow-frame", "psp": "checkout_com", "kinds": ["frame", "iframe", "document"], "origin": "https://checkout-web-components.checkout.com", "path_pattern": "^/pages/[0-9]+\\.[0-9]+\\.[0-9]+/index\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://checkout-web-components.checkout.com/index.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\-web\\-components\\.checkout\\.com$"), pathname: new RegExp("^/pages/[0-9]+\\.[0-9]+\\.[0-9]+/index\\.html$") }, { "id": "adyen-web-script", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-live.cdn.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/standard/integration/drop-in/best-practices", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\.cdn\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-web-script-host-2", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-test.cdn.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/standard/integration/drop-in/best-practices", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-test\\.cdn\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-web-script-host-3", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-live-us.cdn.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/standard/integration/drop-in/best-practices", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\-us\\.cdn\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-web-script-host-4", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-live-au.cdn.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/standard/integration/drop-in/best-practices", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\-au\\.cdn\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-web-script-host-5", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-live-nea.cdn.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/standard/integration/drop-in/best-practices", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\-nea\\.cdn\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "adyen-web-script-host-6", "psp": "adyen", "kinds": ["script"], "origin": "https://checkoutshopper-live-in.cdn.adyen.com", "path_pattern": "^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.adyen.com/standard/integration/drop-in/best-practices", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkoutshopper\\-live\\-in\\.cdn\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/sdk/[0-9]+\\.[0-9]+\\.[0-9]+/adyen\\.js$") }, { "id": "tranzila-hosted-page", "psp": "tranzila", "kinds": ["frame", "iframe", "document", "form"], "origin": "https://direct.tranzila.com", "path_pattern": "^/[A-Za-z0-9_-]+/iframenew\\.php$", "sources": [{ "kind": "primary_source", "reference": "https://docs.tranzila.com/docs/payments-and-billing/iframe-integration", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.tranzila.com/docs/payments-and-billing/iframe-integration-directng", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.tranzila.com/docs/emv-pinpad/emv-iframe-integration", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^direct\\.tranzila\\.com$"), pathname: new RegExp("^/[A-Za-z0-9_-]+/iframenew\\.php$") }, { "id": "tranzila-hosted-page-host-2", "psp": "tranzila", "kinds": ["frame", "iframe", "document", "form"], "origin": "https://directng.tranzila.com", "path_pattern": "^/[A-Za-z0-9_-]+/iframenew\\.php$", "sources": [{ "kind": "primary_source", "reference": "https://docs.tranzila.com/docs/payments-and-billing/iframe-integration", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.tranzila.com/docs/payments-and-billing/iframe-integration-directng", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.tranzila.com/docs/emv-pinpad/emv-iframe-integration", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^directng\\.tranzila\\.com$"), pathname: new RegExp("^/[A-Za-z0-9_-]+/iframenew\\.php$") }, { "id": "square-web-script", "psp": "square", "kinds": ["script"], "origin": "https://web.squarecdn.com", "path_pattern": "^/v1/square\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.squareup.com/docs/web-payments/quickstart/add-sdk-to-web-client", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^web\\.squarecdn\\.com$"), pathname: new RegExp("^/v1/square\\.js$") }, { "id": "square-web-script-host-2", "psp": "square", "kinds": ["script"], "origin": "https://sandbox.web.squarecdn.com", "path_pattern": "^/v1/square\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.squareup.com/docs/web-payments/quickstart/add-sdk-to-web-client", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^sandbox\\.web\\.squarecdn\\.com$"), pathname: new RegExp("^/v1/square\\.js$") }, { "id": "authorize-net-accept-script", "psp": "authorize_net", "kinds": ["script"], "origin": "https://js.authorize.net", "path_pattern": "^/v1/Accept\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.authorize.net/api/reference/features/acceptjs.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.authorize\\.net$"), pathname: new RegExp("^/v1/Accept\\.js$") }, { "id": "authorize-net-accept-script-host-2", "psp": "authorize_net", "kinds": ["script"], "origin": "https://jstest.authorize.net", "path_pattern": "^/v1/Accept\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.authorize.net/api/reference/features/acceptjs.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^jstest\\.authorize\\.net$"), pathname: new RegExp("^/v1/Accept\\.js$") }, { "id": "authorize-net-acceptui-script", "psp": "authorize_net", "kinds": ["script"], "origin": "https://js.authorize.net", "path_pattern": "^/v3/AcceptUI\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.authorize.net/api/reference/features/acceptjs.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.authorize\\.net$"), pathname: new RegExp("^/v3/AcceptUI\\.js$") }, { "id": "authorize-net-acceptui-script-host-2", "psp": "authorize_net", "kinds": ["script"], "origin": "https://jstest.authorize.net", "path_pattern": "^/v3/AcceptUI\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.authorize.net/api/reference/features/acceptjs.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^jstest\\.authorize\\.net$"), pathname: new RegExp("^/v3/AcceptUI\\.js$") }, { "id": "worldpay-checkout-script", "psp": "worldpay", "kinds": ["script"], "origin": "https://access.worldpay.com", "path_pattern": "^/access-checkout/v2/checkout\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.worldpay.com/access/products/checkout/web", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^access\\.worldpay\\.com$"), pathname: new RegExp("^/access-checkout/v2/checkout\\.js$") }, { "id": "worldpay-checkout-script-host-2", "psp": "worldpay", "kinds": ["script"], "origin": "https://try.access.worldpay.com", "path_pattern": "^/access-checkout/v2/checkout\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.worldpay.com/access/products/checkout/web", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^try\\.access\\.worldpay\\.com$"), pathname: new RegExp("^/access-checkout/v2/checkout\\.js$") }, { "id": "nuvei-websdk-script", "psp": "nuvei", "kinds": ["script"], "origin": "https://cdn.safecharge.com", "path_pattern": "^/safecharge_resources/v1/websdk/safecharge\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.nuvei.com/documentation/accept-payment/web-sdk/quick-start-for-web-sdk/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://cdn.safecharge.com/safecharge_resources/v1/websdk/safecharge.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^cdn\\.safecharge\\.com$"), pathname: new RegExp("^/safecharge_resources/v1/websdk/safecharge\\.js$") }, { "id": "nuvei-card-fields-frame", "psp": "nuvei", "kinds": ["frame", "iframe", "document"], "origin": "https://cdn.safecharge.com", "path_pattern": "^/safecharge_resources/v1/websdk/sfc_inner_card\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://docs.nuvei.com/documentation/accept-payment/web-sdk/nuvei-fields/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://cdn.safecharge.com/safecharge_resources/v1/websdk/sfc_inner_card.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^cdn\\.safecharge\\.com$"), pathname: new RegExp("^/safecharge_resources/v1/websdk/sfc_inner_card\\.html$") }, { "id": "airwallex-components-script", "psp": "airwallex", "kinds": ["script"], "origin": "https://static.airwallex.com", "path_pattern": "^/components/sdk/v1/index\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://www.airwallex.com/docs/payments/get-started/quickstart", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://www.airwallex.com/docs/payments/test-and-go-live/upgrade-to-airwallex.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://www.airwallex.com/docs/payouts/test-and-go-live/upgrade-to-airwallex.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^static\\.airwallex\\.com$"), pathname: new RegExp("^/components/sdk/v1/index\\.js$") }, { "id": "airwallex-elements-legacy-script", "psp": "airwallex", "kinds": ["script"], "origin": "https://checkout.airwallex.com", "path_pattern": "^/assets/elements\\.bundle\\.min\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://www.airwallex.com/docs/payments/test-and-go-live/upgrade-to-airwallex.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\.airwallex\\.com$"), pathname: new RegExp("^/assets/elements\\.bundle\\.min\\.js$") }, { "id": "rapyd-checkout-toolkit-script", "psp": "rapyd", "kinds": ["script"], "origin": "https://checkouttoolkit.rapyd.net", "path_pattern": "^/$", "sources": [{ "kind": "primary_source", "reference": "https://docs.rapyd.net/en/checkout-toolkit-integration.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkouttoolkit\\.rapyd\\.net$"), pathname: new RegExp("^/$") }, { "id": "rapyd-checkout-toolkit-script-host-2", "psp": "rapyd", "kinds": ["script"], "origin": "https://sandboxcheckouttoolkit.rapyd.net", "path_pattern": "^/$", "sources": [{ "kind": "primary_source", "reference": "https://docs.rapyd.net/en/checkout-toolkit-integration.html", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^sandboxcheckouttoolkit\\.rapyd\\.net$"), pathname: new RegExp("^/$") }, { "id": "dlocal-smart-fields-script", "psp": "dlocal", "kinds": ["script"], "origin": "https://js.dlocal.com", "path_pattern": "^/$", "sources": [{ "kind": "primary_source", "reference": "https://docs.dlocal.com/docs/set-up-smart-fields", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.dlocal.com/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://static.dlocal.com/modules/fields/6.18.2/iframe.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.dlocal\\.com$"), pathname: new RegExp("^/$") }, { "id": "dlocal-smart-fields-sandbox-script", "psp": "dlocal", "kinds": ["script"], "origin": "https://js-sandbox.dlocal.com", "path_pattern": "^/$", "sources": [{ "kind": "primary_source", "reference": "https://docs.dlocal.com/docs/set-up-smart-fields", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.dlocal.com/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://static.dlocal.com/modules/fields/6.18.2/iframe.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\-sandbox\\.dlocal\\.com$"), pathname: new RegExp("^/$") }, { "id": "dlocal-smart-fields-parent-6-18-2", "psp": "dlocal", "kinds": ["script"], "origin": "https://static.dlocal.com", "path_pattern": "^/modules/fields/6\\.18\\.2/parent\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.dlocal.com/docs/set-up-smart-fields", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.dlocal.com/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://static.dlocal.com/modules/fields/6.18.2/iframe.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^static\\.dlocal\\.com$"), pathname: new RegExp("^/modules/fields/6\\.18\\.2/parent\\.js$") }, { "id": "dlocal-smart-card-fields-6-18-2", "psp": "dlocal", "kinds": ["frame", "iframe", "document"], "origin": "https://static.dlocal.com", "path_pattern": "^/modules/fields/6\\.18\\.2/inner-(?:pan|card)\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://docs.dlocal.com/docs/set-up-smart-fields", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.dlocal.com/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://static.dlocal.com/modules/fields/6.18.2/iframe.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^static\\.dlocal\\.com$"), pathname: new RegExp("^/modules/fields/6\\.18\\.2/inner-(?:pan|card)\\.html$") }, { "id": "ebanx-js-latest", "psp": "ebanx", "kinds": ["script"], "origin": "https://ebanx-js.ebanx.com", "path_pattern": "^/latest/dist/ebanx\\.min\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.ebanx.com/docs/pay-in/features/cards/tokenization/tokenization-ebanx-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://ebanx-js.ebanx.com/latest/dist/ebanx.min.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^ebanx\\-js\\.ebanx\\.com$"), pathname: new RegExp("^/latest/dist/ebanx\\.min\\.js$") }, { "id": "mercado-pago-sdk-v2", "psp": "mercado_pago", "kinds": ["script"], "origin": "https://sdk.mercadopago.com", "path_pattern": "^/js/v2$", "sources": [{ "kind": "primary_source", "reference": "https://github.com/mercadopago/sdk-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://sdk.mercadopago.com/js/v2", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^sdk\\.mercadopago\\.com$"), pathname: new RegExp("^/js/v2$") }, { "id": "payu-gpo-sdk", "psp": "payu", "kinds": ["script"], "origin": "https://secure.payu.com", "path_pattern": "^/javascript/sdk$", "sources": [{ "kind": "primary_source", "reference": "https://developers.payu.com/europe/docs/checkout/secure-elements/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://secure.payu.com/javascript/sdk", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^secure\\.payu\\.com$"), pathname: new RegExp("^/javascript/sdk$") }, { "id": "payu-gpo-sdk-sandbox", "psp": "payu", "kinds": ["script"], "origin": "https://secure.snd.payu.com", "path_pattern": "^/javascript/sdk$", "sources": [{ "kind": "primary_source", "reference": "https://developers.payu.com/europe/docs/checkout/secure-elements/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://secure.payu.com/javascript/sdk", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^secure\\.snd\\.payu\\.com$"), pathname: new RegExp("^/javascript/sdk$") }, { "id": "payu-gpo-sdk-sandbox-host-2", "psp": "payu", "kinds": ["script"], "origin": "https://merch-prod.snd.payu.com", "path_pattern": "^/javascript/sdk$", "sources": [{ "kind": "primary_source", "reference": "https://developers.payu.com/europe/docs/checkout/secure-elements/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://secure.payu.com/javascript/sdk", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^merch\\-prod\\.snd\\.payu\\.com$"), pathname: new RegExp("^/javascript/sdk$") }, { "id": "payu-gpo-secure-form", "psp": "payu", "kinds": ["frame", "iframe", "document"], "origin": "https://secure.payu.com", "path_pattern": "^/front/secure-form/form/$", "sources": [{ "kind": "primary_source", "reference": "https://developers.payu.com/europe/docs/checkout/secure-elements/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://secure.payu.com/javascript/sdk", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^secure\\.payu\\.com$"), pathname: new RegExp("^/front/secure-form/form/$") }, { "id": "razorpay-standard-checkout-v1", "psp": "razorpay", "kinds": ["script"], "origin": "https://checkout.razorpay.com", "path_pattern": "^/v1/checkout\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://razorpay.com/docs/payments/payment-gateway/web-integration/standard/integration-steps/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://checkout.razorpay.com/v1/checkout.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^checkout\\.razorpay\\.com$"), pathname: new RegExp("^/v1/checkout\\.js$") }, { "id": "mollie-components-v1", "psp": "mollie", "kinds": ["script"], "origin": "https://js.mollie.com", "path_pattern": "^/v1/mollie\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.mollie.com/docs/mollie-components", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.mollie.com/docs/custom-checkout-components", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.mollie.com/v2/mollie.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.mollie\\.com$"), pathname: new RegExp("^/v1/mollie\\.js$") }, { "id": "mollie-components-v2", "psp": "mollie", "kinds": ["script"], "origin": "https://js.mollie.com", "path_pattern": "^/v2/mollie\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.mollie.com/docs/mollie-components", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://docs.mollie.com/docs/custom-checkout-components", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.mollie.com/v2/mollie.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.mollie\\.com$"), pathname: new RegExp("^/v2/mollie\\.js$") }, { "id": "paysafe-js-v1-latest", "psp": "paysafe", "kinds": ["script"], "origin": "https://hosted.paysafe.com", "path_pattern": "^/js/v1/latest/paysafe\\.min\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.paysafe.com/en/api-docs/paysafe-js/overview/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://hosted.paysafe.com/js/v1/latest/paysafe.min.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://developer.paysafe.com/en/api-docs/3ds/using-the-sdk/including-the-3d-secure-2-sdk/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^hosted\\.paysafe\\.com$"), pathname: new RegExp("^/js/v1/latest/paysafe\\.min\\.js$") }, { "id": "paysafe-js-v1-fields", "psp": "paysafe", "kinds": ["frame", "iframe", "document"], "origin": "https://hosted.paysafe.com", "path_pattern": "^/js/v1/latest/index\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://developer.paysafe.com/en/api-docs/paysafe-js/overview/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://hosted.paysafe.com/js/v1/latest/paysafe.min.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://developer.paysafe.com/en/api-docs/3ds/using-the-sdk/including-the-3d-secure-2-sdk/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^hosted\\.paysafe\\.com$"), pathname: new RegExp("^/js/v1/latest/index\\.html$") }, { "id": "paysafe-js-v1-fields-host-2", "psp": "paysafe", "kinds": ["frame", "iframe", "document"], "origin": "https://hosted.test.paysafe.com", "path_pattern": "^/js/v1/latest/index\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://developer.paysafe.com/en/api-docs/paysafe-js/overview/", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://hosted.paysafe.com/js/v1/latest/paysafe.min.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://developer.paysafe.com/en/api-docs/3ds/using-the-sdk/including-the-3d-secure-2-sdk/", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^hosted\\.test\\.paysafe\\.com$"), pathname: new RegExp("^/js/v1/latest/index\\.html$") }, { "id": "recurly-js-v4", "psp": "recurly", "kinds": ["script"], "origin": "https://js.recurly.com", "path_pattern": "^/v4/recurly\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://recurly.com/developers/reference/recurly-js/index.html", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://github.com/recurly/recurly-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.recurly.com/v4/recurly.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.recurly\\.com$"), pathname: new RegExp("^/v4/recurly\\.js$") }, { "id": "recurly-hosted-field-v1", "psp": "recurly", "kinds": ["frame", "iframe", "document"], "origin": "https://api.recurly.com", "path_pattern": "^/js/v1/field\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://recurly.com/developers/reference/recurly-js/index.html", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://github.com/recurly/recurly-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.recurly.com/v4/recurly.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^api\\.recurly\\.com$"), pathname: new RegExp("^/js/v1/field\\.html$") }, { "id": "recurly-hosted-field-v1-host-2", "psp": "recurly", "kinds": ["frame", "iframe", "document"], "origin": "https://api.eu.recurly.com", "path_pattern": "^/js/v1/field\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://recurly.com/developers/reference/recurly-js/index.html", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://github.com/recurly/recurly-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.recurly.com/v4/recurly.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^api\\.eu\\.recurly\\.com$"), pathname: new RegExp("^/js/v1/field\\.html$") }, { "id": "moneris-hosted-tokenization", "psp": "moneris", "kinds": ["frame", "iframe", "document"], "origin": "https://www3.moneris.com", "path_pattern": "^/HPPtoken/index\\.php$", "sources": [{ "kind": "primary_source", "reference": "https://developer.moneris.com/hosted-solutions/docs/setup-guide-tokenization", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://developer.moneris.com/moneris-api/docs/purchase-with-payment-token", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://www3.moneris.com/HPPtoken/hpp_common.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^www3\\.moneris\\.com$"), pathname: new RegExp("^/HPPtoken/index\\.php$") }, { "id": "moneris-hosted-tokenization-host-2", "psp": "moneris", "kinds": ["frame", "iframe", "document"], "origin": "https://esqa.moneris.com", "path_pattern": "^/HPPtoken/index\\.php$", "sources": [{ "kind": "primary_source", "reference": "https://developer.moneris.com/hosted-solutions/docs/setup-guide-tokenization", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://developer.moneris.com/moneris-api/docs/purchase-with-payment-token", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://www3.moneris.com/HPPtoken/hpp_common.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^esqa\\.moneris\\.com$"), pathname: new RegExp("^/HPPtoken/index\\.php$") }, { "id": "moneris-new-io-hosted-tokenization", "psp": "moneris", "kinds": ["frame", "iframe", "document"], "origin": "https://mpg1t.moneris.io", "path_pattern": "^/HPPtoken/index\\.php$", "sources": [{ "kind": "primary_source", "reference": "https://developer.moneris.com/hosted-solutions/docs/setup-guide-tokenization", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://developer.moneris.com/moneris-api/docs/purchase-with-payment-token", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://www3.moneris.com/HPPtoken/hpp_common.js", "reviewed_on": "2026-09-11" }], "variant_unverified": "The current canonical Moneris recognizer contains moneris.com hosts only; moneris.io is not admitted.", hostname: new RegExp("^mpg1t\\.moneris\\.io$"), pathname: new RegExp("^/HPPtoken/index\\.php$") }, { "id": "bambora-na-custom-checkout-1", "psp": "bambora", "kinds": ["script"], "origin": "https://libs.na.bambora.com", "path_pattern": "^/customcheckout/1/customcheckout\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://docs.na.worldline-solutions.com/build-your-integration/checkout-form/custom-checkout/reference", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://libs.na.bambora.com/customcheckout/1/customcheckout.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://libs.na.bambora.com/customcheckout/1.0.5-39/customcheckoutremote.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^libs\\.na\\.bambora\\.com$"), pathname: new RegExp("^/customcheckout/1/customcheckout\\.js$") }, { "id": "bambora-na-fields-1-0-5-39", "psp": "bambora", "kinds": ["frame", "iframe", "document"], "origin": "https://libs.na.bambora.com", "path_pattern": "^/customcheckout/1\\.0\\.5-39/iframe\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://docs.na.worldline-solutions.com/build-your-integration/checkout-form/custom-checkout/reference", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://libs.na.bambora.com/customcheckout/1/customcheckout.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://libs.na.bambora.com/customcheckout/1.0.5-39/customcheckoutremote.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^libs\\.na\\.bambora\\.com$"), pathname: new RegExp("^/customcheckout/1\\.0\\.5-39/iframe\\.html$") }, { "id": "global-payments-js-4-1-3", "psp": "global_payments", "kinds": ["script"], "origin": "https://js.globalpay.com", "path_pattern": "^/4\\.1\\.3/globalpayments\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.globalpayments.com/docs/integration-options/sdk/javascript", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://github.com/globalpayments/globalpayments-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.globalpay.com/4.1.3/globalpayments.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.globalpay.com/v1/globalpayments.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.globalpay\\.com$"), pathname: new RegExp("^/4\\.1\\.3/globalpayments\\.js$") }, { "id": "global-payments-js-v1-alias", "psp": "global_payments", "kinds": ["script"], "origin": "https://js.globalpay.com", "path_pattern": "^/v1/globalpayments\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://developer.globalpayments.com/docs/integration-options/sdk/javascript", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://github.com/globalpayments/globalpayments-js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.globalpay.com/4.1.3/globalpayments.js", "reviewed_on": "2026-09-11" }, { "kind": "primary_source", "reference": "https://js.globalpay.com/v1/globalpayments.js", "reviewed_on": "2026-09-11" }], hostname: new RegExp("^js\\.globalpay\\.com$"), pathname: new RegExp("^/v1/globalpayments\\.js$") });
32
+ // Keep sandbox evidence truthful instead of labelling it with a production origin.
33
+ for (const [baseId, suffix, hostname, origin] of [
34
+ ['square-web-sdk', 'sandbox', /^sandbox\.web\.squarecdn\.com$/, 'https://sandbox.web.squarecdn.com'],
35
+ ['paysafe-js', 'test', /^hosted\.test\.paysafe\.com$/, 'https://hosted.test.paysafe.com'],
36
+ ['worldpay-checkout-sdk', 'try', /^try\.access\.worldpay\.com$/, 'https://try.access.worldpay.com'],
37
+ ['authorize-net-accept', 'test', /^jstest\.authorize\.net$/, 'https://jstest.authorize.net'],
38
+ ]) {
39
+ RULES.push({ ...RULES.find(rule => rule.id === baseId), id: `${baseId}-${suffix}`, hostname, origin });
40
+ }
41
+ const SOURCES = {
42
+ stripe: [{ kind: 'official_documentation', reference: 'https://docs.stripe.com/js/including', reviewed_on: '2026-09-11' }],
43
+ square: [{ kind: 'official_documentation', reference: 'https://developer.squareup.com/docs/web-payments/quickstart/add-sdk-to-web-client', reviewed_on: '2026-09-11' }],
44
+ mollie: [{ kind: 'saved_observation', reference: 'mollie-haak-2026-09-11:hosted-credit-card-document-and-v2-script', reviewed_on: '2026-09-11' }],
45
+ braintree: [{ kind: 'official_documentation', reference: 'https://developer.paypal.com/braintree/docs/start/hello-client/javascript/v3/', reviewed_on: '2026-09-11' }],
46
+ paysafe: [{ kind: 'official_documentation', reference: 'https://developer.paysafe.com/en/api-docs/paysafe-js/overview/', reviewed_on: '2026-09-11' }],
47
+ worldpay: [{ kind: 'official_documentation', reference: 'https://developer.worldpay.com/products/checkout/web', reviewed_on: '2026-09-11' }],
48
+ authorize_net: [{ kind: 'official_documentation', reference: 'https://developer.authorize.net/api/reference/features/acceptjs.html', reviewed_on: '2026-09-11' }],
49
+ razorpay: [{ kind: 'official_documentation', reference: 'https://razorpay.com/docs/payments/payment-gateway/web-integration/standard/integration-steps/', reviewed_on: '2026-09-11' }],
50
+ vgs: [{ kind: 'official_documentation', reference: 'https://docs.verygoodsecurity.com/vault/developer-tools/vgs-collect/js/integration', reviewed_on: '2026-09-11' }],
51
+ };
52
+ const FLOWS = [
53
+ { id: 'mollie.hosted_components', psp: 'mollie', operation: 'mollie.card_request', operation_version: 1, mode: 'token', server_constraint: 'eligible', limitations: [
54
+ 'The payment request must match the supported Mollie Components card-token format.',
55
+ 'Authentication and merchant confirmation must finish in the merchant browser.',
56
+ 'Merchant configuration, card eligibility and processor approval still determine whether the purchase succeeds.',
57
+ ] },
58
+ { id: 'vgs.iframe_bound_tokenization', psp: 'vgs', operation: 'vgs.iframe_bound_tokenization', operation_version: 1, mode: 'token', server_constraint: 'unsupported', limitations: [
59
+ 'VGS requires tokenization from its own iframe; the Vault cannot replay this flow from the approval page.',
60
+ ] },
61
+ ];
62
+ const FLOW_BY_ID = new Map(FLOWS.map(flow => [flow.id, flow]));
63
+ const RULE_BY_ID = new Map(RULES.map(rule => [rule.id, rule]));
64
+ const DEFAULT_PROFILE = {
65
+ schema_version: 1, profile_version: 'preflight-2', catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION,
66
+ integration: { id: 'direct_sdk', version: 'bundled' },
67
+ processor_entries: CHECKOUT_PREFLIGHT_CAPABILITIES.processors.map(processor => ({
68
+ psp: processor.psp, mode: processor.mode, scenario: 'one_time', status: 'supported',
69
+ })),
70
+ entries: [{ flow: 'mollie.hosted_components', operation: 'mollie.card_request', operation_version: 1, mode: 'token', scenario: 'one_time', status: 'supported' }],
71
+ };
72
+ const clone = (value) => JSON.parse(JSON.stringify(value));
73
+ const record = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
74
+ const exactKeys = (value, keys) => Object.keys(value).every(key => keys.includes(key));
75
+ const id = (value) => typeof value === 'string' && /^[A-Za-z0-9][A-Za-z0-9._+-]{0,119}$/.test(value);
76
+ const frameId = (value) => Number.isSafeInteger(value) && value >= 0 && value < CHECKOUT_PREFLIGHT_LIMITS.frames;
77
+ const unique = (items) => [...new Set(items)];
78
+ function dateTime(value) {
79
+ if (typeof value !== 'string' || value.length > 40)
80
+ return false;
81
+ const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(?:Z|[+-](\d{2}):(\d{2}))$/.exec(value);
82
+ if (!match)
83
+ return false;
84
+ const [year, month, day, hour, minute, second, zoneHour = 0, zoneMinute = 0] = match.slice(1).map(part => part === undefined ? 0 : Number(part));
85
+ const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
86
+ const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
87
+ return month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] && hour <= 23 && minute <= 59 && second <= 59
88
+ && zoneHour <= 23 && zoneMinute <= 59 && Number.isFinite(Date.parse(value));
89
+ }
90
+ function metadata(value) {
91
+ return KINDS.includes(value.kind) && frameId(value.frame_id) && (value.parent_frame_id === null || frameId(value.parent_frame_id))
92
+ && (value.frame_id !== 0 || value.parent_frame_id === null)
93
+ && value.parent_frame_id !== value.frame_id && (value.visible === null || typeof value.visible === 'boolean');
94
+ }
95
+ function consistentParents(signals) {
96
+ const parents = new Map();
97
+ for (const signal of signals) {
98
+ if (parents.has(signal.frame_id) && parents.get(signal.frame_id) !== signal.parent_frame_id)
99
+ return false;
100
+ parents.set(signal.frame_id, signal.parent_frame_id);
101
+ }
102
+ for (const frame of parents.keys()) {
103
+ const visited = new Set();
104
+ let current = frame;
105
+ while (current !== null && current !== undefined) {
106
+ if (visited.has(current))
107
+ return false;
108
+ visited.add(current);
109
+ current = parents.get(current);
110
+ }
111
+ }
112
+ return true;
113
+ }
114
+ function cleanObservation(input) {
115
+ if (!record(input) || !exactKeys(input, ['complete', 'truncated', 'reasons']) || typeof input.complete !== 'boolean' || typeof input.truncated !== 'boolean'
116
+ || !Array.isArray(input.reasons) || input.reasons.length > 32 || Array.from(input.reasons).some(reason => !OBSERVATION_REASONS.includes(reason))) {
117
+ return { complete: false, truncated: false, reasons: ['invalid_observation'] };
118
+ }
119
+ const reasons = unique(input.reasons);
120
+ const complete = input.complete && !input.truncated && reasons.length === 0;
121
+ return { complete, truncated: input.truncated, reasons: complete ? [] : unique([...reasons, 'collection_incomplete']) };
122
+ }
123
+ const byteLength = (value) => new TextEncoder().encode(JSON.stringify(value)).length;
124
+ function incomplete(observation, reason, truncated = false) {
125
+ observation.complete = false;
126
+ observation.truncated ||= truncated;
127
+ observation.reasons = unique([...observation.reasons, reason]);
128
+ }
129
+ /** Normalize observations locally. Unknown assets are omitted; no URL leaves this function. */
130
+ export function normalizeCheckoutSignals(input) {
131
+ const snapshot = { schema_version: 1, catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION, signals: [], observation: cleanObservation(record(input) ? input.observation : null) };
132
+ if (!record(input) || !exactKeys(input, ['signals', 'observation']) || !Array.isArray(input.signals)) {
133
+ incomplete(snapshot.observation, 'invalid_observation');
134
+ return snapshot;
135
+ }
136
+ if (input.signals.length > CHECKOUT_PREFLIGHT_LIMITS.signals)
137
+ incomplete(snapshot.observation, 'signal_limit', true);
138
+ const seen = new Set();
139
+ for (const raw of input.signals.slice(0, CHECKOUT_PREFLIGHT_LIMITS.signals)) {
140
+ if (!record(raw) || !exactKeys(raw, ['kind', 'url', 'frame_id', 'parent_frame_id', 'visible']) || !metadata(raw)) {
141
+ incomplete(snapshot.observation, 'invalid_observation');
142
+ continue;
143
+ }
144
+ if (typeof raw.url !== 'string' || raw.url.length > CHECKOUT_PREFLIGHT_LIMITS.url_length) {
145
+ incomplete(snapshot.observation, 'invalid_url');
146
+ continue;
147
+ }
148
+ let url;
149
+ try {
150
+ url = new URL(raw.url);
151
+ }
152
+ catch {
153
+ incomplete(snapshot.observation, 'invalid_url');
154
+ continue;
155
+ }
156
+ // Non-HTTPS local/blank frames provide no PSP evidence. Credentials and nondefault ports are refused.
157
+ if (url.protocol !== 'https:' || url.username || url.password || url.port)
158
+ continue;
159
+ for (const rule of RULES) {
160
+ if (!rule.kinds.includes(raw.kind) || !rule.hostname.test(url.hostname) || !rule.pathname.test(url.pathname))
161
+ continue;
162
+ const signal = { rule_id: rule.id, kind: raw.kind, frame_id: raw.frame_id, parent_frame_id: raw.parent_frame_id, visible: raw.visible };
163
+ const key = JSON.stringify(signal);
164
+ if (!seen.has(key)) {
165
+ // One observed asset can match more than one reviewed fingerprint.
166
+ // Bound normalized evidence independently of the raw observation count.
167
+ if (snapshot.signals.length >= CHECKOUT_PREFLIGHT_LIMITS.signals) {
168
+ incomplete(snapshot.observation, 'signal_limit', true);
169
+ continue;
170
+ }
171
+ snapshot.signals.push(signal);
172
+ seen.add(key);
173
+ }
174
+ }
175
+ }
176
+ while (byteLength(snapshot) > CHECKOUT_PREFLIGHT_LIMITS.snapshot_bytes && snapshot.signals.length) {
177
+ snapshot.signals.pop();
178
+ incomplete(snapshot.observation, 'snapshot_limit', true);
179
+ }
180
+ if (!consistentParents(snapshot.signals))
181
+ incomplete(snapshot.observation, 'invalid_observation');
182
+ return snapshot;
183
+ }
184
+ /** The returned catalog is metadata only. It does not change card destination recognition. */
185
+ export function getCheckoutPreflightCatalog() {
186
+ return clone({
187
+ schema_version: 1, catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION, scope: 'preflight_hint',
188
+ integration_version_note: 'bundled describes the capabilities accompanying this helper, not a claim about another installed SDK version.',
189
+ limits: CHECKOUT_PREFLIGHT_LIMITS,
190
+ known_psps: KNOWN_PSPS.map(psp => ({ psp, detection: RULES.some(rule => rule.psp === psp) ? 'reviewed_rules' : 'unknown' })),
191
+ rules: RULES.map(({ hostname, pathname, ...rule }) => ({ ...rule, hostname_pattern: hostname.source, pathname_pattern: pathname.source, sources: rule.sources ?? SOURCES[rule.psp] })),
192
+ processors: CHECKOUT_PREFLIGHT_CAPABILITIES.processors, exclusions: CHECKOUT_PREFLIGHT_CAPABILITIES.exclusions,
193
+ flows: FLOWS, direct_sdk_profile: DEFAULT_PROFILE,
194
+ kernel_profile_template: { schema_version: 1, profile_version: 'kernel-template-1', catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION,
195
+ integration: { id: 'kernel_native', version: 'REPLACE-WITH-ADAPTER-VERSION' }, entries: [], processor_entries: [] },
196
+ observation_reason_codes: OBSERVATION_REASONS,
197
+ });
198
+ }
199
+ function validSnapshot(input) {
200
+ return record(input) && exactKeys(input, ['schema_version', 'catalog_version', 'signals', 'observation'])
201
+ && input.schema_version === 1 && input.catalog_version === CHECKOUT_PREFLIGHT_CATALOG_VERSION
202
+ && Array.isArray(input.signals) && input.signals.length <= CHECKOUT_PREFLIGHT_LIMITS.signals
203
+ && Array.from(input.signals).every(signal => record(signal) && exactKeys(signal, ['rule_id', 'kind', 'frame_id', 'parent_frame_id', 'visible']) && metadata(signal)
204
+ && id(signal.rule_id) && !!RULE_BY_ID.get(signal.rule_id)?.kinds.includes(signal.kind))
205
+ && consistentParents(input.signals)
206
+ && record(input.observation) && exactKeys(input.observation, ['complete', 'truncated', 'reasons'])
207
+ && typeof input.observation.complete === 'boolean' && typeof input.observation.truncated === 'boolean'
208
+ && Array.isArray(input.observation.reasons) && input.observation.reasons.length <= 32
209
+ && Array.from(input.observation.reasons).every(reason => OBSERVATION_REASONS.includes(reason))
210
+ && byteLength(input) <= CHECKOUT_PREFLIGHT_LIMITS.snapshot_bytes;
211
+ }
212
+ function validIntegration(value) {
213
+ return record(value) && exactKeys(value, ['id', 'version']) && ['direct_sdk', 'kernel_native'].includes(value.id) && (value.version === null || id(value.version));
214
+ }
215
+ function profileError(profile, integration, now) {
216
+ if (!record(profile) || !exactKeys(profile, ['schema_version', 'profile_version', 'catalog_version', 'integration', 'entries', 'processor_entries', 'expires_at'])
217
+ || profile.schema_version !== 1 || !id(profile.profile_version) || !validIntegration(profile.integration) || !id(profile.integration.version)
218
+ || !Array.isArray(profile.entries) || profile.entries.length > 256
219
+ || (profile.processor_entries !== undefined && (!Array.isArray(profile.processor_entries) || profile.processor_entries.length > 256)))
220
+ return 'integration_profile_invalid';
221
+ if (profile.catalog_version !== CHECKOUT_PREFLIGHT_CATALOG_VERSION)
222
+ return 'integration_profile_incompatible';
223
+ if (profile.integration.id !== integration.id || profile.integration.version !== integration.version)
224
+ return 'integration_profile_mismatch';
225
+ if (profile.expires_at !== undefined) {
226
+ const expires = dateTime(profile.expires_at) ? Date.parse(profile.expires_at) : NaN;
227
+ const time = now === undefined ? Date.now() : dateTime(now) ? Date.parse(now) : NaN;
228
+ if (!Number.isFinite(expires) || !Number.isFinite(time))
229
+ return 'integration_profile_invalid';
230
+ if (expires <= time)
231
+ return 'integration_profile_expired';
232
+ }
233
+ const entries = new Set();
234
+ for (const entry of profile.entries) {
235
+ if (!record(entry) || !exactKeys(entry, ['flow', 'operation', 'operation_version', 'mode', 'scenario', 'status', 'limitations'])
236
+ || !id(entry.flow) || !id(entry.operation) || !SCENARIOS.includes(entry.scenario) || !['supported', 'unsupported'].includes(entry.status)
237
+ || (entry.limitations !== undefined && (!Array.isArray(entry.limitations) || entry.limitations.length > 16 || Array.from(entry.limitations).some(text => typeof text !== 'string' || text.length > 256 || /[\x00-\x1f]/.test(text)))))
238
+ return 'integration_profile_invalid';
239
+ const flow = FLOW_BY_ID.get(entry.flow);
240
+ if (!flow || entry.operation !== flow.operation || entry.operation_version !== flow.operation_version || entry.mode !== flow.mode)
241
+ return 'integration_profile_incompatible';
242
+ const key = `${entry.flow}:${entry.scenario}`;
243
+ if (entries.has(key))
244
+ return 'integration_profile_invalid';
245
+ entries.add(key);
246
+ }
247
+ const processors = new Set();
248
+ for (const entry of profile.processor_entries ?? []) {
249
+ if (!record(entry) || !exactKeys(entry, ['psp', 'mode', 'scenario', 'status', 'limitations'])
250
+ || !id(entry.psp) || !SCENARIOS.includes(entry.scenario) || !['supported', 'unsupported'].includes(entry.status)
251
+ || (entry.limitations !== undefined && (!Array.isArray(entry.limitations) || entry.limitations.length > 16 || Array.from(entry.limitations).some(text => typeof text !== 'string' || text.length > 256 || /[\x00-\x1f]/.test(text)))))
252
+ return 'integration_profile_invalid';
253
+ const processor = PROCESSOR_BY_ID.get(entry.psp);
254
+ if (!processor || processor.mode !== entry.mode)
255
+ return 'integration_profile_incompatible';
256
+ const key = `${entry.psp}:${entry.scenario}`;
257
+ if (processors.has(key))
258
+ return 'integration_profile_invalid';
259
+ processors.add(key);
260
+ }
261
+ return null;
262
+ }
263
+ /** Classify a sanitized snapshot. No browser, HTTP, or payment operations occur here. */
264
+ export function assessCheckoutSupport(input, options = {}) {
265
+ const opts = record(options) ? options : {};
266
+ const fallbackIntegrationId = record(opts.integration) && opts.integration.id === 'kernel_native' ? 'kernel_native' : 'direct_sdk';
267
+ const integration = validIntegration(opts.integration) ? clone(opts.integration) : {
268
+ id: fallbackIntegrationId,
269
+ version: opts.integration === undefined ? 'bundled' : null,
270
+ };
271
+ const result = {
272
+ schema_version: 1, catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION, integration,
273
+ scenario: opts.scenario !== undefined && SCENARIOS.includes(opts.scenario) ? opts.scenario : 'one_time', scenario_defaulted: opts.scenario === undefined,
274
+ psp: null, flow: null, mode: null, status: 'unknown', support_scope: null, checkout_flow_status: 'unknown', candidates: [], reason_codes: [], limitations: [], missing_evidence: [],
275
+ observation: { complete: false, truncated: false, reasons: ['invalid_observation'] }, scope: 'preflight_hint', merchant_confirmation_required: true,
276
+ };
277
+ if (!record(options) || !exactKeys(opts, ['scenario', 'integration', 'profile', 'now']) || (opts.scenario !== undefined && !SCENARIOS.includes(opts.scenario))
278
+ || (opts.integration !== undefined && !validIntegration(opts.integration)) || (opts.now !== undefined && !dateTime(opts.now))) {
279
+ result.reason_codes = ['invalid_options'];
280
+ return result;
281
+ }
282
+ if (!validSnapshot(input)) {
283
+ result.reason_codes = [record(input) && input.catalog_version !== CHECKOUT_PREFLIGHT_CATALOG_VERSION ? 'catalog_incompatible' : 'invalid_snapshot'];
284
+ return result;
285
+ }
286
+ result.observation = cleanObservation(input.observation);
287
+ const candidates = new Map();
288
+ const activeFlows = new Set();
289
+ const activePsps = new Set();
290
+ const activeFlowFrames = new Set();
291
+ let missingCorroboration = false;
292
+ for (const signal of input.signals) {
293
+ const rule = RULE_BY_ID.get(signal.rule_id);
294
+ const active = signal.visible === true && (['frame', 'iframe', 'form'].includes(signal.kind)
295
+ || signal.kind === 'document' && signal.frame_id === 0 && signal.parent_frame_id === null);
296
+ const candidate = candidates.get(rule.psp) ?? { psp: rule.psp, relevance: 'undetermined', evidence: [] };
297
+ candidate.evidence.push({ ...clone(signal), origin: rule.origin, path_pattern: rule.path_pattern });
298
+ if (active) {
299
+ candidate.relevance = 'active';
300
+ activePsps.add(rule.psp);
301
+ if (rule.flow) {
302
+ // A hosted route can also display an expired/error page. Require the reviewed
303
+ // Components script in that document; a similarly named asset elsewhere is insufficient.
304
+ const corroborated = rule.flow !== 'mollie.hosted_components' || signal.kind !== 'iframe' && input.signals.some(other => other.rule_id === 'mollie-components-script' && other.kind === 'script' && other.frame_id === signal.frame_id && other.parent_frame_id === signal.parent_frame_id);
305
+ if (corroborated) {
306
+ activeFlows.add(rule.flow);
307
+ activeFlowFrames.add(signal.frame_id);
308
+ }
309
+ else
310
+ missingCorroboration = true;
311
+ }
312
+ }
313
+ candidates.set(rule.psp, candidate);
314
+ }
315
+ result.candidates = [...candidates.values()].sort((a, b) => a.psp.localeCompare(b.psp));
316
+ if (missingCorroboration && activeFlows.size === 0)
317
+ result.reason_codes.push('flow_corroboration_missing');
318
+ if (activePsps.size === 1)
319
+ result.psp = [...activePsps][0];
320
+ else if (activePsps.size === 0 && candidates.size === 1)
321
+ result.psp = [...candidates.keys()][0];
322
+ if (!result.observation.complete)
323
+ result.reason_codes.push('observation_incomplete');
324
+ if (!input.signals.length) {
325
+ result.reason_codes.push('psp_not_detected');
326
+ result.missing_evidence.push('payment_page_signal');
327
+ }
328
+ if (activePsps.size > 1 || activeFlows.size > 1 || activeFlowFrames.size > 1 || activePsps.size === 0 && candidates.size > 1)
329
+ result.reason_codes.push('ambiguous_checkout');
330
+ if (activeFlows.size !== 1 || result.psp === null) {
331
+ result.reason_codes.push('checkout_flow_unidentified');
332
+ result.missing_evidence.push('active_checkout_flow');
333
+ }
334
+ else {
335
+ const flow = FLOW_BY_ID.get([...activeFlows][0]);
336
+ if (flow.psp === result.psp) {
337
+ result.flow = flow.id;
338
+ result.mode = flow.mode;
339
+ result.limitations.push(...flow.limitations);
340
+ }
341
+ }
342
+ if (!result.flow && result.candidates.length)
343
+ result.limitations.push('Processor assets alone do not establish the active card payment flow.');
344
+ const profile = opts.profile === undefined ? (integration.id === 'direct_sdk' && integration.version === 'bundled' ? DEFAULT_PROFILE : undefined) : opts.profile;
345
+ let error = profile === undefined ? 'integration_profile_missing' : profileError(profile, integration, opts.now);
346
+ if (integration.version === null)
347
+ error = 'integration_version_missing';
348
+ if (error) {
349
+ result.reason_codes.push(error);
350
+ result.missing_evidence.push('compatible_integration_profile');
351
+ }
352
+ result.reason_codes = unique(result.reason_codes);
353
+ const ambiguous = result.reason_codes.includes('ambiguous_checkout');
354
+ result.checkout_flow_status = ambiguous ? 'ambiguous' : result.flow ? 'identified' : 'unknown';
355
+ // Processor capability and observed checkout compatibility answer different questions.
356
+ // Missing flow evidence is advisory when an identified processor has an explicit
357
+ // implementation declaration. Incomplete, contradictory or invalid input stays unknown.
358
+ if (!result.observation.complete || ambiguous || error || !result.psp || missingCorroboration && !result.flow)
359
+ return result;
360
+ const flow = result.flow ? FLOW_BY_ID.get(result.flow) : undefined;
361
+ if (flow?.server_constraint === 'unsupported') {
362
+ result.status = 'unsupported';
363
+ result.support_scope = 'checkout_flow';
364
+ result.reason_codes.push('vault_flow_unsupported');
365
+ return result;
366
+ }
367
+ // A hidden document cannot lend its scripts to a visible card checkout. Script-only
368
+ // observations with no known hidden container can still identify an available adapter.
369
+ const eligible = input.signals.some(signal => RULE_BY_ID.get(signal.rule_id).psp === result.psp
370
+ && (signal.kind === 'script' ? signal.visible !== false && !input.signals.some(container => container.frame_id === signal.frame_id && ['document', 'frame'].includes(container.kind) && container.visible !== true)
371
+ : signal.visible === true));
372
+ if (!eligible) {
373
+ result.reason_codes.push('payment_signal_inactive');
374
+ return result;
375
+ }
376
+ {
377
+ // A native declaration cannot expand the shared Vault's admitted processor variants.
378
+ const incompatible = input.signals.map(signal => ({ signal, rule: RULE_BY_ID.get(signal.rule_id) }))
379
+ .filter(({ signal, rule }) => rule.psp === result.psp && rule.variant_unverified
380
+ && (signal.kind === 'script' ? signal.visible !== false : signal.visible === true));
381
+ if (incompatible.length) {
382
+ result.reason_codes.push('processor_variant_unverified');
383
+ result.limitations.push(...incompatible.map(({ rule }) => rule.variant_unverified));
384
+ return result;
385
+ }
386
+ }
387
+ const processor = PROCESSOR_BY_ID.get(result.psp);
388
+ const scenario = processor?.scenarios[result.scenario];
389
+ if (processor) {
390
+ const bundledSdk = integration.id === 'direct_sdk' && integration.version === 'bundled';
391
+ if (bundledSdk)
392
+ result.limitations.push(...processor.limitations);
393
+ for (const variant of processor.unsupported_variants) {
394
+ if (bundledSdk || variant.constraint === 'vault')
395
+ result.limitations.push(variant.reason);
396
+ }
397
+ }
398
+ if (scenario && (scenario.status === 'unsupported' || scenario.status === 'outside_vault')) {
399
+ result.status = 'unsupported';
400
+ result.mode = processor.mode;
401
+ result.support_scope = 'processor_integration';
402
+ result.reason_codes.push(scenario.reason);
403
+ return result;
404
+ }
405
+ const profileValue = profile;
406
+ const entry = flow && profileValue.entries.find(entry => entry.flow === flow.id && entry.scenario === result.scenario);
407
+ if (entry) {
408
+ result.status = entry.status;
409
+ result.support_scope = 'checkout_flow';
410
+ result.reason_codes.push(entry.status === 'supported' ? 'flow_supported_by_integration' : 'integration_flow_unsupported');
411
+ result.limitations.push(...(entry.limitations ?? []));
412
+ return result;
413
+ }
414
+ if (!processor)
415
+ return result;
416
+ result.mode = processor.mode;
417
+ const processorEntry = profileValue.processor_entries?.find(entry => entry.psp === processor.psp && entry.scenario === result.scenario);
418
+ if (!processorEntry) {
419
+ result.reason_codes.push(flow ? 'integration_flow_undeclared' : 'integration_processor_undeclared');
420
+ result.missing_evidence.push(flow ? 'integration_flow_capability' : 'integration_processor_capability');
421
+ return result;
422
+ }
423
+ result.status = processorEntry.status;
424
+ result.support_scope = 'processor_integration';
425
+ result.reason_codes.push(processorEntry.status === 'supported' ? 'processor_supported_by_integration' : 'integration_processor_unsupported');
426
+ result.limitations.push(...(processorEntry.limitations ?? []));
427
+ result.limitations = unique(result.limitations);
428
+ return result;
429
+ }
430
+ /** Machine-readable transport shapes; semantic compatibility is checked by the classifier. */
431
+ export function getCheckoutPreflightSchemas() {
432
+ const text = { type: 'string', minLength: 1, maxLength: 120, pattern: '^[A-Za-z0-9][A-Za-z0-9._+-]{0,119}$' };
433
+ const integration = { type: 'object', additionalProperties: false, required: ['id', 'version'], properties: { id: { enum: ['direct_sdk', 'kernel_native'] }, version: { anyOf: [text, { type: 'null' }] } } };
434
+ const observation = { type: 'object', additionalProperties: false, required: ['complete', 'truncated', 'reasons'], properties: { complete: { type: 'boolean' }, truncated: { type: 'boolean' }, reasons: { type: 'array', maxItems: 32, uniqueItems: true, items: { enum: OBSERVATION_REASONS } } } };
435
+ const signal = { type: 'object', additionalProperties: false, required: ['rule_id', 'kind', 'frame_id', 'parent_frame_id', 'visible'], properties: {
436
+ rule_id: { enum: RULES.map(rule => rule.id) }, kind: { enum: KINDS }, frame_id: { type: 'integer', minimum: 0, maximum: 63 },
437
+ parent_frame_id: { anyOf: [{ type: 'integer', minimum: 0, maximum: 63 }, { type: 'null' }] }, visible: { type: ['boolean', 'null'] },
438
+ } };
439
+ const profile = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
440
+ required: ['schema_version', 'profile_version', 'catalog_version', 'integration', 'entries'], properties: {
441
+ schema_version: { const: 1 }, profile_version: text, catalog_version: { const: CHECKOUT_PREFLIGHT_CATALOG_VERSION }, integration,
442
+ processor_entries: { type: 'array', maxItems: 256, items: {
443
+ type: 'object', additionalProperties: false, required: ['psp', 'mode', 'scenario', 'status'], properties: {
444
+ psp: { enum: KNOWN_PSPS }, mode: { enum: ['token', 'cse', 'hosted_form'] }, scenario: { enum: SCENARIOS }, status: { enum: ['supported', 'unsupported'] },
445
+ limitations: { type: 'array', maxItems: 16, items: { type: 'string', maxLength: 256, pattern: '^[^\\u0000-\\u001f]*$' } },
446
+ },
447
+ } },
448
+ expires_at: { type: 'string', format: 'date-time', maxLength: 40 }, entries: { type: 'array', maxItems: 256, items: {
449
+ type: 'object', additionalProperties: false, required: ['flow', 'operation', 'operation_version', 'mode', 'scenario', 'status'], properties: {
450
+ flow: { enum: FLOWS.map(flow => flow.id) }, operation: { enum: FLOWS.map(flow => flow.operation) }, operation_version: { const: 1 },
451
+ mode: { enum: ['token', 'cse', 'hosted_form'] }, scenario: { enum: SCENARIOS }, status: { enum: ['supported', 'unsupported'] },
452
+ limitations: { type: 'array', maxItems: 16, items: { type: 'string', maxLength: 256, pattern: '^[^\\u0000-\\u001f]*$' } },
453
+ },
454
+ } },
455
+ } };
456
+ const snapshot = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
457
+ required: ['schema_version', 'catalog_version', 'signals', 'observation'], properties: {
458
+ schema_version: { const: 1 }, catalog_version: { const: CHECKOUT_PREFLIGHT_CATALOG_VERSION },
459
+ signals: { type: 'array', maxItems: CHECKOUT_PREFLIGHT_LIMITS.signals, items: signal }, observation,
460
+ } };
461
+ const evidence = { ...signal, required: [...signal.required, 'origin', 'path_pattern'], properties: { ...signal.properties, origin: { type: 'string', maxLength: 256 }, path_pattern: { type: 'string', maxLength: 256 } } };
462
+ const result = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
463
+ required: ['schema_version', 'catalog_version', 'integration', 'scenario', 'scenario_defaulted', 'psp', 'flow', 'mode', 'status', 'support_scope', 'checkout_flow_status', 'candidates', 'reason_codes', 'limitations', 'missing_evidence', 'observation', 'scope', 'merchant_confirmation_required'], properties: {
464
+ schema_version: { const: 1 }, catalog_version: { const: CHECKOUT_PREFLIGHT_CATALOG_VERSION }, integration,
465
+ scenario: { enum: SCENARIOS }, scenario_defaulted: { type: 'boolean' }, psp: { type: ['string', 'null'] }, flow: { type: ['string', 'null'] }, mode: { enum: ['token', 'cse', 'hosted_form', null] },
466
+ support_scope: { enum: ['processor_integration', 'checkout_flow', null] }, checkout_flow_status: { enum: ['identified', 'unknown', 'ambiguous'] },
467
+ status: { enum: ['supported', 'unsupported', 'unknown'] }, candidates: { type: 'array', items: { type: 'object', additionalProperties: false, required: ['psp', 'relevance', 'evidence'], properties: {
468
+ psp: { type: 'string' }, relevance: { enum: ['active', 'undetermined'] }, evidence: { type: 'array', items: evidence },
469
+ } } }, reason_codes: { type: 'array', items: { type: 'string' } }, limitations: { type: 'array', items: { type: 'string' } }, missing_evidence: { type: 'array', items: { type: 'string' } }, observation,
470
+ scope: { const: 'preflight_hint' }, merchant_confirmation_required: { const: true },
471
+ } };
472
+ const rawSignalProperties = { ...signal.properties, url: { type: 'string', maxLength: CHECKOUT_PREFLIGHT_LIMITS.url_length } };
473
+ delete rawSignalProperties.rule_id;
474
+ const observations = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
475
+ required: ['signals', 'observation'], properties: { signals: { type: 'array', maxItems: CHECKOUT_PREFLIGHT_LIMITS.signals, items: {
476
+ type: 'object', additionalProperties: false, required: ['url', 'kind', 'frame_id', 'parent_frame_id', 'visible'], properties: rawSignalProperties,
477
+ } }, observation } };
478
+ const options = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false, properties: {
479
+ scenario: { enum: SCENARIOS }, integration, profile, now: { type: 'string', format: 'date-time', maxLength: 40 },
480
+ } };
481
+ return clone({ observations, options, snapshot, profile, result });
482
+ }
@@ -0,0 +1,2 @@
1
+ // Read-only discovery is separate from request interception and authorization.
2
+ export * from './preflight.generated.js';