@agent-cards/checkout 0.18.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +6 -669
  2. package/cdp.d.ts +1 -0
  3. package/cdp.js +2 -0
  4. package/index.d.ts +1 -0
  5. package/index.js +2 -0
  6. package/package.json +33 -33
  7. package/playwright.d.ts +1 -0
  8. package/playwright.js +2 -0
  9. package/preflight.d.ts +1 -0
  10. package/preflight.js +2 -0
  11. package/CHANGELOG.md +0 -124
  12. package/PREFLIGHT.md +0 -308
  13. package/dist/adyen.generated.d.ts +0 -24
  14. package/dist/adyen.generated.js +0 -64
  15. package/dist/attachment.d.ts +0 -11
  16. package/dist/attachment.js +0 -50
  17. package/dist/braintree.d.ts +0 -2
  18. package/dist/braintree.generated.d.ts +0 -10
  19. package/dist/braintree.generated.js +0 -302
  20. package/dist/braintree.js +0 -2
  21. package/dist/builtin-registry.generated.d.ts +0 -2
  22. package/dist/builtin-registry.generated.js +0 -1
  23. package/dist/card-fields.generated.d.ts +0 -3
  24. package/dist/card-fields.generated.js +0 -46
  25. package/dist/cdp.d.ts +0 -189
  26. package/dist/cdp.js +0 -2194
  27. package/dist/checkout-com.generated.d.ts +0 -4
  28. package/dist/checkout-com.generated.js +0 -183
  29. package/dist/client.d.ts +0 -618
  30. package/dist/client.js +0 -1251
  31. package/dist/hosted-form.d.ts +0 -44
  32. package/dist/hosted-form.js +0 -78
  33. package/dist/index.d.ts +0 -13
  34. package/dist/index.js +0 -6
  35. package/dist/lifecycle.d.ts +0 -165
  36. package/dist/lifecycle.js +0 -370
  37. package/dist/mercado-checkout.d.ts +0 -20
  38. package/dist/mercado-checkout.generated.d.ts +0 -52
  39. package/dist/mercado-checkout.generated.js +0 -198
  40. package/dist/mercado-checkout.js +0 -108
  41. package/dist/owned-shop.generated.d.ts +0 -24
  42. package/dist/owned-shop.generated.js +0 -108
  43. package/dist/paysafe.generated.d.ts +0 -12
  44. package/dist/paysafe.generated.js +0 -87
  45. package/dist/playwright.d.ts +0 -3
  46. package/dist/playwright.js +0 -3
  47. package/dist/preflight-capabilities.generated.d.ts +0 -1253
  48. package/dist/preflight-capabilities.generated.js +0 -1929
  49. package/dist/preflight-catalog.json +0 -4595
  50. package/dist/preflight-playwright.d.ts +0 -34
  51. package/dist/preflight-playwright.js +0 -355
  52. package/dist/preflight-schemas.json +0 -1110
  53. package/dist/preflight.d.ts +0 -1
  54. package/dist/preflight.generated.d.ts +0 -1965
  55. package/dist/preflight.generated.js +0 -556
  56. package/dist/preflight.js +0 -2
  57. package/dist/preparation.d.ts +0 -31
  58. package/dist/preparation.js +0 -164
  59. package/dist/prepared-processor.d.ts +0 -10
  60. package/dist/prepared-processor.js +0 -122
  61. package/dist/recurly.generated.d.ts +0 -1
  62. package/dist/recurly.generated.js +0 -87
  63. package/dist/registry.d.ts +0 -76
  64. package/dist/registry.js +0 -296
  65. package/dist/spreedly.generated.d.ts +0 -10
  66. package/dist/spreedly.generated.js +0 -332
  67. package/dist/stripe-checkout.d.ts +0 -81
  68. package/dist/stripe-checkout.generated.d.ts +0 -82
  69. package/dist/stripe-checkout.generated.js +0 -1004
  70. package/dist/stripe-checkout.js +0 -140
  71. package/dist/substitute.d.ts +0 -38
  72. package/dist/substitute.js +0 -23
  73. package/dist/substitutions.generated.d.ts +0 -10
  74. package/dist/substitutions.generated.js +0 -66
  75. package/examples/existing-browser.mjs +0 -63
  76. package/examples/preflight/classify-direct.mjs +0 -21
  77. package/examples/preflight/classify-kernel.mjs +0 -30
  78. package/examples/preflight/inspect-browser.mjs +0 -44
  79. package/examples/preflight/kernel-native/README.md +0 -112
  80. package/examples/preflight/kernel-native/documented-adapters.json +0 -113
  81. package/examples/preflight/kernel-native/inventory.json +0 -233
  82. package/examples/preflight/kernel-native/qualification.mjs +0 -182
  83. package/examples/preflight/kernel-profile.empty.json +0 -11
  84. package/examples/preflight/mollie-hosted.observations.json +0 -23
  85. package/examples/preflight/mollie-hosted.result.json +0 -103
  86. package/examples/preflight/stripe-script.direct.result.json +0 -92
  87. package/examples/preflight/stripe-script.observations.json +0 -16
  88. package/examples/preflight/stripe-script.result.json +0 -87
@@ -1,556 +0,0 @@
1
- // Generated from @agent-cards/payment-core. Do not edit.
2
- // source-sha256: 47959768c673f160be4b35fd7cd406aebce431e666963f46a2c9c95125906456
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-15.1';
7
- // `url_length` bounds the origin and path that discovery matches. `raw_url_length` bounds the
8
- // observed location including its query, which never takes part in matching or evidence.
9
- export const CHECKOUT_PREFLIGHT_LIMITS = Object.freeze({ frames: 64, signals: 2048, snapshot_bytes: 262144, url_length: 4096, raw_url_length: 65536 });
10
- // Identification-only IDs, checked against the canonical catalog by the core tests.
11
- // No card destination, request method, or request body pattern lives here.
12
- const KNOWN_PSPS = CHECKOUT_PREFLIGHT_CAPABILITIES.processors.map(processor => processor.psp);
13
- const PROCESSOR_BY_ID = new Map(CHECKOUT_PREFLIGHT_CAPABILITIES.processors.map(processor => [processor.psp, processor]));
14
- const KINDS = ['document', 'frame', 'script', 'iframe', 'form'];
15
- const SCENARIOS = ['one_time', 'save_card', 'subscription_initial', 'subscription_renewal'];
16
- const OBSERVATION_REASONS = ['collection_timeout', 'frame_limit', 'signal_limit', 'snapshot_limit', 'frame_unavailable', 'navigation_changed', 'invalid_observation', 'invalid_url', 'card_entry_unrecognized', 'collection_incomplete'];
17
- const RULES = [
18
- { id: 'stripe-js-v3', psp: 'stripe', kinds: ['script', 'frame', 'iframe'], hostname: /^js\.stripe\.com$/, pathname: /^\/v3(?:\/|$)/, origin: 'https://js.stripe.com', path_pattern: '/v3/*' },
19
- { 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' },
20
- { 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' },
21
- { 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' },
22
- { 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' },
23
- { 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/*' },
24
- { id: 'braintree-hosted-fields', psp: 'braintree', kinds: ['frame', 'iframe'], hostname: /^assets\.braintreegateway\.com$/, pathname: /^\/web\//, origin: 'https://assets.braintreegateway.com', path_pattern: '/web/*' },
25
- { 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}/*' },
26
- { 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/*' },
27
- { 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' },
28
- { 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' },
29
- { id: 'vgs-collect-script', psp: 'vgs', kinds: ['script'], hostname: /^js\.verygoodvault\.com$/, pathname: /^\/vgs-collect\//, origin: 'https://js.verygoodvault.com', path_pattern: '/vgs-collect/*' },
30
- { 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: '/*' },
31
- ];
32
- // SDK/page fingerprints identify implemented processor families, not an active payment operation.
33
- 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/[^/]+/[0-9]+\\.[0-9]+\\.[0-9]+/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" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/development-resources/live-endpoints/", "reviewed_on": "2026-09-15" }, { "kind": "partner_observation", "reference": "kernel-discovery-2026-09-14:adyen-secured-fields-4.9.0-live-us", "reviewed_on": "2026-09-15" }], hostname: new RegExp("^checkoutshopper\\-live\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/securedfields/[^/]+/[0-9]+\\.[0-9]+\\.[0-9]+/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/[^/]+/[0-9]+\\.[0-9]+\\.[0-9]+/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" }, { "kind": "primary_source", "reference": "https://docs.adyen.com/development-resources/live-endpoints/", "reviewed_on": "2026-09-15" }], hostname: new RegExp("^checkoutshopper\\-test\\.adyen\\.com$"), pathname: new RegExp("^/checkoutshopper/securedfields/[^/]+/[0-9]+\\.[0-9]+\\.[0-9]+/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": "spreedly-iframe-v1-script", "psp": "spreedly", "kinds": ["script"], "origin": "https://core.spreedly.com", "path_pattern": "^/iframe/iframe-v1\\.min\\.js$", "sources": [{ "kind": "primary_source", "reference": "https://core.spreedly.com/iframe/iframe-v1.min.js", "reviewed_on": "2026-09-16" }], hostname: new RegExp("^core\\.spreedly\\.com$"), pathname: new RegExp("^/iframe/iframe-v1\\.min\\.js$") }, { "id": "spreedly-native-card-frame", "psp": "spreedly", "kinds": ["frame", "iframe", "document"], "origin": "https://core.spreedly.com", "path_pattern": "^/v1/embedded/(?:number|cvv)-frame-1\\.[0-9]{1,4}\\.html$", "sources": [{ "kind": "primary_source", "reference": "https://core.spreedly.com/iframe/iframe-v1.min.js", "reviewed_on": "2026-09-16" }], hostname: new RegExp("^core\\.spreedly\\.com$"), pathname: new RegExp("^/v1/embedded/(?:number|cvv)-frame-1\\.[0-9]{1,4}\\.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$") });
34
- // Hosted, regional and versioned product variants seen on live checkouts (Kernel discovery report,
35
- // 2026-09-14). A variant the implemented adapter does not admit still identifies its processor and
36
- // stays unknown through `variant_unverified`; no entry here expands a recognized card destination.
37
- const documented = (reference) => ({ kind: 'primary_source', reference, reviewed_on: '2026-09-15' });
38
- const observed = (reference) => ({ kind: 'partner_observation', reference: `kernel-discovery-2026-09-14:${reference}`, reviewed_on: '2026-09-15' });
39
- RULES.push({ id: 'tranzila-terminal-hosted-page', psp: 'tranzila', kinds: ['document', 'frame', 'iframe', 'form'], hostname: /^direct\.tranzila\.com$/, pathname: /^\/(?!process(?:\/|$)|done(?:\/|$))[A-Za-z0-9_-]+\/?$/, origin: 'https://direct.tranzila.com', path_pattern: '/:terminal/',
40
- sources: [documented('https://docs.tranzila.com/docs/payments-and-billing/hosted-payment-page'), observed('tranzila-terminal-root-hosted-page')],
41
- variant_unverified: 'The implemented Tranzila hosted form covers direct.tranzila.com/:terminal/iframenew.php; a terminal-root hosted payment page is not admitted.' }, { id: 'square-card-element-frame', psp: 'square', kinds: ['frame', 'iframe'], hostname: /^web\.squarecdn\.com$/, pathname: /^\/[0-9]+\.[0-9]+\.[0-9]+\/single-card-element-iframe\.html$/, origin: 'https://web.squarecdn.com', path_pattern: '/:version/single-card-element-iframe.html',
42
- sources: [documented('https://developer.squareup.com/docs/web-payments/take-card-payment'), observed('square-single-card-element-iframe-1.84.5')] }, { id: 'authorize-net-sim-hosted-form', psp: 'authorize_net', kinds: ['document', 'frame', 'iframe', 'form'], hostname: /^secure\.authorize\.net$/, pathname: /^\/gateway\/transact\.dll$/, origin: 'https://secure.authorize.net', path_pattern: '/gateway/transact.dll',
43
- sources: [documented('https://developer.authorize.net/api/upgrade_guide.html'), observed('authorize-net-hosted-transact-form')],
44
- variant_unverified: 'The implemented Authorize.Net adapter covers Accept.js card requests; the hosted SIM payment form at secure.authorize.net/gateway/transact.dll posts the card as a top-level form and is not admitted.' }, { id: 'worldpay-hosted-payment-page', psp: 'worldpay', kinds: ['document', 'frame', 'iframe', 'form'], hostname: /^secure\.worldpay\.com$/, pathname: /^\/wcc\/(?:purchase|card)$/, origin: 'https://secure.worldpay.com', path_pattern: '/wcc/{purchase,card}',
45
- sources: [documented('https://docs.worldpay.com/access/products/checkout/web'), observed('worldpay-hosted-payment-page-card')],
46
- variant_unverified: 'The implemented Worldpay adapter covers Access Checkout card sessions; Worldpay hosted payment pages under secure.worldpay.com/wcc post the card to Worldpay directly and are not admitted.' }, { id: 'rapyd-hosted-checkout-page', psp: 'rapyd', kinds: ['document', 'frame', 'iframe'], hostname: /^checkout\.rapyd\.net$/, pathname: /^\/$/, origin: 'https://checkout.rapyd.net', path_pattern: '/',
47
- sources: [documented('https://docs.rapyd.net/en/hosted-checkout-page.html'), observed('rapyd-hosted-checkout-page')] }, { id: 'dlocal-smart-fields-parent', psp: 'dlocal', kinds: ['script'], hostname: /^static\.dlocal\.com$/, pathname: /^\/modules\/fields\/[0-9]+\.[0-9]+\.[0-9]+\/(?:parent|iframe)\.js$/, origin: 'https://static.dlocal.com', path_pattern: '/modules/fields/:version/{parent,iframe}.js',
48
- sources: [documented('https://docs.dlocal.com/docs/set-up-smart-fields'), observed('dlocal-smart-fields-6.8.3')] }, { id: 'dlocal-smart-card-fields', psp: 'dlocal', kinds: ['frame', 'iframe', 'document'], hostname: /^static\.dlocal\.com$/, pathname: /^\/modules\/fields\/[0-9]+\.[0-9]+\.[0-9]+\/inner-(?:pan|card)\.html$/, origin: 'https://static.dlocal.com', path_pattern: '/modules/fields/:version/inner-{pan,card}.html',
49
- sources: [documented('https://docs.dlocal.com/docs/set-up-smart-fields'), observed('dlocal-smart-fields-6.8.3')] }, { id: 'mercado-pago-secure-fields-frame', psp: 'mercado_pago', kinds: ['frame', 'iframe', 'document'], hostname: /^secure-fields\.mercadopago\.com$/, pathname: /^\/$/, origin: 'https://secure-fields.mercadopago.com', path_pattern: '/',
50
- sources: [documented('https://sdk.mercadopago.com/js/v2'), observed('mercado-pago-secure-fields-frames')] }, { id: 'mercado-pago-checkout-pro-card-form', psp: 'mercado_pago', kinds: ['document', 'frame', 'iframe'], hostname: /^www\.mercadopago\.com\.ar$/, pathname: /^\/checkout\/v1\/payment\/redirect\/[^/]+\/card-form\/?$/, origin: 'https://www.mercadopago.com.ar', path_pattern: '/checkout/v1/payment/redirect/:preference/card-form/',
51
- sources: [documented('https://www.mercadopago.com.ar/developers/es/docs/checkout-pro/landing'), observed('mercado-pago-checkout-pro-guest-card-form')] });
52
- // Keep sandbox evidence truthful instead of labelling it with a production origin.
53
- for (const [baseId, suffix, hostname, origin] of [
54
- ['square-web-sdk', 'sandbox', /^sandbox\.web\.squarecdn\.com$/, 'https://sandbox.web.squarecdn.com'],
55
- ['paysafe-js', 'test', /^hosted\.test\.paysafe\.com$/, 'https://hosted.test.paysafe.com'],
56
- ['worldpay-checkout-sdk', 'try', /^try\.access\.worldpay\.com$/, 'https://try.access.worldpay.com'],
57
- ['authorize-net-accept', 'test', /^jstest\.authorize\.net$/, 'https://jstest.authorize.net'],
58
- ['tranzila-terminal-hosted-page', 'directng', /^directng\.tranzila\.com$/, 'https://directng.tranzila.com'],
59
- ['square-card-element-frame', 'sandbox', /^sandbox\.web\.squarecdn\.com$/, 'https://sandbox.web.squarecdn.com'],
60
- ['authorize-net-sim-hosted-form', 'secure2', /^secure2\.authorize\.net$/, 'https://secure2.authorize.net'],
61
- ['worldpay-hosted-payment-page', 'test', /^secure-test\.worldpay\.com$/, 'https://secure-test.worldpay.com'],
62
- ['rapyd-hosted-checkout-page', 'sandbox', /^sandboxcheckout\.rapyd\.net$/, 'https://sandboxcheckout.rapyd.net'],
63
- // Adyen's regional live hosts (docs.adyen.com/development-resources/live-endpoints/).
64
- ['adyen-secured-fields-live', 'us', /^checkoutshopper-live-us\.adyen\.com$/, 'https://checkoutshopper-live-us.adyen.com'],
65
- ['adyen-secured-fields-live', 'au', /^checkoutshopper-live-au\.adyen\.com$/, 'https://checkoutshopper-live-au.adyen.com'],
66
- ['adyen-secured-fields-live', 'apse', /^checkoutshopper-live-apse\.adyen\.com$/, 'https://checkoutshopper-live-apse.adyen.com'],
67
- ['adyen-secured-fields-live', 'in', /^checkoutshopper-live-in\.adyen\.com$/, 'https://checkoutshopper-live-in.adyen.com'],
68
- ['adyen-secured-fields-live', 'nea', /^checkoutshopper-live-nea\.adyen\.com$/, 'https://checkoutshopper-live-nea.adyen.com'],
69
- ]) {
70
- RULES.push({ ...RULES.find(rule => rule.id === baseId), id: `${baseId}-${suffix}`, hostname, origin });
71
- }
72
- const SOURCES = {
73
- stripe: [{ kind: 'official_documentation', reference: 'https://docs.stripe.com/js/including', reviewed_on: '2026-09-11' }],
74
- square: [{ kind: 'official_documentation', reference: 'https://developer.squareup.com/docs/web-payments/quickstart/add-sdk-to-web-client', reviewed_on: '2026-09-11' }],
75
- mollie: [{ kind: 'saved_observation', reference: 'mollie-haak-2026-09-11:hosted-credit-card-document-and-v2-script', reviewed_on: '2026-09-11' }],
76
- braintree: [{ kind: 'official_documentation', reference: 'https://developer.paypal.com/braintree/docs/start/hello-client/javascript/v3/', reviewed_on: '2026-09-11' }],
77
- paysafe: [{ kind: 'official_documentation', reference: 'https://developer.paysafe.com/en/api-docs/paysafe-js/overview/', reviewed_on: '2026-09-11' }],
78
- worldpay: [{ kind: 'official_documentation', reference: 'https://developer.worldpay.com/products/checkout/web', reviewed_on: '2026-09-11' }],
79
- authorize_net: [{ kind: 'official_documentation', reference: 'https://developer.authorize.net/api/reference/features/acceptjs.html', reviewed_on: '2026-09-11' }],
80
- razorpay: [{ kind: 'official_documentation', reference: 'https://razorpay.com/docs/payments/payment-gateway/web-integration/standard/integration-steps/', reviewed_on: '2026-09-11' }],
81
- vgs: [{ kind: 'official_documentation', reference: 'https://docs.verygoodsecurity.com/vault/developer-tools/vgs-collect/js/integration', reviewed_on: '2026-09-11' }],
82
- };
83
- const FLOWS = [
84
- { id: 'mollie.hosted_components', psp: 'mollie', operation: 'mollie.card_request', operation_version: 1, mode: 'token', server_constraint: 'eligible', limitations: [
85
- 'The payment request must match the supported Mollie Components card-token format.',
86
- 'Authentication and merchant confirmation must finish in the merchant browser.',
87
- 'Merchant configuration, card eligibility and processor approval still determine whether the purchase succeeds.',
88
- ] },
89
- { id: 'vgs.iframe_bound_tokenization', psp: 'vgs', operation: 'vgs.iframe_bound_tokenization', operation_version: 1, mode: 'token', server_constraint: 'unsupported', limitations: [
90
- 'VGS requires tokenization from its own iframe; the Vault cannot replay this flow from the approval page.',
91
- ] },
92
- ];
93
- const FLOW_BY_ID = new Map(FLOWS.map(flow => [flow.id, flow]));
94
- const RULE_BY_ID = new Map(RULES.map(rule => [rule.id, rule]));
95
- const DEFAULT_PROFILE = {
96
- schema_version: 1, profile_version: 'preflight-2', catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION,
97
- integration: { id: 'direct_sdk', version: 'bundled' },
98
- processor_entries: CHECKOUT_PREFLIGHT_CAPABILITIES.processors.map(processor => ({
99
- psp: processor.psp, mode: processor.mode, scenario: 'one_time', status: 'supported',
100
- })),
101
- entries: [{ flow: 'mollie.hosted_components', operation: 'mollie.card_request', operation_version: 1, mode: 'token', scenario: 'one_time', status: 'supported' }],
102
- };
103
- const clone = (value) => JSON.parse(JSON.stringify(value));
104
- const record = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
105
- const exactKeys = (value, keys) => Object.keys(value).every(key => keys.includes(key));
106
- const id = (value) => typeof value === 'string' && /^[A-Za-z0-9][A-Za-z0-9._+-]{0,119}$/.test(value);
107
- const frameId = (value) => Number.isSafeInteger(value) && value >= 0 && value < CHECKOUT_PREFLIGHT_LIMITS.frames;
108
- const unique = (items) => [...new Set(items)];
109
- function dateTime(value) {
110
- if (typeof value !== 'string' || value.length > 40)
111
- return false;
112
- 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);
113
- if (!match)
114
- return false;
115
- const [year, month, day, hour, minute, second, zoneHour = 0, zoneMinute = 0] = match.slice(1).map(part => part === undefined ? 0 : Number(part));
116
- const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
117
- const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
118
- return month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] && hour <= 23 && minute <= 59 && second <= 59
119
- && zoneHour <= 23 && zoneMinute <= 59 && Number.isFinite(Date.parse(value));
120
- }
121
- function metadata(value) {
122
- return KINDS.includes(value.kind) && frameId(value.frame_id) && (value.parent_frame_id === null || frameId(value.parent_frame_id))
123
- && (value.frame_id !== 0 || value.parent_frame_id === null)
124
- && value.parent_frame_id !== value.frame_id && (value.visible === null || typeof value.visible === 'boolean');
125
- }
126
- function consistentParents(signals) {
127
- const parents = new Map();
128
- for (const signal of signals) {
129
- if (parents.has(signal.frame_id) && parents.get(signal.frame_id) !== signal.parent_frame_id)
130
- return false;
131
- parents.set(signal.frame_id, signal.parent_frame_id);
132
- }
133
- for (const frame of parents.keys()) {
134
- const visited = new Set();
135
- let current = frame;
136
- while (current !== null && current !== undefined) {
137
- if (visited.has(current))
138
- return false;
139
- visited.add(current);
140
- current = parents.get(current);
141
- }
142
- }
143
- return true;
144
- }
145
- function cleanObservation(input) {
146
- if (!record(input) || !exactKeys(input, ['complete', 'truncated', 'reasons']) || typeof input.complete !== 'boolean' || typeof input.truncated !== 'boolean'
147
- || !Array.isArray(input.reasons) || input.reasons.length > 32 || Array.from(input.reasons).some(reason => !OBSERVATION_REASONS.includes(reason))) {
148
- return { complete: false, truncated: false, reasons: ['invalid_observation'] };
149
- }
150
- const reasons = unique(input.reasons);
151
- const complete = input.complete && !input.truncated && reasons.length === 0;
152
- return { complete, truncated: input.truncated, reasons: complete ? [] : unique([...reasons, 'collection_incomplete']) };
153
- }
154
- const byteLength = (value) => new TextEncoder().encode(JSON.stringify(value)).length;
155
- function incomplete(observation, reason, truncated = false) {
156
- observation.complete = false;
157
- observation.truncated ||= truncated;
158
- observation.reasons = unique([...observation.reasons, reason]);
159
- }
160
- /** Normalize observations locally. Unknown assets are omitted; no URL leaves this function. */
161
- export function normalizeCheckoutSignals(input) {
162
- const snapshot = { schema_version: 1, catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION, signals: [], observation: cleanObservation(record(input) ? input.observation : null) };
163
- if (!record(input) || !exactKeys(input, ['signals', 'observation']) || !Array.isArray(input.signals)) {
164
- incomplete(snapshot.observation, 'invalid_observation');
165
- return snapshot;
166
- }
167
- if (input.signals.length > CHECKOUT_PREFLIGHT_LIMITS.signals)
168
- incomplete(snapshot.observation, 'signal_limit', true);
169
- const seen = new Set();
170
- for (const raw of input.signals.slice(0, CHECKOUT_PREFLIGHT_LIMITS.signals)) {
171
- if (!record(raw) || !exactKeys(raw, ['kind', 'url', 'frame_id', 'parent_frame_id', 'visible']) || !metadata(raw)) {
172
- incomplete(snapshot.observation, 'invalid_observation');
173
- continue;
174
- }
175
- if (typeof raw.url !== 'string' || raw.url.length > CHECKOUT_PREFLIGHT_LIMITS.raw_url_length) {
176
- incomplete(snapshot.observation, 'invalid_url');
177
- continue;
178
- }
179
- let url;
180
- try {
181
- url = new URL(raw.url);
182
- }
183
- catch {
184
- incomplete(snapshot.observation, 'invalid_url');
185
- continue;
186
- }
187
- // Matching reads the origin and path only. A long query string on an unrelated wallet or
188
- // widget frame is dropped here rather than invalidating the whole observation.
189
- if (url.origin.length + url.pathname.length > CHECKOUT_PREFLIGHT_LIMITS.url_length) {
190
- incomplete(snapshot.observation, 'invalid_url');
191
- continue;
192
- }
193
- // Non-HTTPS local/blank frames provide no PSP evidence. Credentials and nondefault ports are refused.
194
- if (url.protocol !== 'https:' || url.username || url.password || url.port)
195
- continue;
196
- for (const rule of RULES) {
197
- if (!rule.kinds.includes(raw.kind) || !rule.hostname.test(url.hostname) || !rule.pathname.test(url.pathname))
198
- continue;
199
- const signal = { rule_id: rule.id, kind: raw.kind, frame_id: raw.frame_id, parent_frame_id: raw.parent_frame_id, visible: raw.visible };
200
- const key = JSON.stringify(signal);
201
- if (!seen.has(key)) {
202
- // One observed asset can match more than one reviewed fingerprint.
203
- // Bound normalized evidence independently of the raw observation count.
204
- if (snapshot.signals.length >= CHECKOUT_PREFLIGHT_LIMITS.signals) {
205
- incomplete(snapshot.observation, 'signal_limit', true);
206
- continue;
207
- }
208
- snapshot.signals.push(signal);
209
- seen.add(key);
210
- }
211
- }
212
- }
213
- while (byteLength(snapshot) > CHECKOUT_PREFLIGHT_LIMITS.snapshot_bytes && snapshot.signals.length) {
214
- snapshot.signals.pop();
215
- incomplete(snapshot.observation, 'snapshot_limit', true);
216
- }
217
- if (!consistentParents(snapshot.signals))
218
- incomplete(snapshot.observation, 'invalid_observation');
219
- return snapshot;
220
- }
221
- /** The returned catalog is metadata only. It does not change card destination recognition. */
222
- export function getCheckoutPreflightCatalog() {
223
- return clone({
224
- schema_version: 1, catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION, scope: 'preflight_hint',
225
- integration_version_note: 'bundled describes the capabilities accompanying this helper, not a claim about another installed SDK version.',
226
- limits: CHECKOUT_PREFLIGHT_LIMITS,
227
- known_psps: KNOWN_PSPS.map(psp => ({ psp, detection: RULES.some(rule => rule.psp === psp) ? 'reviewed_rules' : 'unknown' })),
228
- rules: RULES.map(({ hostname, pathname, ...rule }) => ({ ...rule, hostname_pattern: hostname.source, pathname_pattern: pathname.source, sources: rule.sources ?? SOURCES[rule.psp] })),
229
- processors: CHECKOUT_PREFLIGHT_CAPABILITIES.processors, exclusions: CHECKOUT_PREFLIGHT_CAPABILITIES.exclusions,
230
- flows: FLOWS, direct_sdk_profile: DEFAULT_PROFILE,
231
- kernel_profile_template: { schema_version: 1, profile_version: 'kernel-template-1', catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION,
232
- integration: { id: 'kernel_native', version: 'REPLACE-WITH-ADAPTER-VERSION' }, entries: [], processor_entries: [] },
233
- observation_reason_codes: OBSERVATION_REASONS,
234
- });
235
- }
236
- // Registrable-site approximation for provider hosts; a public-suffix list is deliberately not bundled.
237
- function site(hostname) {
238
- const labels = hostname.toLowerCase().split('.').filter(Boolean);
239
- const secondLevel = ['com', 'co', 'net', 'org', 'gov', 'edu', 'ac', 'or', 'ne'];
240
- const count = labels.length > 2 && labels[labels.length - 1].length === 2 && secondLevel.includes(labels[labels.length - 2]) ? 3 : 2;
241
- return labels.slice(-count).join('.');
242
- }
243
- /**
244
- * Whether a visible card-entry frame on `hostname` can belong to a processor already evidenced in the
245
- * snapshot. A collector reports `card_entry_unrecognized` when this is false, so co-loaded SDK scripts
246
- * cannot be presented as the processor behind card controls that no reviewed fingerprint explains, and
247
- * a card form with no processor evidence at all is reported rather than passing as an empty page.
248
- * The hostname stays local to the caller; nothing here enters evidence.
249
- */
250
- export function cardEntryAttributable(input, hostname) {
251
- if (!validSnapshot(input) || typeof hostname !== 'string' || !hostname)
252
- return false;
253
- const evidenced = new Set(input.signals.map(signal => RULE_BY_ID.get(signal.rule_id).psp));
254
- if (!evidenced.size)
255
- return false;
256
- const target = site(hostname);
257
- return RULES.some(rule => {
258
- if (!evidenced.has(rule.psp))
259
- return false;
260
- if (rule.hostname.test(hostname))
261
- return true;
262
- // A templated origin (the VGS tenant frame) is covered by its hostname pattern above.
263
- try {
264
- return site(new URL(rule.origin).hostname) === target;
265
- }
266
- catch {
267
- return false;
268
- }
269
- });
270
- }
271
- function validSnapshot(input) {
272
- return record(input) && exactKeys(input, ['schema_version', 'catalog_version', 'signals', 'observation'])
273
- && input.schema_version === 1 && input.catalog_version === CHECKOUT_PREFLIGHT_CATALOG_VERSION
274
- && Array.isArray(input.signals) && input.signals.length <= CHECKOUT_PREFLIGHT_LIMITS.signals
275
- && Array.from(input.signals).every(signal => record(signal) && exactKeys(signal, ['rule_id', 'kind', 'frame_id', 'parent_frame_id', 'visible']) && metadata(signal)
276
- && id(signal.rule_id) && !!RULE_BY_ID.get(signal.rule_id)?.kinds.includes(signal.kind))
277
- && consistentParents(input.signals)
278
- && record(input.observation) && exactKeys(input.observation, ['complete', 'truncated', 'reasons'])
279
- && typeof input.observation.complete === 'boolean' && typeof input.observation.truncated === 'boolean'
280
- && Array.isArray(input.observation.reasons) && input.observation.reasons.length <= 32
281
- && Array.from(input.observation.reasons).every(reason => OBSERVATION_REASONS.includes(reason))
282
- && byteLength(input) <= CHECKOUT_PREFLIGHT_LIMITS.snapshot_bytes;
283
- }
284
- function validIntegration(value) {
285
- return record(value) && exactKeys(value, ['id', 'version']) && ['direct_sdk', 'kernel_native'].includes(value.id) && (value.version === null || id(value.version));
286
- }
287
- function profileError(profile, integration, now) {
288
- if (!record(profile) || !exactKeys(profile, ['schema_version', 'profile_version', 'catalog_version', 'integration', 'entries', 'processor_entries', 'expires_at'])
289
- || profile.schema_version !== 1 || !id(profile.profile_version) || !validIntegration(profile.integration) || !id(profile.integration.version)
290
- || !Array.isArray(profile.entries) || profile.entries.length > 256
291
- || (profile.processor_entries !== undefined && (!Array.isArray(profile.processor_entries) || profile.processor_entries.length > 256)))
292
- return 'integration_profile_invalid';
293
- if (profile.catalog_version !== CHECKOUT_PREFLIGHT_CATALOG_VERSION)
294
- return 'integration_profile_incompatible';
295
- if (profile.integration.id !== integration.id || profile.integration.version !== integration.version)
296
- return 'integration_profile_mismatch';
297
- if (profile.expires_at !== undefined) {
298
- const expires = dateTime(profile.expires_at) ? Date.parse(profile.expires_at) : NaN;
299
- const time = now === undefined ? Date.now() : dateTime(now) ? Date.parse(now) : NaN;
300
- if (!Number.isFinite(expires) || !Number.isFinite(time))
301
- return 'integration_profile_invalid';
302
- if (expires <= time)
303
- return 'integration_profile_expired';
304
- }
305
- const entries = new Set();
306
- for (const entry of profile.entries) {
307
- if (!record(entry) || !exactKeys(entry, ['flow', 'operation', 'operation_version', 'mode', 'scenario', 'status', 'limitations'])
308
- || !id(entry.flow) || !id(entry.operation) || !SCENARIOS.includes(entry.scenario) || !['supported', 'unsupported'].includes(entry.status)
309
- || (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)))))
310
- return 'integration_profile_invalid';
311
- const flow = FLOW_BY_ID.get(entry.flow);
312
- if (!flow || entry.operation !== flow.operation || entry.operation_version !== flow.operation_version || entry.mode !== flow.mode)
313
- return 'integration_profile_incompatible';
314
- const key = `${entry.flow}:${entry.scenario}`;
315
- if (entries.has(key))
316
- return 'integration_profile_invalid';
317
- entries.add(key);
318
- }
319
- const processors = new Set();
320
- for (const entry of profile.processor_entries ?? []) {
321
- if (!record(entry) || !exactKeys(entry, ['psp', 'mode', 'scenario', 'status', 'limitations'])
322
- || !id(entry.psp) || !SCENARIOS.includes(entry.scenario) || !['supported', 'unsupported'].includes(entry.status)
323
- || (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)))))
324
- return 'integration_profile_invalid';
325
- const processor = PROCESSOR_BY_ID.get(entry.psp);
326
- if (!processor || processor.mode !== entry.mode)
327
- return 'integration_profile_incompatible';
328
- const key = `${entry.psp}:${entry.scenario}`;
329
- if (processors.has(key))
330
- return 'integration_profile_invalid';
331
- processors.add(key);
332
- }
333
- return null;
334
- }
335
- /** Classify a sanitized snapshot. No browser, HTTP, or payment operations occur here. */
336
- export function assessCheckoutSupport(input, options = {}) {
337
- const opts = record(options) ? options : {};
338
- const fallbackIntegrationId = record(opts.integration) && opts.integration.id === 'kernel_native' ? 'kernel_native' : 'direct_sdk';
339
- const integration = validIntegration(opts.integration) ? clone(opts.integration) : {
340
- id: fallbackIntegrationId,
341
- version: opts.integration === undefined ? 'bundled' : null,
342
- };
343
- const result = {
344
- schema_version: 1, catalog_version: CHECKOUT_PREFLIGHT_CATALOG_VERSION, integration,
345
- scenario: opts.scenario !== undefined && SCENARIOS.includes(opts.scenario) ? opts.scenario : 'one_time', scenario_defaulted: opts.scenario === undefined,
346
- psp: null, flow: null, mode: null, status: 'unknown', support_scope: null, checkout_flow_status: 'unknown', candidates: [], reason_codes: [], limitations: [], missing_evidence: [],
347
- observation: { complete: false, truncated: false, reasons: ['invalid_observation'] }, scope: 'preflight_hint', merchant_confirmation_required: true,
348
- };
349
- if (!record(options) || !exactKeys(opts, ['scenario', 'integration', 'profile', 'now']) || (opts.scenario !== undefined && !SCENARIOS.includes(opts.scenario))
350
- || (opts.integration !== undefined && !validIntegration(opts.integration)) || (opts.now !== undefined && !dateTime(opts.now))) {
351
- result.reason_codes = ['invalid_options'];
352
- return result;
353
- }
354
- if (!validSnapshot(input)) {
355
- result.reason_codes = [record(input) && input.catalog_version !== CHECKOUT_PREFLIGHT_CATALOG_VERSION ? 'catalog_incompatible' : 'invalid_snapshot'];
356
- return result;
357
- }
358
- result.observation = cleanObservation(input.observation);
359
- const candidates = new Map();
360
- const activeFlows = new Set();
361
- const activePsps = new Set();
362
- const activeFlowFrames = new Set();
363
- let missingCorroboration = false;
364
- for (const signal of input.signals) {
365
- const rule = RULE_BY_ID.get(signal.rule_id);
366
- const active = signal.visible === true && (['frame', 'iframe', 'form'].includes(signal.kind)
367
- || signal.kind === 'document' && signal.frame_id === 0 && signal.parent_frame_id === null);
368
- const candidate = candidates.get(rule.psp) ?? { psp: rule.psp, relevance: 'undetermined', evidence: [] };
369
- candidate.evidence.push({ ...clone(signal), origin: rule.origin, path_pattern: rule.path_pattern });
370
- if (active) {
371
- candidate.relevance = 'active';
372
- activePsps.add(rule.psp);
373
- if (rule.flow) {
374
- // A hosted route can also display an expired/error page. Require the reviewed
375
- // Components script in that document; a similarly named asset elsewhere is insufficient.
376
- 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);
377
- if (corroborated) {
378
- activeFlows.add(rule.flow);
379
- activeFlowFrames.add(signal.frame_id);
380
- }
381
- else
382
- missingCorroboration = true;
383
- }
384
- }
385
- candidates.set(rule.psp, candidate);
386
- }
387
- result.candidates = [...candidates.values()].sort((a, b) => a.psp.localeCompare(b.psp));
388
- if (missingCorroboration && activeFlows.size === 0)
389
- result.reason_codes.push('flow_corroboration_missing');
390
- if (activePsps.size === 1)
391
- result.psp = [...activePsps][0];
392
- // Script-only evidence names the processor only when the scan saw everything. On a partial scan
393
- // the sole candidate stays listed as undetermined instead of becoming the selected route.
394
- else if (activePsps.size === 0 && candidates.size === 1 && result.observation.complete)
395
- result.psp = [...candidates.keys()][0];
396
- if (!result.observation.complete)
397
- result.reason_codes.push('observation_incomplete');
398
- if (!input.signals.length) {
399
- result.reason_codes.push('psp_not_detected');
400
- result.missing_evidence.push('payment_page_signal');
401
- }
402
- if (activePsps.size > 1 || activeFlows.size > 1 || activeFlowFrames.size > 1 || activePsps.size === 0 && candidates.size > 1)
403
- result.reason_codes.push('ambiguous_checkout');
404
- if (activeFlows.size !== 1 || result.psp === null) {
405
- result.reason_codes.push('checkout_flow_unidentified');
406
- result.missing_evidence.push('active_checkout_flow');
407
- }
408
- else {
409
- const flow = FLOW_BY_ID.get([...activeFlows][0]);
410
- if (flow.psp === result.psp) {
411
- result.flow = flow.id;
412
- result.mode = flow.mode;
413
- result.limitations.push(...flow.limitations);
414
- }
415
- }
416
- if (!result.flow && result.candidates.length)
417
- result.limitations.push('Processor assets alone do not establish the active card payment flow.');
418
- const profile = opts.profile === undefined ? (integration.id === 'direct_sdk' && integration.version === 'bundled' ? DEFAULT_PROFILE : undefined) : opts.profile;
419
- let error = profile === undefined ? 'integration_profile_missing' : profileError(profile, integration, opts.now);
420
- if (integration.version === null)
421
- error = 'integration_version_missing';
422
- if (error) {
423
- result.reason_codes.push(error);
424
- result.missing_evidence.push('compatible_integration_profile');
425
- }
426
- result.reason_codes = unique(result.reason_codes);
427
- const ambiguous = result.reason_codes.includes('ambiguous_checkout');
428
- result.checkout_flow_status = ambiguous ? 'ambiguous' : result.flow ? 'identified' : 'unknown';
429
- // Processor capability and observed checkout compatibility answer different questions.
430
- // Missing flow evidence is advisory when an identified processor has an explicit
431
- // implementation declaration. Incomplete, contradictory or invalid input stays unknown.
432
- if (!result.observation.complete || ambiguous || error || !result.psp || missingCorroboration && !result.flow)
433
- return result;
434
- const flow = result.flow ? FLOW_BY_ID.get(result.flow) : undefined;
435
- if (flow?.server_constraint === 'unsupported') {
436
- result.status = 'unsupported';
437
- result.support_scope = 'checkout_flow';
438
- result.reason_codes.push('vault_flow_unsupported');
439
- return result;
440
- }
441
- // A hidden document cannot lend its scripts to a visible card checkout. Script-only
442
- // observations with no known hidden container can still identify an available adapter.
443
- const eligible = input.signals.some(signal => RULE_BY_ID.get(signal.rule_id).psp === result.psp
444
- && (signal.kind === 'script' ? signal.visible !== false && !input.signals.some(container => container.frame_id === signal.frame_id && ['document', 'frame'].includes(container.kind) && container.visible !== true)
445
- : signal.visible === true));
446
- if (!eligible) {
447
- result.reason_codes.push('payment_signal_inactive');
448
- return result;
449
- }
450
- {
451
- // A native declaration cannot expand the shared Vault's admitted processor variants.
452
- const incompatible = input.signals.map(signal => ({ signal, rule: RULE_BY_ID.get(signal.rule_id) }))
453
- .filter(({ signal, rule }) => rule.psp === result.psp && rule.variant_unverified
454
- && (signal.kind === 'script' ? signal.visible !== false : signal.visible === true));
455
- if (incompatible.length) {
456
- result.reason_codes.push('processor_variant_unverified');
457
- result.limitations.push(...incompatible.map(({ rule }) => rule.variant_unverified));
458
- return result;
459
- }
460
- }
461
- const processor = PROCESSOR_BY_ID.get(result.psp);
462
- const scenario = processor?.scenarios[result.scenario];
463
- if (processor) {
464
- const bundledSdk = integration.id === 'direct_sdk' && integration.version === 'bundled';
465
- if (bundledSdk)
466
- result.limitations.push(...processor.limitations);
467
- for (const variant of processor.unsupported_variants) {
468
- if (bundledSdk || variant.constraint === 'vault')
469
- result.limitations.push(variant.reason);
470
- }
471
- }
472
- if (scenario && (scenario.status === 'unsupported' || scenario.status === 'outside_vault')) {
473
- result.status = 'unsupported';
474
- result.mode = processor.mode;
475
- result.support_scope = 'processor_integration';
476
- result.reason_codes.push(scenario.reason);
477
- return result;
478
- }
479
- const profileValue = profile;
480
- const entry = flow && profileValue.entries.find(entry => entry.flow === flow.id && entry.scenario === result.scenario);
481
- if (entry) {
482
- result.status = entry.status;
483
- result.support_scope = 'checkout_flow';
484
- result.reason_codes.push(entry.status === 'supported' ? 'flow_supported_by_integration' : 'integration_flow_unsupported');
485
- result.limitations.push(...(entry.limitations ?? []));
486
- return result;
487
- }
488
- if (!processor)
489
- return result;
490
- result.mode = processor.mode;
491
- const processorEntry = profileValue.processor_entries?.find(entry => entry.psp === processor.psp && entry.scenario === result.scenario);
492
- if (!processorEntry) {
493
- result.reason_codes.push(flow ? 'integration_flow_undeclared' : 'integration_processor_undeclared');
494
- result.missing_evidence.push(flow ? 'integration_flow_capability' : 'integration_processor_capability');
495
- return result;
496
- }
497
- result.status = processorEntry.status;
498
- result.support_scope = 'processor_integration';
499
- result.reason_codes.push(processorEntry.status === 'supported' ? 'processor_supported_by_integration' : 'integration_processor_unsupported');
500
- result.limitations.push(...(processorEntry.limitations ?? []));
501
- result.limitations = unique(result.limitations);
502
- return result;
503
- }
504
- /** Machine-readable transport shapes; semantic compatibility is checked by the classifier. */
505
- export function getCheckoutPreflightSchemas() {
506
- const text = { type: 'string', minLength: 1, maxLength: 120, pattern: '^[A-Za-z0-9][A-Za-z0-9._+-]{0,119}$' };
507
- const integration = { type: 'object', additionalProperties: false, required: ['id', 'version'], properties: { id: { enum: ['direct_sdk', 'kernel_native'] }, version: { anyOf: [text, { type: 'null' }] } } };
508
- 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 } } } };
509
- const signal = { type: 'object', additionalProperties: false, required: ['rule_id', 'kind', 'frame_id', 'parent_frame_id', 'visible'], properties: {
510
- rule_id: { enum: RULES.map(rule => rule.id) }, kind: { enum: KINDS }, frame_id: { type: 'integer', minimum: 0, maximum: 63 },
511
- parent_frame_id: { anyOf: [{ type: 'integer', minimum: 0, maximum: 63 }, { type: 'null' }] }, visible: { type: ['boolean', 'null'] },
512
- } };
513
- const profile = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
514
- required: ['schema_version', 'profile_version', 'catalog_version', 'integration', 'entries'], properties: {
515
- schema_version: { const: 1 }, profile_version: text, catalog_version: { const: CHECKOUT_PREFLIGHT_CATALOG_VERSION }, integration,
516
- processor_entries: { type: 'array', maxItems: 256, items: {
517
- type: 'object', additionalProperties: false, required: ['psp', 'mode', 'scenario', 'status'], properties: {
518
- psp: { enum: KNOWN_PSPS }, mode: { enum: ['token', 'cse', 'hosted_form'] }, scenario: { enum: SCENARIOS }, status: { enum: ['supported', 'unsupported'] },
519
- limitations: { type: 'array', maxItems: 16, items: { type: 'string', maxLength: 256, pattern: '^[^\\u0000-\\u001f]*$' } },
520
- },
521
- } },
522
- expires_at: { type: 'string', format: 'date-time', maxLength: 40 }, entries: { type: 'array', maxItems: 256, items: {
523
- type: 'object', additionalProperties: false, required: ['flow', 'operation', 'operation_version', 'mode', 'scenario', 'status'], properties: {
524
- flow: { enum: FLOWS.map(flow => flow.id) }, operation: { enum: FLOWS.map(flow => flow.operation) }, operation_version: { const: 1 },
525
- mode: { enum: ['token', 'cse', 'hosted_form'] }, scenario: { enum: SCENARIOS }, status: { enum: ['supported', 'unsupported'] },
526
- limitations: { type: 'array', maxItems: 16, items: { type: 'string', maxLength: 256, pattern: '^[^\\u0000-\\u001f]*$' } },
527
- },
528
- } },
529
- } };
530
- const snapshot = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
531
- required: ['schema_version', 'catalog_version', 'signals', 'observation'], properties: {
532
- schema_version: { const: 1 }, catalog_version: { const: CHECKOUT_PREFLIGHT_CATALOG_VERSION },
533
- signals: { type: 'array', maxItems: CHECKOUT_PREFLIGHT_LIMITS.signals, items: signal }, observation,
534
- } };
535
- const evidence = { ...signal, required: [...signal.required, 'origin', 'path_pattern'], properties: { ...signal.properties, origin: { type: 'string', maxLength: 256 }, path_pattern: { type: 'string', maxLength: 256 } } };
536
- const result = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
537
- 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: {
538
- schema_version: { const: 1 }, catalog_version: { const: CHECKOUT_PREFLIGHT_CATALOG_VERSION }, integration,
539
- scenario: { enum: SCENARIOS }, scenario_defaulted: { type: 'boolean' }, psp: { type: ['string', 'null'] }, flow: { type: ['string', 'null'] }, mode: { enum: ['token', 'cse', 'hosted_form', null] },
540
- support_scope: { enum: ['processor_integration', 'checkout_flow', null] }, checkout_flow_status: { enum: ['identified', 'unknown', 'ambiguous'] },
541
- status: { enum: ['supported', 'unsupported', 'unknown'] }, candidates: { type: 'array', items: { type: 'object', additionalProperties: false, required: ['psp', 'relevance', 'evidence'], properties: {
542
- psp: { type: 'string' }, relevance: { enum: ['active', 'undetermined'] }, evidence: { type: 'array', items: evidence },
543
- } } }, reason_codes: { type: 'array', items: { type: 'string' } }, limitations: { type: 'array', items: { type: 'string' } }, missing_evidence: { type: 'array', items: { type: 'string' } }, observation,
544
- scope: { const: 'preflight_hint' }, merchant_confirmation_required: { const: true },
545
- } };
546
- const rawSignalProperties = { ...signal.properties, url: { type: 'string', maxLength: CHECKOUT_PREFLIGHT_LIMITS.raw_url_length } };
547
- delete rawSignalProperties.rule_id;
548
- const observations = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false,
549
- required: ['signals', 'observation'], properties: { signals: { type: 'array', maxItems: CHECKOUT_PREFLIGHT_LIMITS.signals, items: {
550
- type: 'object', additionalProperties: false, required: ['url', 'kind', 'frame_id', 'parent_frame_id', 'visible'], properties: rawSignalProperties,
551
- } }, observation } };
552
- const options = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', additionalProperties: false, properties: {
553
- scenario: { enum: SCENARIOS }, integration, profile, now: { type: 'string', format: 'date-time', maxLength: 40 },
554
- } };
555
- return clone({ observations, options, snapshot, profile, result });
556
- }