@agent-cards/sdk 0.23.19 → 0.23.21

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 (66) hide show
  1. package/CHANGELOG.md +61 -2
  2. package/PREFLIGHT.md +4 -0
  3. package/README.md +175 -7
  4. package/dist/amadeus.d.ts +4 -2
  5. package/dist/amadeus.js +16 -3
  6. package/dist/buy.d.ts +84 -2
  7. package/dist/buy.js +16 -1
  8. package/dist/card-endpoint-facts.d.ts +2 -1
  9. package/dist/card-endpoint-facts.js +18 -9
  10. package/dist/card-endpoint.d.ts +20 -4
  11. package/dist/card-endpoint.js +38 -4
  12. package/dist/card-fields.generated.js +1444 -51
  13. package/dist/cdp.d.ts +29 -0
  14. package/dist/cdp.js +444 -24
  15. package/dist/client.d.ts +134 -7
  16. package/dist/client.js +350 -25
  17. package/dist/comgate.d.ts +50 -0
  18. package/dist/comgate.js +80 -0
  19. package/dist/cybersource-secure-acceptance.generated.d.ts +1 -1
  20. package/dist/eprotect.generated.d.ts +1 -1
  21. package/dist/gmo.generated.js +7 -3
  22. package/dist/hipay.generated.d.ts +56 -0
  23. package/dist/hipay.generated.js +392 -0
  24. package/dist/hold.d.ts +180 -0
  25. package/dist/hold.js +270 -0
  26. package/dist/hosted-entry.d.ts +4 -0
  27. package/dist/hosted-entry.js +32 -0
  28. package/dist/index.d.ts +4 -1
  29. package/dist/index.js +1 -0
  30. package/dist/lifecycle.d.ts +10 -0
  31. package/dist/lifecycle.js +21 -0
  32. package/dist/merchant-card-endpoints.generated.js +102 -11
  33. package/dist/paddle-tokenex.generated.js +7 -3
  34. package/dist/paddle-vgs.generated.d.ts +3 -2
  35. package/dist/paddle-vgs.generated.js +9 -5
  36. package/dist/payrails.generated.js +7 -3
  37. package/dist/pre-claim.d.ts +20 -0
  38. package/dist/pre-claim.js +202 -22
  39. package/dist/preflight-catalog.json +58 -0
  40. package/dist/preflight-schemas.json +4 -0
  41. package/dist/preflight.generated.js +26 -2
  42. package/dist/prepared-processor.d.ts +6 -2
  43. package/dist/prepared-processor.js +18 -2
  44. package/dist/primer.generated.js +1487 -94
  45. package/dist/przelewy24.d.ts +47 -0
  46. package/dist/przelewy24.js +88 -0
  47. package/dist/quickpay.d.ts +44 -0
  48. package/dist/quickpay.js +65 -0
  49. package/dist/registry.d.ts +6 -5
  50. package/dist/registry.js +27 -7
  51. package/dist/shiji-sts.generated.js +7 -3
  52. package/dist/stripe-checkout.generated.js +744 -13
  53. package/dist/tokenex-iframe.d.ts +93 -0
  54. package/dist/tokenex-iframe.generated.d.ts +81 -0
  55. package/dist/tokenex-iframe.generated.js +403 -0
  56. package/dist/tokenex-iframe.js +195 -0
  57. package/dist/transbank.d.ts +45 -0
  58. package/dist/transbank.js +73 -0
  59. package/dist/twoc2p.d.ts +54 -0
  60. package/dist/twoc2p.generated.d.ts +33 -0
  61. package/dist/twoc2p.generated.js +1149 -0
  62. package/dist/twoc2p.js +85 -0
  63. package/dist/voice.d.ts +16 -13
  64. package/dist/voice.js +13 -10
  65. package/examples/preflight/kernel-native/inventory.json +1 -1
  66. package/package.json +3 -3
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Przelewy24's pay wall (secure.przelewy24.pl, where most Polish shops send a buyer who pays by card), as this SDK
3
+ * reads it.
4
+ *
5
+ * The merchant's server registers the payment with Przelewy24 and sends the buyer's browser to the pay wall link
6
+ * Przelewy24 answered with, https://secure.przelewy24.pl/trnRequest/<token>, by a redirect, by setting the page's
7
+ * location, or in a window the page opens. That GET carries no card, no amount and no merchant, and it is the one
8
+ * request a build that declares Przelewy24's capability pauses (hosted-entry.ts): the cardholder's device repeats it
9
+ * over the end-to-end TLS relay, picks the pay wall's card method and fills the card form Przelewy24 returns to it
10
+ * (payment-core processors/przelewy24.js). Everything else the agent's browser sends the pay wall to pay follows
11
+ * that entry and leads to a card: the card method's post (/trnRequest/<token>/241), the card form's post
12
+ * (/card/p24form/<token>) and the Saferpay resolver the card form asks for its post's URL
13
+ * (/saferpay/cardPaymentEndpointResolver/<token>/<card type>). This SDK aborts every one of them, so a placeholder
14
+ * card never reaches Przelewy24.
15
+ *
16
+ * PRZELEWY24_HOSTS is payment-core's PRZELEWY24_HOSTS, and isPrzelewy24EntryUrl is payment-core's
17
+ * isPrzelewy24EntryUrl; przelewy24.test.mjs pins both to payment-core on every case payment-core's own tests list.
18
+ */
19
+ export declare const PRZELEWY24_PSP = "przelewy24";
20
+ /** The dark-launch capability the API serves Przelewy24's recognizer behind (payment-core definitions.js). */
21
+ export declare const PRZELEWY24_CAPABILITY = "przelewy24_hosted_payment_page";
22
+ /** The pay wall's two hosts: live, and Przelewy24's sandbox, which runs the same pay wall for a test account. */
23
+ export declare const PRZELEWY24_HOSTS: readonly string[];
24
+ /**
25
+ * Whether a URL is the pay wall link exactly as the merchant's redirect names it: https, one of the two pay wall
26
+ * hosts in lowercase, the default port, no credentials, /trnRequest/ and one token, and no query, fragment, trailing
27
+ * segment or other spelling. The card method's link, the card post and every other pay wall page share the host,
28
+ * and none of them is the entry.
29
+ */
30
+ export declare function isPrzelewy24EntryUrl(raw: unknown): boolean;
31
+ /**
32
+ * Whether a request on the pay wall's hosts is a step toward paying there: any POST (the card method's post, the
33
+ * card form's post, and any other form the pay wall posts), and the GET of the Saferpay resolver, which names the
34
+ * typed card's type and answers with the URL the card form posts the card to. The pay wall's own pages, scripts and
35
+ * images are GETs of no card and are not one.
36
+ */
37
+ export declare function isPrzelewy24PayStep(url: string, method: string): boolean;
38
+ /**
39
+ * Whether an adapter must hand this request to the pre-claim gates: it is on a pay wall host and this build's registry
40
+ * serves Przelewy24's entry there. The card method's post and the other pay steps are not the entry, so the registry's
41
+ * card-request test does not name them; the CDP adapter still pauses them through the recognizer's host pattern, and
42
+ * attachToPlaywright's route predicate asks this, so both adapters show the gates every request to the pay wall once
43
+ * Przelewy24 is armed.
44
+ */
45
+ export declare function isArmedPrzelewy24Url(vault: {
46
+ isCardRequest(url: string, method?: string): boolean;
47
+ }, url: string): boolean;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Przelewy24's pay wall (secure.przelewy24.pl, where most Polish shops send a buyer who pays by card), as this SDK
3
+ * reads it.
4
+ *
5
+ * The merchant's server registers the payment with Przelewy24 and sends the buyer's browser to the pay wall link
6
+ * Przelewy24 answered with, https://secure.przelewy24.pl/trnRequest/<token>, by a redirect, by setting the page's
7
+ * location, or in a window the page opens. That GET carries no card, no amount and no merchant, and it is the one
8
+ * request a build that declares Przelewy24's capability pauses (hosted-entry.ts): the cardholder's device repeats it
9
+ * over the end-to-end TLS relay, picks the pay wall's card method and fills the card form Przelewy24 returns to it
10
+ * (payment-core processors/przelewy24.js). Everything else the agent's browser sends the pay wall to pay follows
11
+ * that entry and leads to a card: the card method's post (/trnRequest/<token>/241), the card form's post
12
+ * (/card/p24form/<token>) and the Saferpay resolver the card form asks for its post's URL
13
+ * (/saferpay/cardPaymentEndpointResolver/<token>/<card type>). This SDK aborts every one of them, so a placeholder
14
+ * card never reaches Przelewy24.
15
+ *
16
+ * PRZELEWY24_HOSTS is payment-core's PRZELEWY24_HOSTS, and isPrzelewy24EntryUrl is payment-core's
17
+ * isPrzelewy24EntryUrl; przelewy24.test.mjs pins both to payment-core on every case payment-core's own tests list.
18
+ */
19
+ export const PRZELEWY24_PSP = 'przelewy24';
20
+ /** The dark-launch capability the API serves Przelewy24's recognizer behind (payment-core definitions.js). */
21
+ export const PRZELEWY24_CAPABILITY = 'przelewy24_hosted_payment_page';
22
+ /** The pay wall's two hosts: live, and Przelewy24's sandbox, which runs the same pay wall for a test account. */
23
+ export const PRZELEWY24_HOSTS = Object.freeze(['secure.przelewy24.pl', 'sandbox.przelewy24.pl']);
24
+ const ENTRY_PATH = '/trnRequest/';
25
+ // The token transaction/register returns: four groups of uppercase hexadecimal, 10, 6, 6 and 10 long.
26
+ const TOKEN = /^[0-9A-F]{10}-[0-9A-F]{6}-[0-9A-F]{6}-[0-9A-F]{10}$/;
27
+ // A token of that shape, for asking whether this build's registry serves the entry on a host.
28
+ const PROBE_TOKEN = '0000000000-000000-000000-0000000000';
29
+ /**
30
+ * Whether a URL is the pay wall link exactly as the merchant's redirect names it: https, one of the two pay wall
31
+ * hosts in lowercase, the default port, no credentials, /trnRequest/ and one token, and no query, fragment, trailing
32
+ * segment or other spelling. The card method's link, the card post and every other pay wall page share the host,
33
+ * and none of them is the entry.
34
+ */
35
+ export function isPrzelewy24EntryUrl(raw) {
36
+ if (typeof raw !== 'string')
37
+ return false;
38
+ let url;
39
+ try {
40
+ url = new URL(raw);
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ if (url.protocol !== 'https:' || !PRZELEWY24_HOSTS.includes(url.hostname) || url.port || url.username || url.password
46
+ || url.href !== raw || /[?#]/.test(raw) || !url.pathname.startsWith(ENTRY_PATH))
47
+ return false;
48
+ return TOKEN.test(url.pathname.slice(ENTRY_PATH.length));
49
+ }
50
+ /** The pay wall host a URL is on (https, no credentials, any port, any letter case, a trailing dot or not), or null. */
51
+ function przelewy24Host(raw) {
52
+ let url;
53
+ try {
54
+ url = new URL(raw);
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ if (url.protocol !== 'https:' || url.username || url.password)
60
+ return null;
61
+ const host = url.hostname.toLowerCase().replace(/\.$/, '');
62
+ return PRZELEWY24_HOSTS.includes(host) ? host : null;
63
+ }
64
+ /**
65
+ * Whether a request on the pay wall's hosts is a step toward paying there: any POST (the card method's post, the
66
+ * card form's post, and any other form the pay wall posts), and the GET of the Saferpay resolver, which names the
67
+ * typed card's type and answers with the URL the card form posts the card to. The pay wall's own pages, scripts and
68
+ * images are GETs of no card and are not one.
69
+ */
70
+ export function isPrzelewy24PayStep(url, method) {
71
+ if (przelewy24Host(url) === null)
72
+ return false;
73
+ const verb = String(method).toUpperCase();
74
+ if (verb === 'POST')
75
+ return true;
76
+ return verb === 'GET' && /^\/saferpay\//i.test(new URL(url).pathname);
77
+ }
78
+ /**
79
+ * Whether an adapter must hand this request to the pre-claim gates: it is on a pay wall host and this build's registry
80
+ * serves Przelewy24's entry there. The card method's post and the other pay steps are not the entry, so the registry's
81
+ * card-request test does not name them; the CDP adapter still pauses them through the recognizer's host pattern, and
82
+ * attachToPlaywright's route predicate asks this, so both adapters show the gates every request to the pay wall once
83
+ * Przelewy24 is armed.
84
+ */
85
+ export function isArmedPrzelewy24Url(vault, url) {
86
+ const host = przelewy24Host(url);
87
+ return host !== null && vault.isCardRequest(`https://${host}${ENTRY_PATH}${PROBE_TOKEN}`, 'GET');
88
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * QuickPay's hosted payment window (where most Danish and Nordic webshops send the buyer), as this SDK reads it.
3
+ *
4
+ * The merchant's page posts a signed entry form, top-level, to https://payment.quickpay.net/ (QuickPay's Form
5
+ * API v10), and QuickPay answers with a redirect to its own window under a session of its own (/<32 hex>). That
6
+ * entry carries no card, and it is the one request this SDK pauses: the cardholder's device repeats it over the
7
+ * end-to-end TLS relay and fills the card into the window QuickPay returns to it (payment-core
8
+ * processors/quickpay.js). Everything else the agent's browser posts to QuickPay carries a card the agent typed
9
+ * or follows one: the window's card post (/process_card), its fee lookup (/calculate_fee, which carries the card
10
+ * number), its wallet token post (/process_payment_token) and its 3-D Secure step (/<session>/3ds_auth). The
11
+ * window also looks up the card's first eight digits with a GET (/payment-methods?bin=...). This SDK aborts every
12
+ * one of them, so a placeholder card never reaches QuickPay.
13
+ *
14
+ * The host is payment-core's QUICKPAY_HOSTS; quickpay.test.mjs pins the two lists together. QuickPay has no test
15
+ * host: a test payment runs on the same host with QuickPay's own test cards.
16
+ */
17
+ export declare const QUICKPAY_PSP = "quickpay";
18
+ export declare const QUICKPAY_HOSTS: readonly string[];
19
+ /** Whether this URL is on QuickPay's window host (https, no credentials, any port, a trailing dot or not). */
20
+ export declare function isQuickpayHost(url: string): boolean;
21
+ /**
22
+ * The only request on QuickPay's host that is the merchant's entry: a POST to the host's root, written exactly as
23
+ * a form action writes it, with no port, query or fragment (payment-core isQuickpayEntryUrl, which takes that one
24
+ * string only). The entry the SDK pauses; every other POST there is aborted.
25
+ */
26
+ export declare function isQuickpayEntry(url: string, method: string): boolean;
27
+ /**
28
+ * The window's card lookup: a GET on QuickPay's host to /payment-methods, which names the first eight digits of
29
+ * the card typed so far in its `bin` query. Any other GET there (the window itself, its scripts and images) is
30
+ * not a card request.
31
+ */
32
+ export declare function isQuickpayCardLookup(url: string, method: string): boolean;
33
+ /** The entry URL the registry recognizes when this build is armed for QuickPay, for any URL on QuickPay's host. */
34
+ export declare function quickpayEntryUrl(url: string): string | null;
35
+ /**
36
+ * Whether an adapter must hand this request to the pre-claim gates: it is on QuickPay's host and this build's
37
+ * registry serves QuickPay's entry. The window's card post and the other card requests are not the entry, so the
38
+ * registry's card-request test does not name them; the CDP adapter still pauses them through the recognizer's
39
+ * host pattern, and attachToPlaywright's route predicate asks this, so both adapters show the gates every
40
+ * request to QuickPay's host once QuickPay is armed.
41
+ */
42
+ export declare function isArmedQuickpayUrl(vault: {
43
+ isCardRequest(url: string, method?: string): boolean;
44
+ }, url: string): boolean;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * QuickPay's hosted payment window (where most Danish and Nordic webshops send the buyer), as this SDK reads it.
3
+ *
4
+ * The merchant's page posts a signed entry form, top-level, to https://payment.quickpay.net/ (QuickPay's Form
5
+ * API v10), and QuickPay answers with a redirect to its own window under a session of its own (/<32 hex>). That
6
+ * entry carries no card, and it is the one request this SDK pauses: the cardholder's device repeats it over the
7
+ * end-to-end TLS relay and fills the card into the window QuickPay returns to it (payment-core
8
+ * processors/quickpay.js). Everything else the agent's browser posts to QuickPay carries a card the agent typed
9
+ * or follows one: the window's card post (/process_card), its fee lookup (/calculate_fee, which carries the card
10
+ * number), its wallet token post (/process_payment_token) and its 3-D Secure step (/<session>/3ds_auth). The
11
+ * window also looks up the card's first eight digits with a GET (/payment-methods?bin=...). This SDK aborts every
12
+ * one of them, so a placeholder card never reaches QuickPay.
13
+ *
14
+ * The host is payment-core's QUICKPAY_HOSTS; quickpay.test.mjs pins the two lists together. QuickPay has no test
15
+ * host: a test payment runs on the same host with QuickPay's own test cards.
16
+ */
17
+ export const QUICKPAY_PSP = 'quickpay';
18
+ export const QUICKPAY_HOSTS = Object.freeze(['payment.quickpay.net']);
19
+ const QUICKPAY_ENTRY_URL = 'https://payment.quickpay.net/';
20
+ /** Whether this URL is on QuickPay's window host (https, no credentials, any port, a trailing dot or not). */
21
+ export function isQuickpayHost(url) {
22
+ let parsed;
23
+ try {
24
+ parsed = new URL(url);
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ return parsed.protocol === 'https:' && !parsed.username && !parsed.password
30
+ && QUICKPAY_HOSTS.includes(parsed.hostname.toLowerCase().replace(/\.$/, ''));
31
+ }
32
+ /**
33
+ * The only request on QuickPay's host that is the merchant's entry: a POST to the host's root, written exactly as
34
+ * a form action writes it, with no port, query or fragment (payment-core isQuickpayEntryUrl, which takes that one
35
+ * string only). The entry the SDK pauses; every other POST there is aborted.
36
+ */
37
+ export function isQuickpayEntry(url, method) {
38
+ return String(method).toUpperCase() === 'POST' && url === QUICKPAY_ENTRY_URL;
39
+ }
40
+ /**
41
+ * The window's card lookup: a GET on QuickPay's host to /payment-methods, which names the first eight digits of
42
+ * the card typed so far in its `bin` query. Any other GET there (the window itself, its scripts and images) is
43
+ * not a card request.
44
+ */
45
+ export function isQuickpayCardLookup(url, method) {
46
+ if (String(method).toUpperCase() !== 'GET' || !isQuickpayHost(url))
47
+ return false;
48
+ const parsed = new URL(url);
49
+ return /(?:^|\/)payment-methods\/?$/i.test(parsed.pathname) || parsed.searchParams.has('bin');
50
+ }
51
+ /** The entry URL the registry recognizes when this build is armed for QuickPay, for any URL on QuickPay's host. */
52
+ export function quickpayEntryUrl(url) {
53
+ return isQuickpayHost(url) ? QUICKPAY_ENTRY_URL : null;
54
+ }
55
+ /**
56
+ * Whether an adapter must hand this request to the pre-claim gates: it is on QuickPay's host and this build's
57
+ * registry serves QuickPay's entry. The window's card post and the other card requests are not the entry, so the
58
+ * registry's card-request test does not name them; the CDP adapter still pauses them through the recognizer's
59
+ * host pattern, and attachToPlaywright's route predicate asks this, so both adapters show the gates every
60
+ * request to QuickPay's host once QuickPay is armed.
61
+ */
62
+ export function isArmedQuickpayUrl(vault, url) {
63
+ const entry = quickpayEntryUrl(url);
64
+ return entry !== null && vault.isCardRequest(entry, 'POST');
65
+ }
@@ -225,11 +225,12 @@ export declare function recognizerRequestMethod(rec: Pick<Recognizer, 'request'>
225
225
  /**
226
226
  * Whether `method` is this recognizer's card request method for `url`. A PUT
227
227
  * recognizer (Gravy) carries the card in its body as a POST one does, so its PUT
228
- * pauses like a POST, and neither pauses in the other's method. A GET carries
229
- * the card in its URL, so a GET recognizer is a card request only for a
230
- * processor whose exact query this build checks (Worldpay eProtect, through
231
- * payment-core's grammar); any other GET recognizer is nothing this build can
232
- * complete and is never paused.
228
+ * pauses like a POST, and neither pauses in the other's method. A GET is a card
229
+ * request only for a processor whose exact URL this build checks: Worldpay
230
+ * eProtect's registration, whose query carries the card (payment-core's
231
+ * grammar), and a hosted page entered with a plain GET, whose link carries no
232
+ * card and which the cardholder's device takes over (hosted-entry.ts). Any other
233
+ * GET recognizer is nothing this build can complete and is never paused.
233
234
  */
234
235
  export declare function isRecognizerRequest(rec: Recognizer, url: string, method: string): boolean;
235
236
  /**
package/dist/registry.js CHANGED
@@ -12,6 +12,8 @@ import { isEprotectTokenRequest } from './eprotect.generated.js';
12
12
  import { EPROTECT_PSP } from './eprotect.js';
13
13
  import { isSecureAcceptanceTokenRequest } from './cybersource-secure-acceptance.generated.js';
14
14
  import { SECURE_ACCEPTANCE_PSP } from './cybersource-secure-acceptance.js';
15
+ import { hasHostedGetEntry, isHostedGetEntry } from './hosted-entry.js';
16
+ import { TOKENEX_IFRAME_PSP, isTokenexIframeUrl } from './tokenex-iframe.generated.js';
15
17
  export { BUILTIN_REGISTRY };
16
18
  /** True for a plain-http loopback address (`127.0.0.1` or `localhost`, any port); the only http a sandbox recogniser admits. */
17
19
  export function isLoopbackUrl(parsed) {
@@ -123,6 +125,15 @@ export function findRecognizer(url, registry = BUILTIN_REGISTRY, opts = {}) {
123
125
  // doubled slash. Any other spelling stays the stop's (pre-claim.ts).
124
126
  if (r.psp === SECURE_ACCEPTANCE_PSP)
125
127
  return isSecureAcceptanceTokenRequest(url, 'POST') === true;
128
+ // A hosted page entered with a plain GET (hosted-entry.ts, ComGate's gateway link) is recognized as the
129
+ // server recognizes it, by its exact link, query included: the match reads only the host and the path.
130
+ if (hasHostedGetEntry(r.psp))
131
+ return isHostedGetEntry(r.psp, url);
132
+ // The TokenEx iframe's card post goes to the frame's own document URL, query included, and the server
133
+ // recognizes only that exact URL with the PCI card frame's query (payment-core tokenexIframeTarget): the match
134
+ // reads only the host and the path. Any other query on that path is the TokenEx gate's (pre-claim.ts).
135
+ if (r.psp === TOKENEX_IFRAME_PSP)
136
+ return isTokenexIframeUrl(url);
126
137
  return true;
127
138
  }) ?? null);
128
139
  }
@@ -140,17 +151,19 @@ export function recognizerRequestMethod(rec) {
140
151
  /**
141
152
  * Whether `method` is this recognizer's card request method for `url`. A PUT
142
153
  * recognizer (Gravy) carries the card in its body as a POST one does, so its PUT
143
- * pauses like a POST, and neither pauses in the other's method. A GET carries
144
- * the card in its URL, so a GET recognizer is a card request only for a
145
- * processor whose exact query this build checks (Worldpay eProtect, through
146
- * payment-core's grammar); any other GET recognizer is nothing this build can
147
- * complete and is never paused.
154
+ * pauses like a POST, and neither pauses in the other's method. A GET is a card
155
+ * request only for a processor whose exact URL this build checks: Worldpay
156
+ * eProtect's registration, whose query carries the card (payment-core's
157
+ * grammar), and a hosted page entered with a plain GET, whose link carries no
158
+ * card and which the cardholder's device takes over (hosted-entry.ts). Any other
159
+ * GET recognizer is nothing this build can complete and is never paused.
148
160
  */
149
161
  export function isRecognizerRequest(rec, url, method) {
150
162
  const expected = recognizerRequestMethod(rec);
151
163
  if (typeof method !== 'string' || method.toUpperCase() !== expected)
152
164
  return false;
153
- return expected !== 'GET' || (rec.psp === EPROTECT_PSP && isEprotectTokenRequest(url, 'GET'));
165
+ return expected !== 'GET' || (rec.psp === EPROTECT_PSP && isEprotectTokenRequest(url, 'GET'))
166
+ || (rec.mode === 'hosted_form' && isHostedGetEntry(rec.psp, url));
154
167
  }
155
168
  /**
156
169
  * True when this processor cannot be taken over on an ordinary authorization:
@@ -223,7 +236,14 @@ function cardHostPatterns(rec) {
223
236
  // normalization resolveRecognizerForUrl does with url.hostname. Do not
224
237
  // "fix" this by wildcarding the letters: `*???.??????.???*` matches most of
225
238
  // the web and would pause every request on the page.
226
- return rec.hosts.filter((h) => typeof h === 'string').flatMap((h) => regexSourceToGlobs(h)).map((g) => wrap(g).toLowerCase());
239
+ //
240
+ // PayPal is armed by path, not host: www.paypal.com serves PayPal's whole site and its buttons' own
241
+ // traffic, so arming the host would pause and re-check every PayPal request on every page for nothing.
242
+ // Its frames send the confirm under one lower-case prefix, the spelling payment-core's
243
+ // paypalConfirmOrderId takes; the checkout guard (paypal-card-forms.ts) arms the same confirm for
244
+ // every company.
245
+ const path = rec?.psp === 'paypal' ? '/v2/checkout/orders/' : '';
246
+ return rec.hosts.filter((h) => typeof h === 'string').flatMap((h) => regexSourceToGlobs(h)).map((g) => wrap(`${g}${path}`).toLowerCase());
227
247
  }
228
248
  // No hosts[] — a registry pinned before the field existed, or hand-built.
229
249
  // Fall back to widening `match`, which is the predicate isCardRequest
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 98a535f4ba13e1ee4744fb725ae47c91fd9ca650dcb37fcd9eadd92b85bf6ce1
3
+ // artifact-sha256: 9e15c873e3e3002651f0d5bcde91507c344bf33bfacec748aabfd56c6e7529f1
4
4
  // src/sha256.js
5
5
  var K = /* @__PURE__ */ new Uint32Array([
6
6
  1116352408,
@@ -153,6 +153,9 @@ var typedArrayName = Object.getOwnPropertyDescriptor(TYPED_ARRAY, Symbol.toStrin
153
153
  function parseRsaPublicKey(key) {
154
154
  const spki = key && typeof key === "object" ? key.spki : void 0;
155
155
  const pin = key && typeof key === "object" ? key.sha256 : void 0;
156
+ const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
157
+ if (named !== void 0 && named !== 17)
158
+ throw refuse("key");
156
159
  if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
157
160
  throw refuse("key");
158
161
  if (typeof pin !== "string" || !SHA256_HEX.test(pin))
@@ -188,9 +191,10 @@ function parseRsaPublicKey(key) {
188
191
  if (!MODULUS_BYTES.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
189
192
  throw refuse("key");
190
193
  const e = exponent.bytes;
191
- if (e.length !== 3 || e[0] !== 1 || e[1] !== 0 || e[2] !== 1)
194
+ const expected = named === 17 ? [17] : [1, 0, 1];
195
+ if (e.length !== expected.length || !expected.every((byte, i) => e[i] === byte))
192
196
  throw refuse("key");
193
- return Object.freeze({ n: toBigInt(n), e: 65537n, size: n.length });
197
+ return Object.freeze({ n: toBigInt(n), e: named === 17 ? 17n : 65537n, size: n.length });
194
198
  }
195
199
  function rsaesPkcs1v15Encrypt(key, message, random) {
196
200
  const { n, e, size } = parseRsaPublicKey(key);