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