@agent-cards/sdk 0.23.20 → 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 (42) hide show
  1. package/CHANGELOG.md +41 -2
  2. package/PREFLIGHT.md +2 -0
  3. package/README.md +143 -5
  4. package/dist/card-fields.generated.js +984 -57
  5. package/dist/cdp.js +146 -10
  6. package/dist/client.d.ts +104 -3
  7. package/dist/client.js +233 -23
  8. package/dist/comgate.d.ts +50 -0
  9. package/dist/comgate.js +80 -0
  10. package/dist/cybersource-secure-acceptance.generated.d.ts +1 -1
  11. package/dist/eprotect.generated.d.ts +1 -1
  12. package/dist/gmo.generated.js +7 -3
  13. package/dist/hipay.generated.d.ts +5 -5
  14. package/dist/hipay.generated.js +5 -2
  15. package/dist/hold.d.ts +1 -1
  16. package/dist/hold.js +10 -4
  17. package/dist/hosted-entry.d.ts +4 -0
  18. package/dist/hosted-entry.js +32 -0
  19. package/dist/index.d.ts +1 -0
  20. package/dist/paddle-tokenex.generated.js +7 -3
  21. package/dist/payrails.generated.js +7 -3
  22. package/dist/pre-claim.d.ts +7 -1
  23. package/dist/pre-claim.js +127 -20
  24. package/dist/preflight-catalog.json +58 -0
  25. package/dist/preflight-schemas.json +4 -0
  26. package/dist/preflight.generated.js +26 -2
  27. package/dist/primer.generated.js +1027 -100
  28. package/dist/przelewy24.d.ts +47 -0
  29. package/dist/przelewy24.js +88 -0
  30. package/dist/registry.d.ts +6 -5
  31. package/dist/registry.js +27 -7
  32. package/dist/shiji-sts.generated.js +7 -3
  33. package/dist/stripe-checkout.generated.js +621 -12
  34. package/dist/tokenex-iframe.d.ts +93 -0
  35. package/dist/tokenex-iframe.generated.d.ts +81 -0
  36. package/dist/tokenex-iframe.generated.js +403 -0
  37. package/dist/tokenex-iframe.js +195 -0
  38. package/dist/transbank.d.ts +45 -0
  39. package/dist/transbank.js +73 -0
  40. package/dist/twoc2p.generated.js +7 -3
  41. package/examples/preflight/kernel-native/inventory.json +1 -1
  42. package/package.json +3 -3
package/dist/client.js CHANGED
@@ -2,7 +2,11 @@ import { BUILTIN_REGISTRY, cardUrlPatterns as deriveCardUrlPatterns, LOOPBACK_UR
2
2
  import { armServedProfiles, classifyProfileRequest, declareSandboxMerchant, merchantProfileEnvironment, merchantProfileFor, merchantProfileUrlPatterns, } from './merchant-hosted.js';
3
3
  import { merchantAmountExchanges, merchantAmountFromResponses, merchantProfilePricedBySource, merchantTotalWire, MerchantTotalWait, } from './merchant-total.js';
4
4
  import { ACI_CAPABILITY, ACI_PSP, aciCardLegAnswer } from './aci.js';
5
+ import { PRZELEWY24_CAPABILITY, PRZELEWY24_PSP } from './przelewy24.js';
5
6
  import { EPROTECT_CAPABILITY, EPROTECT_PSP, eprotectCheckoutRefusal, eprotectScriptAnswer, isEprotectRegistration } from './eprotect.js';
7
+ import { COMGATE_CAPABILITY, COMGATE_PSP } from './comgate.js';
8
+ import { isHostedGetEntry } from './hosted-entry.js';
9
+ import { TRANSBANK_CAPABILITY, TRANSBANK_PSP } from './transbank.js';
6
10
  import { isMercadoTokenRequest, parseMercadoCheckoutContext, validateMercadoProcessorContext } from './mercado-checkout.generated.js';
7
11
  import { matchesPreparation, preparationMode, validPreparationEnvironment } from './prepared-processor.js';
8
12
  import { fiservKeyPinById, isFiservSubstitution, requiresFiservPreparation } from './fiserv.js';
@@ -32,6 +36,7 @@ import { JUSPAY_CAPABILITY, JUSPAY_PSP, juspayPageAnswer } from './juspay-gate.j
32
36
  import { CARD_ENDPOINT_MODE, CARD_ENDPOINT_PSP, CardEndpointRefusedError, cardEndpointById, cardEndpointLive, cardEndpointSessionRefusal, } from './card-endpoint.js';
33
37
  import { merchantCardEndpointFactsRefusal as sharedFactsRefusal, readMerchantCardEndpointFacts as sharedReadFacts, } from './merchant-card-endpoints.generated.js';
34
38
  import { DATATRANS_CAPABILITY } from './datatrans.js';
39
+ import { TOKENEX_IFRAME_CAPABILITY, TOKENEX_IFRAME_PSP, tokenexIframePageAnswer, tokenexIframePlaceholderFits } from './tokenex-iframe.js';
35
40
  import { PELECARD_CAPABILITY, PELECARD_PSP } from './pelecard.js';
36
41
  import { PRIMER_CAPABILITY, PRIMER_PSP, primerTokenAnswer } from './primer.js';
37
42
  import { PAYRAILS_CAPABILITY, isPayrailsPaymentUrl, payrailsAnswer } from './payrails.js';
@@ -228,6 +233,13 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
228
233
  * checkout relay. Served on the same terms: only to a build that lists it, for a company
229
234
  * Agentcard turned Payfast on for.
230
235
  *
236
+ * `przelewy24_hosted_payment_page`: Przelewy24's pay wall, whose card-free link
237
+ * (secure.przelewy24.pl/trnRequest/<token>, a plain GET the merchant's redirect or script sends
238
+ * the buyer to) this build pauses for the cardholder's device by its exact link (hosted-entry.ts),
239
+ * and whose card method post, card form post and Saferpay resolver this build never lets the
240
+ * agent's browser send (pre-claim.ts, przelewy24.ts). Served on the same terms as NMI's and
241
+ * Redsys's: only to a build that lists it, for a company Agentcard turned Przelewy24 on for.
242
+ *
231
243
  * `wix_payments_tokenize`: the card request Wix Cashier's card frame sends to Wix's
232
244
  * tokenizer (cashier-pci.wixapps.net), only through a prepared checkout: Wix's payment
233
245
  * widget fails the payment 30 seconds after it asks the frame for a token. The
@@ -244,6 +256,15 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
244
256
  * the checkout relay. Served on the same terms: only to a build that lists it, for a company
245
257
  * Agentcard turned PayMongo on for.
246
258
  *
259
+ * `gopay_card_form`: the card post GoPay's card frame sends to its own URL
260
+ * (secure.gopay.com/gp-card-comm/h/<token>) inside the GoPay gateway a shop opens. This build pauses
261
+ * only the frame's own card post and answers it with GoPay's answer as the API recorded it, the
262
+ * empty JSON object the frame reads; the gateway then reads the payment's end from GoPay and runs
263
+ * 3-D Secure in the agent's browser when the bank asks for it. The cardholder's device sends the card
264
+ * through the checkout relay. Served only to a build that lists it, and only for Agentcard's proof
265
+ * company until a reviewed change binds GoPay's payee and amount to the approval: the post names
266
+ * neither. The API takes it only at a shop Agentcard reviewed.
267
+ *
247
268
  * `hipay_vault_token`: the token create HiPay's hosted fields send to HiPay's Secure Vault
248
269
  * (secure2-vault.hipay-tpp.com, stage-secure2-vault for a test row), only through a prepared
249
270
  * checkout: the merchant's page gives the frame 20 seconds after Pay. The cardholder's device
@@ -265,9 +286,89 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
265
286
  * Secure step and card lookup this build never lets the agent's browser send (pre-claim.ts,
266
287
  * quickpay.ts). Served on the same terms as NMI's and Redsys's: only to a build that lists it, for a
267
288
  * company Agentcard turned QuickPay on for.
289
+ *
290
+ * `revolut_card_field`: the card payment Revolut Business's card field or card popup sends from
291
+ * its frame to /api/public/orders/<order token>/payments on merchant.revolut.com, on a merchant's
292
+ * own page or Revolut's hosted checkout. This build pauses only the frame's card payment and
293
+ * answers it with Revolut's answer as the API recorded it: the payment Revolut created, which the
294
+ * frame then follows, through any 3-D Secure step, in the agent's browser. A payment by Apple Pay,
295
+ * Google Pay or Revolut Pay on the same URL carries no card and continues untouched. Revolut's
296
+ * host answers the Vault's origin, so the cardholder's device sends the card itself, with no relay.
297
+ * Served on the same terms: only to a build that lists it, for a company Agentcard turned Revolut
298
+ * on for.
299
+ *
300
+ * `pay_nl_card_token`: the card token request a shop's card form sends to Pay. (pay.nl),
301
+ * Weeztix's sandboxed frame posting its FormData to payment.pay.nl/v1/Payment/getCardToken/json.
302
+ * This build pauses only the form's own multipart body at that exact URL; the cardholder's
303
+ * device sends the card through the checkout relay, and the frame gets the token answer
304
+ * payment-core's judge rebuilt, with the CORS answer for the frame's own origin, null. The
305
+ * request names no amount, so the agent's pair, above zero, is the one the cardholder approves
306
+ * (PAY_NL_PSP below). Served on the same terms: only to a build that lists it, for a company
307
+ * Agentcard turned Pay. on for.
308
+ *
309
+ * `paypal_card_fields`: PayPal Card Fields' confirm, the POST its v5 frame sends to
310
+ * www.paypal.com and its v6 frame to api-m.paypal.com. This build pauses it only in
311
+ * the frames' own shape, refuses one that asks PayPal to keep the card or forces
312
+ * 3-D Secure in the browser with a `blocked` event, and answers the frame with the
313
+ * order's id and status as the API recorded them. The device sends a v5 confirm
314
+ * through the checkout relay and a v6 one directly. Served on the same terms: only
315
+ * to a build that lists it, for a company Agentcard turned PayPal Card Fields on
316
+ * for. Every other company keeps the checkout guard's refusal (paypal-card-forms.ts).
317
+ *
318
+ * `comgate_hosted_payment_page`: ComGate's payment gateway, whose card-free gateway link
319
+ * (payN.comgate.cz/init?id=<transaction id>, a plain GET) this build pauses for the
320
+ * cardholder's device by its exact link (hosted-entry.ts), in the page, in a frame of it or
321
+ * in a window it opened, and whose card hosts this build never lets the agent's browser post
322
+ * to (pre-claim.ts, comgate.ts). Served on the same terms as NMI's and Redsys's: only to a
323
+ * build that lists it, for a company Agentcard turned ComGate on for.
324
+ *
325
+ * `makecommerce_card_frame`: the card post MakeCommerce's card frame sends to its own card endpoint
326
+ * (cc.maksekeskus.ee/card-payment) under the shop's publishable key. This build pauses only the
327
+ * frame's own one-time card payment and answers it with MakeCommerce's answer as the API recorded
328
+ * it: the URL of MakeCommerce's 3-D Secure page, which the frame then opens in the agent's browser.
329
+ * The cardholder's device sends the card through the checkout relay. Served on the same terms: only
330
+ * to a build that lists it, for a company Agentcard turned MakeCommerce on for.
331
+ *
332
+ * `poynt_collect_nonce`: GoDaddy Payments' card request, the POST Poynt Collect's
333
+ * card frame sends to a store's generate-nonce on services.poynt.net. This build
334
+ * pauses it only as the frame writes it, refuses a body that asks Poynt to keep the
335
+ * card in the browser with a `blocked` event, and answers the frame with the nonce as
336
+ * the API recorded it. The device sends the card through the checkout relay. Served
337
+ * on the same terms: only to a build that lists it, for a company Agentcard turned
338
+ * GoDaddy Payments on for.
339
+ *
340
+ * `tokenex_iframe_tokenize`: the card post TokenEx's hosted iframe v3 sends from its card-number frame
341
+ * to its own document URL on htp.tokenex.com (JetBlue's card form). This build pauses only the PCI frame's
342
+ * own card post with its CVV frame, refuses in the browser every other post on that path that carries a
343
+ * card (tokenex-iframe.ts), answers it with TokenEx's token as the API recorded it, rebuilt from
344
+ * payment-core's allow-list, and answers the same frame's byte-identical repeat from that answer while the
345
+ * approval is being handed off. Served on the same terms: only to a build that lists it, for a company
346
+ * Agentcard turned the TokenEx iframe on for.
347
+ *
348
+ * `transbank_webpay_hosted_payment_page`: Transbank's Webpay Plus, whose card-free entry
349
+ * (webpay3g.transbank.cl/webpayserver/initTransaction?token_ws=<token>, the merchant's
350
+ * redirect, a plain GET) this build pauses for the cardholder's device by its exact link
351
+ * (hosted-entry.ts) in the page or a frame of it, and with attachToCdp also in a window the
352
+ * page opened, and whose hosts this build never lets the agent's browser post to (pre-claim.ts,
353
+ * transbank.ts), so the token is never spent there. attachToPlaywright covers the page it is
354
+ * attached to and that page's frames only, and pauses only a direct or scripted navigation to
355
+ * the entry: its page.route sees no HTTP redirect hop, so a merchant's redirect needs attachToCdp.
356
+ * Served on the same terms as NMI's and Redsys's: only to a build that lists it, for a company
357
+ * Agentcard turned Webpay on for.
358
+ *
359
+ * `sumup_checkout_process`: the card request SumUp's Payment Widget sends from its hidden form frame
360
+ * on gateway.sumup.com, a PUT to https://api.sumup.com/v0.2/checkouts/<checkout id>. This build pauses
361
+ * that PUT as it pauses Gravy's, so only the CDP and Playwright adapters see it (the form frame is
362
+ * cross-origin to the page), and answers the frame with SumUp's own answer as the API recorded it: the
363
+ * paid checkout, or the 3-D Secure step the widget then runs in the agent's browser. The cardholder's
364
+ * device sends the card itself, and the API holds the payment to a merchant Agentcard reviewed, at the
365
+ * amount SumUp holds for the checkout. Served on the same terms: only to a build that lists it, for a
366
+ * company Agentcard turned SumUp on for.
268
367
  */
269
368
  export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CYBERSOURCE_FLEX_CAPABILITY, JUSPAY_CAPABILITY, DATATRANS_CAPABILITY, 'authorize_net_dpm_form', PELECARD_CAPABILITY, ACI_CAPABILITY, 'creditguard_pps_process', PRIMER_CAPABILITY, PAYRAILS_CAPABILITY, CONVERGE_CAPABILITY, EPROTECT_CAPABILITY, WSPAY_CAPABILITY, SHIJI_STS_CAPABILITY, AMADEUS_CHECKOUT_CAPABILITY, 'worldline_mycheckout_form', 'verifone_card_capture', 'ekashu_hosted_payment_page', SECURE_ACCEPTANCE_CAPABILITY, 'gravy_session_fields_put', 'moneris_hosted_tokenization', PADDLE_VGS_CAPABILITY, PADDLE_TOKENEX_CAPABILITY,
270
- 'redsys_hosted_payment_page', 'lyra_krypton_payment', 'payfast_card_pay', WIX_PAYMENTS_CAPABILITY, 'paymongo_checkout_pay', HIPAY_CAPABILITY, TWOC2P_CAPABILITY, 'quickpay_hosted_payment_page'];
369
+ 'redsys_hosted_payment_page', 'lyra_krypton_payment', 'payfast_card_pay', WIX_PAYMENTS_CAPABILITY, 'paymongo_checkout_pay', 'pay_nl_card_token', HIPAY_CAPABILITY, TWOC2P_CAPABILITY, 'quickpay_hosted_payment_page', 'revolut_card_field', 'paypal_card_fields', 'gopay_card_form', COMGATE_CAPABILITY, PRZELEWY24_CAPABILITY, 'makecommerce_card_frame', 'poynt_collect_nonce',
370
+ TOKENEX_IFRAME_CAPABILITY, TRANSBANK_CAPABILITY,
371
+ 'sumup_checkout_process'];
271
372
  /**
272
373
  * Processors whose paused request names no amount at all, so the pair the
273
374
  * agent passes is the amount the cardholder approves: authorize() refuses one
@@ -299,20 +400,68 @@ export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CY
299
400
  * PayMongo's card attach carries none either: the merchant bound the total, always in
300
401
  * Philippine pesos, to the checkout session when it created it, so the agent sends that
301
402
  * total, above zero (PAYMONGO_PSP below), and the API holds it to the session PayMongo's
302
- * own page shows. 2C2P's Payment carries none either: the merchant bound the total to the
403
+ * own page shows. GoPay's card post carries none either: the shop's server set the amount
404
+ * when it created the payment at GoPay, and GoPay's gateway shows it only inside its own
405
+ * session, so the agent sends the total the gateway shows, above zero (GOPAY_PSP below).
406
+ * 2C2P's Payment carries none either: the merchant bound the total to the
303
407
  * payment token when it created it, so the agent sends the total 2C2P's page shows, above
304
408
  * zero (TWOC2P_PSP), and the API holds it to the amount 2C2P's own PaymentOption answer names.
409
+ * Przelewy24's pay wall link carries none either: the merchant's server registered the amount
410
+ * with Przelewy24 under the link's token, so the agent sends the amount the pay wall shows, above
411
+ * zero (PRZELEWY24_PSP below), and the cardholder's device holds the pay wall to it.
305
412
  * HiPay's token create carries none either: the merchant's server charges
306
413
  * HiPay's token for its own order, so the agent's pair, which the prepared checkout carries,
307
- * is the total the cardholder approves, above zero as Moneris's is.
414
+ * is the total the cardholder approves, above zero as Moneris's is. Revolut's card payment
415
+ * names the order's amount in minor units but not its currency, which only the order holds,
416
+ * so the number alone is no price the cardholder can approve: the agent sends the pair, above
417
+ * zero (REVOLUT_PSP below), and the API holds its amount to the body's and its currency to
418
+ * one that Revolut and the API both count in hundredths.
419
+ * Pay.'s card token request carries none either: the shop's server charges the token later for
420
+ * its own order total, so the agent's pair, above zero (PAY_NL_PSP below), is the one figure the
421
+ * approval shows.
422
+ * PayPal Card Fields' confirm carries none either: the merchant's server fixed the
423
+ * amount when it created the order, so the agent's pair, above zero (PAYPAL_PSP
424
+ * below), is the one figure the approval shows.
425
+ * ComGate's gateway link carries none either: the merchant's server set
426
+ * the amount when it created the payment at ComGate, so the agent's pair, above zero
427
+ * (COMGATE_PSP below), is the figure the cardholder approves, and the cardholder's device
428
+ * holds ComGate's own figure to it before any card leaves.
429
+ * MakeCommerce's card post carries none either: MakeCommerce's transaction holds the total, in
430
+ * euros, so the agent sends the total the shop's order page shows, above zero (MAKECOMMERCE_PSP
431
+ * below), and the API refuses any other currency.
432
+ * GoDaddy Payments' generate-nonce carries none either: GoDaddy's server charges
433
+ * the nonce later, so its pair must be above zero too (POYNT_PSP below).
434
+ * The TokenEx iframe's card post carries none either: it mints a token into the merchant's TokenEx
435
+ * vault, which the merchant's server charges later for its own order, so the agent sends the total
436
+ * the merchant's page shows, above zero (TOKENEX_IFRAME_PSP), and the API refuses a create without it.
437
+ * Webpay's entry carries none either: the merchant's server bound the total, in Chilean pesos,
438
+ * to the transaction when it created it, so the agent's pair, above zero (TRANSBANK_PSP below),
439
+ * is the figure the cardholder approves, and the cardholder's device holds Webpay's own
440
+ * transaction to it before any card leaves.
441
+ * SumUp's card request carries none either: the merchant's server bound the
442
+ * total and its currency to the checkout when it created it, so the agent sends the total the
443
+ * payment page shows, above zero (SUMUP_PSP below), and the API holds it to the checkout SumUp
444
+ * itself reports.
308
445
  */
309
446
  const MONERIS_PSP = 'moneris';
310
447
  const PAYFAST_PSP = 'payfast';
311
448
  const PAYMONGO_PSP = 'paymongo';
312
- const AGENT_AMOUNT_PROCESSORS = [GMO_PSP, PELECARD_PSP, WSPAY_PSP, SECURE_ACCEPTANCE_PSP, MONERIS_PSP, PADDLE_VGS_PSP, PAYFAST_PSP, WIX_PAYMENTS_PSP, PAYMONGO_PSP, HIPAY_PSP, TWOC2P_PSP];
449
+ const REVOLUT_PSP = 'revolut';
450
+ const PAY_NL_PSP = 'pay_nl';
451
+ const PAYPAL_PSP = 'paypal';
452
+ const GOPAY_PSP = 'gopay';
453
+ const MAKECOMMERCE_PSP = 'makecommerce';
454
+ const POYNT_PSP = 'poynt';
455
+ const SUMUP_PSP = 'sumup';
456
+ const AGENT_AMOUNT_PROCESSORS = [GMO_PSP, PELECARD_PSP, WSPAY_PSP, SECURE_ACCEPTANCE_PSP, MONERIS_PSP, PADDLE_VGS_PSP, PAYFAST_PSP, WIX_PAYMENTS_PSP, PAYMONGO_PSP, PAY_NL_PSP, HIPAY_PSP, TWOC2P_PSP, REVOLUT_PSP, PAYPAL_PSP, GOPAY_PSP, COMGATE_PSP,
457
+ PRZELEWY24_PSP, MAKECOMMERCE_PSP, POYNT_PSP, TOKENEX_IFRAME_PSP, TRANSBANK_PSP, SUMUP_PSP];
313
458
  /** How AmountRequiredError names a processor. */
314
459
  const PROCESSOR_NAMES = { [GMO_PSP]: 'GMO', [PELECARD_PSP]: 'Pelecard', [WSPAY_PSP]: 'WSPay',
315
- [SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance', [MONERIS_PSP]: 'Moneris', [PADDLE_VGS_PSP]: 'Paddle', [PAYFAST_PSP]: 'Payfast', [WIX_PAYMENTS_PSP]: 'Wix', [PAYMONGO_PSP]: 'PayMongo', [HIPAY_PSP]: 'HiPay', [TWOC2P_PSP]: '2C2P' };
460
+ [SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance', [MONERIS_PSP]: 'Moneris', [PADDLE_VGS_PSP]: 'Paddle', [PAYFAST_PSP]: 'Payfast', [WIX_PAYMENTS_PSP]: 'Wix', [PAYMONGO_PSP]: 'PayMongo', [PAY_NL_PSP]: 'Pay.', [HIPAY_PSP]: 'HiPay', [TWOC2P_PSP]: '2C2P',
461
+ [REVOLUT_PSP]: 'Revolut', [PAYPAL_PSP]: 'PayPal', [GOPAY_PSP]: 'GoPay',
462
+ [COMGATE_PSP]: 'ComGate', [PRZELEWY24_PSP]: 'Przelewy24',
463
+ [MAKECOMMERCE_PSP]: 'MakeCommerce', [POYNT_PSP]: 'GoDaddy Payments', [TOKENEX_IFRAME_PSP]: 'TokenEx', [TRANSBANK_PSP]: 'Webpay',
464
+ [SUMUP_PSP]: 'SumUp' };
316
465
  /**
317
466
  * Processors whose request and answer name no amount at all, so the total the
318
467
  * payment page shows (`pageAmount`) is the one figure that ties the agent's pair
@@ -543,13 +692,18 @@ const PROCESSOR_PLACEHOLDER_NUMBERS = Object.freeze({});
543
692
  /**
544
693
  * The placeholder number for a network (lowercase, as GET /api/v2/vault_cards names it) on a
545
694
  * processor's page: the processor's own number for that network when `overrides` names one, else
546
- * the network's default, else undefined for a network with no placeholder.
695
+ * the network's default, else undefined for a network with no placeholder. On a TokenEx iframe
696
+ * (`tokenex_iframe`) the number must also be one TokenEx's frame reads as that network, since the frame
697
+ * names the brand to the page from the typed digits and the cardholder's device refuses a mismatch: the
698
+ * frame's table takes Visa, Mastercard and American Express, so every other network gets undefined.
547
699
  */
548
700
  export function placeholderNumber(brand, psp, overrides = PROCESSOR_PLACEHOLDER_NUMBERS) {
549
701
  const own = psp !== undefined && Object.prototype.hasOwnProperty.call(overrides, psp) ? overrides[psp] : undefined;
550
- if (own && Object.prototype.hasOwnProperty.call(own, brand))
551
- return own[brand];
552
- return Object.prototype.hasOwnProperty.call(PLACEHOLDER_NUMBERS, brand) ? PLACEHOLDER_NUMBERS[brand] : undefined;
702
+ const number = own && Object.prototype.hasOwnProperty.call(own, brand) ? own[brand]
703
+ : Object.prototype.hasOwnProperty.call(PLACEHOLDER_NUMBERS, brand) ? PLACEHOLDER_NUMBERS[brand] : undefined;
704
+ if (number !== undefined && psp === TOKENEX_IFRAME_PSP && !tokenexIframePlaceholderFits(brand, number))
705
+ return undefined;
706
+ return number;
553
707
  }
554
708
  /**
555
709
  * The recognizer says this processor is preparation-required, and no preparation
@@ -575,7 +729,9 @@ export class PreparationRequiredError extends Error {
575
729
  * when the merchant's server created the payment), so the `amount` and
576
730
  * `currency` you pass are what the cardholder approves, and for WSPay the
577
731
  * figure the API compares with WSPay's answer when that answer names one (a
578
- * 3-D Secure step names none). Thrown locally before any create or
732
+ * 3-D Secure step names none). A Revolut card payment names the order's
733
+ * amount but not its currency, so it takes the same pair, above zero.
734
+ * Thrown locally before any create or
579
735
  * prompt, and terminal: the same request without an amount fails the same
580
736
  * way. The API answers 400 amount_required for the same case. A page total
581
737
  * (`pageAmount`) does not count.
@@ -585,7 +741,8 @@ export class AmountRequiredError extends Error {
585
741
  code = 'amount_required';
586
742
  constructor(psp) {
587
743
  const processor = PROCESSOR_NAMES[psp] ?? psp;
588
- super(`A ${processor} payment request names no amount, so pass amount and currency: that is the amount the cardholder approves. Nothing was created and nothing was charged.`);
744
+ const lacks = psp === REVOLUT_PSP ? 'names its amount but not its currency' : 'names no amount';
745
+ super(`A ${processor} payment request ${lacks}, so pass amount and currency: that is the amount the cardholder approves. Nothing was created and nothing was charged.`);
589
746
  this.psp = psp;
590
747
  this.name = 'AmountRequiredError';
591
748
  }
@@ -1183,12 +1340,19 @@ function maskPaymongoSession(path) {
1183
1340
  * https://secure.gopay.com/gp-card-comm/h/<hex token>?lang=..&ver=..&SG=<64 hex> (payment-core gopay.js). The
1184
1341
  * token names that payment's card form, and with the SG, which redactUrl drops with the query, anyone who holds
1185
1342
  * the URL can open the form and post a card to it. On GoPay's two card frame hosts the segment after /h/, in any
1186
- * case or after an escaped slash, reads {token}: https://secure.gopay.com/gp-card-comm/h/{token}.
1343
+ * case or after an escaped slash, reads {token}: https://secure.gopay.com/gp-card-comm/h/{token}. Then every run of
1344
+ * 16 or more hex digits left reads {token} too, so a token after a path the frame never writes (an escaped h, a
1345
+ * path parameter) is masked as well; the token is 16 hex digits or more, and no other path the card frame uses holds
1346
+ * such a run. The pattern reads a percent escape as one unit: an escaped hex digit (%61, %2561) counts toward a run,
1347
+ * so escaping some of a token's digits never splits it into runs that show, and any other escape (%2F, %252F, %68)
1348
+ * is kept whole, so its own hex digits never start a run and leave part of a token showing.
1187
1349
  */
1188
1350
  const GOPAY_CARD_FORM_HOST = /^secure(?:\.sandbox)?\.gopay\.com\.?$/i;
1189
1351
  const GOPAY_CARD_FORM_TOKEN = new RegExp(`(${SLASH}h${SLASH}+)[^/?#]*`, 'gi');
1352
+ const GOPAY_TOKEN_RUN = /(?:[0-9a-f]|%(?:25)*(?:3[0-9]|[46][1-6])){16,}|%(?:25)*[0-9a-f]{2}/gi;
1353
+ const GOPAY_LONE_ESCAPE = /^%(?:25)*[0-9a-f]{2}$/i;
1190
1354
  function maskGopayToken(path) {
1191
- return path.replace(GOPAY_CARD_FORM_TOKEN, '$1{token}');
1355
+ return path.replace(GOPAY_CARD_FORM_TOKEN, '$1{token}').replace(GOPAY_TOKEN_RUN, (run) => (GOPAY_LONE_ESCAPE.test(run) ? run : '{token}'));
1192
1356
  }
1193
1357
  /**
1194
1358
  * KOMOJU's Hosted Fields frame pays a session with POST /api/v1/sessions/<id>/pay on komoju.com under
@@ -1273,6 +1437,18 @@ const REVOLUT_HOST = /^(?:sandbox-)?(?:merchant|checkout|merchant-mgmt)\.revolut
1273
1437
  function maskRevolutToken(path) {
1274
1438
  return maskUuids(path, '{token}');
1275
1439
  }
1440
+ /**
1441
+ * ComGate's gateway pages name the payment by its transaction id in their paths (pay1.comgate.cz/<id>,
1442
+ * /specify/card2/<id>, payment-core processors/comgate.js), and the id alone opens that payment's gateway page, its
1443
+ * amount and its merchant. Its entry link names the id in the query, which redactUrl drops. On every host ComGate
1444
+ * owns, any id of its shape, in any case and with each hyphen in any spelling HYPHEN reads, reads {payment}. The
1445
+ * pattern reads a percent escape as one unit and keeps it, as maskUuids does.
1446
+ */
1447
+ const COMGATE_HOST = /(?:^|\.)comgate\.cz\.?$/i;
1448
+ const COMGATE_ID = new RegExp(`%(?:25)*[0-9a-f]{2}|[a-z0-9]{4}${HYPHEN}[a-z0-9]{4}${HYPHEN}[a-z0-9]{4}`, 'gi');
1449
+ function maskComgateId(path) {
1450
+ return path.replace(COMGATE_ID, (token) => (token.startsWith('%') ? token : '{payment}'));
1451
+ }
1276
1452
  /**
1277
1453
  * Paytrail names its payment in the path of every route of its card method
1278
1454
  * (/payments/<transaction>/click-to-pay/loading-and-redirect, and its success and cancel routes), and the same id
@@ -1377,6 +1553,7 @@ const PATH_CREDENTIALS = [
1377
1553
  { host: PRZELEWY24_HOST, named: /przelewy24\.pl/i, mask: maskPrzelewy24Token },
1378
1554
  { host: REVOLUT_HOST, named: /(?:merchant|checkout|merchant-mgmt)\.revolut\.com/i, mask: maskRevolutToken },
1379
1555
  { host: SUMUP_API_HOST, named: /api\.sumup\.com/i, mask: maskSumupCheckout },
1556
+ { host: COMGATE_HOST, named: /comgate\.cz/i, mask: maskComgateId },
1380
1557
  { host: PAYTRAIL_HOST, named: /paytrail\.com/i, mask: maskPaytrailTransaction },
1381
1558
  { host: PAYMENT_HIGHWAY_HOST, named: /(?:paymenthighway\.io|sph-test-solinor\.com)/i, mask: maskPaymentHighwaySession },
1382
1559
  { host: TWOC2P_PAGE_HOST, named: /pgw-ui\.2c2p\.com/i, mask: maskTwoC2pToken, pathMask: maskTwoC2pPath },
@@ -1754,7 +1931,7 @@ export class VaultClient {
1754
1931
  // cybersource_sa_token_create, gravy_session_fields_put,
1755
1932
  // moneris_hosted_tokenization, paddle_vgs_cards, paddle_tokenex_pay,
1756
1933
  // redsys_hosted_payment_page, lyra_krypton_payment, payfast_card_pay,
1757
- // quickpay_hosted_payment_page) and
1934
+ // quickpay_hosted_payment_page, tokenex_iframe_tokenize, among others) and
1758
1935
  // the caller's company is one Agentcard turned that processor on for, so this
1759
1936
  // build arms Fiserv's card capture, GMO's getToken, CyberSource Flex's card
1760
1937
  // fields, Juspay's card flow, Datatrans's Secure Fields card post, the
@@ -1948,7 +2125,9 @@ export class VaultClient {
1948
2125
  * The facts hold only while the cardholder pays with that card. `psp` names the processor
1949
2126
  * whose card form the agent types into (the recognizer's name, `worldline_mycheckout`): a
1950
2127
  * processor that needs its own number for the card's network gets it, and every other gets the
1951
- * network's default. Throws PlaceholderCardError when there is no such card, its network has no
2128
+ * network's default. On a TokenEx iframe (`tokenex_iframe`, JetBlue) the number is one TokenEx's frame
2129
+ * reads as the card's own network, Visa, Mastercard or American Express, and any other network has no
2130
+ * placeholder there. Throws PlaceholderCardError when there is no such card, its network has no
1952
2131
  * placeholder, or it carries no expiry.
1953
2132
  */
1954
2133
  async placeholderCard(input) {
@@ -2488,10 +2667,14 @@ export class VaultClient {
2488
2667
  : `checkout authorization is POST-only; got ${method} for ${redactUrl(input.request.url)}. ` +
2489
2668
  'A non-POST tokenizer needs recognizer support before it can be intercepted.');
2490
2669
  }
2491
- // A GET card request is its URL alone. This build completes one: Worldpay
2492
- // eProtect's registration exactly as payment-core admits it, with no body.
2670
+ // A GET card request is its URL alone. This build completes two kinds: Worldpay
2671
+ // eProtect's registration exactly as payment-core admits it, with no body, and a
2672
+ // hosted page's entry link exactly as its rule admits it (hosted-entry.ts), with no
2673
+ // body, which the cardholder's device takes over.
2493
2674
  const eprotect = rec?.psp === EPROTECT_PSP;
2494
- if (cardMethod === 'GET' && !(eprotect && isEprotectRegistration(input.request))) {
2675
+ const hostedGetEntry = mode === 'hosted_form' && !!rec && isHostedGetEntry(rec.psp, input.request.url)
2676
+ && (input.request.body === undefined || input.request.body === null || input.request.body === '');
2677
+ if (cardMethod === 'GET' && !(eprotect && isEprotectRegistration(input.request)) && !hostedGetEntry) {
2495
2678
  throw new Error(`this ${rec?.psp} GET is not a card registration this version of @agent-cards/checkout can complete: ${redactUrl(input.request.url)}.`);
2496
2679
  }
2497
2680
  // A CyberSource Secure Acceptance token create (always prepared: its recognizer requires it). The
@@ -2517,11 +2700,26 @@ export class VaultClient {
2517
2700
  // amount_required.
2518
2701
  if (!hasAmount && rec && AGENT_AMOUNT_PROCESSORS.includes(rec.psp))
2519
2702
  throw new AmountRequiredError(rec.psp);
2520
- // A Moneris or a HiPay token is charged later for whatever the merchant's server decides, and a Payfast pay, a
2521
- // PayMongo attach or a 2C2P Payment charges the total its payment, checkout session or payment token
2522
- // already holds, so a zero pair would show the cardholder no price at all: it is refused like a missing one.
2523
- if (hasAmount && rec && (rec.psp === MONERIS_PSP || rec.psp === PAYFAST_PSP || rec.psp === PAYMONGO_PSP || rec.psp === HIPAY_PSP || rec.psp === TWOC2P_PSP)
2524
- && Number(input.amount) <= 0)
2703
+ // A Przelewy24 pay wall charges the amount the merchant's server registered with Przelewy24 under the link's
2704
+ // token, so a zero pair would show the cardholder no price at all: it is refused like a missing one.
2705
+ // A Moneris, a HiPay or a Pay. token, or a GoDaddy Payments nonce, is charged later for whatever the merchant's
2706
+ // server decides, a Payfast pay, a PayMongo attach, a 2C2P Payment, a Revolut card payment or a SumUp card request
2707
+ // charges the total its payment, checkout session, payment token, order or checkout already holds, and a PayPal
2708
+ // order's amount was fixed by the merchant's server and never shown in the confirm, and a GoPay card post charges
2709
+ // the total GoPay's payment already holds, so a zero pair would show the cardholder no price at all: it is refused
2710
+ // like a missing one.
2711
+ // A ComGate payment charges the total ComGate already holds for it, the same way, and a Webpay transaction the
2712
+ // total the merchant's server bound to it.
2713
+ // A Moneris token is charged later for whatever the merchant's server decides, and a Payfast pay, a
2714
+ // PayMongo attach or a MakeCommerce card post charges the total its payment, checkout session or
2715
+ // transaction already holds, so a zero pair would show the cardholder no price at all: it is refused
2716
+ // like a missing one. So is a TokenEx iframe token, which the merchant's server charges later for its own order.
2717
+ if (hasAmount && rec && rec.psp === PRZELEWY24_PSP && Number(input.amount) <= 0)
2718
+ throw new AmountRequiredError(rec.psp);
2719
+ if (hasAmount && rec && (rec.psp === MONERIS_PSP || rec.psp === PAYFAST_PSP || rec.psp === PAYMONGO_PSP || rec.psp === HIPAY_PSP || rec.psp === TWOC2P_PSP
2720
+ || rec.psp === REVOLUT_PSP || rec.psp === PAY_NL_PSP || rec.psp === PAYPAL_PSP
2721
+ || rec.psp === GOPAY_PSP || rec.psp === COMGATE_PSP || rec.psp === MAKECOMMERCE_PSP
2722
+ || rec.psp === POYNT_PSP || rec.psp === TOKENEX_IFRAME_PSP || rec.psp === TRANSBANK_PSP || rec.psp === SUMUP_PSP) && Number(input.amount) <= 0)
2525
2723
  throw new AmountRequiredError(rec.psp);
2526
2724
  // Nor is the agent's pair tied to the page by anything but the total the
2527
2725
  // page shows: without it the cardholder could approve one figure while the
@@ -3039,6 +3237,18 @@ export class VaultClient {
3039
3237
  response.headers = answer.headers;
3040
3238
  response.body = answer.body;
3041
3239
  }
3240
+ if (rec?.psp === TOKENEX_IFRAME_PSP) {
3241
+ // TokenEx's answer enters the frame only as TokenEx's 200 with a sound token, rebuilt from payment-core's
3242
+ // allow-list under a JSON content type (tokenex-iframe.ts tokenexIframePageAnswer); the frame adds its own
3243
+ // cardType. Anything else is never handed over: the device may already have sent the card, so the
3244
+ // outcome is unknown rather than declined.
3245
+ const answer = tokenexIframePageAnswer(response.status, response.body);
3246
+ if (!answer)
3247
+ throw new PaymentOutcomeUnknownError(authorizationId, 'tokenex_iframe_token_unconfirmed');
3248
+ response.status = answer.status;
3249
+ response.headers = answer.headers;
3250
+ response.body = answer.body;
3251
+ }
3042
3252
  let processorContext;
3043
3253
  if (mercadoContext) {
3044
3254
  try {
@@ -0,0 +1,50 @@
1
+ /**
2
+ * ComGate's payment gateway (pay1 to pay4.comgate.cz, where most Czech and Slovak e-shops send the buyer), as this
3
+ * SDK reads it.
4
+ *
5
+ * The merchant's server creates the payment at ComGate and sends the buyer's browser to the gateway link ComGate
6
+ * answered with, https://payN.comgate.cz/init?id=<transaction id>, by a redirect or by setting the page's or a
7
+ * frame's location. That GET carries no card and nothing but the payment's id, and it is the one request a build
8
+ * that declares ComGate's capability pauses for ComGate (hosted-entry.ts): the cardholder's device then makes the
9
+ * gateway's own calls for that payment over the end-to-end TLS relay (payment-core processors/comgate.js). Only the
10
+ * link exactly as ComGate writes it is the entry; any other parameter would be handed on to the gateway's own
11
+ * route, which these rules never see.
12
+ *
13
+ * COMGATE_GATEWAY_HOSTS is payment-core's COMGATE_GATEWAY_HOSTS, and isComgateEntryUrl is payment-core's rule of
14
+ * the same name; hosted-entry.test.mjs pins both to payment-core on every case payment-core's own tests list.
15
+ */
16
+ export declare const COMGATE_PSP = "comgate";
17
+ /** The dark-launch capability the API serves ComGate's recognizer behind (payment-core definitions.js). */
18
+ export declare const COMGATE_CAPABILITY = "comgate_hosted_payment_page";
19
+ /** The four gateway hosts ComGate's create answer names, each a host of its own entry. */
20
+ export declare const COMGATE_GATEWAY_HOSTS: readonly string[];
21
+ /**
22
+ * The hosts that take a card, or part of one, for ComGate: the gateway's API (payments.comgate.cz behind pay1 and pay2,
23
+ * payments-gcp.comgate.cz behind pay3 and pay4), where the gateway posts the card (/client/instructions/card-process,
24
+ * check-card) and ComGate's Web Checkout SDK posts its own (/checkout/provider/*, /checkout/card/check-card), and the
25
+ * card frames' hosts (sec.comgate.cz, sec-gcp.comgate.cz), which post the card's first digits to their /bin-checker.
26
+ * The card is already encrypted in ComGate's frame by then, so no body rule could see it: once ComGate is served, this
27
+ * build fails every request to these hosts but a GET, so the card the agent typed never reaches ComGate.
28
+ */
29
+ export declare const COMGATE_CARD_HOSTS: readonly string[];
30
+ /** The Fetch.enable globs attachToCdp arms for the card hosts, only while ComGate is served (cdp.ts). */
31
+ export declare const COMGATE_CARD_PATTERNS: readonly string[];
32
+ /** Whether this URL is on one of ComGate's card hosts (https, no credentials, any port, a trailing dot or not). */
33
+ export declare function isComgateCardHost(url: string): boolean;
34
+ /** Whether this build's registry serves ComGate's entry: a company Agentcard turned ComGate on for, on a build that declares it. */
35
+ export declare function servesComgate(vault: {
36
+ isCardRequest(url: string, method?: string): boolean;
37
+ } | undefined): boolean;
38
+ /**
39
+ * Whether an adapter must hand this request to the pre-claim gates: it is on one of ComGate's card hosts and this
40
+ * build's registry serves ComGate. attachToPlaywright's route predicate asks this, as attachToCdp arms the hosts.
41
+ */
42
+ export declare function isArmedComgateUrl(vault: {
43
+ isCardRequest(url: string, method?: string): boolean;
44
+ } | undefined, url: string): boolean;
45
+ /**
46
+ * Whether a URL is ComGate's gateway link exactly as ComGate's create answer writes it: https, one of the four
47
+ * gateway hosts in lowercase, the default port, no credentials or fragment, the path /init, and a query of the one
48
+ * `id` parameter holding a transaction id. A string that parses to another spelling is not it.
49
+ */
50
+ export declare function isComgateEntryUrl(raw: unknown): boolean;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * ComGate's payment gateway (pay1 to pay4.comgate.cz, where most Czech and Slovak e-shops send the buyer), as this
3
+ * SDK reads it.
4
+ *
5
+ * The merchant's server creates the payment at ComGate and sends the buyer's browser to the gateway link ComGate
6
+ * answered with, https://payN.comgate.cz/init?id=<transaction id>, by a redirect or by setting the page's or a
7
+ * frame's location. That GET carries no card and nothing but the payment's id, and it is the one request a build
8
+ * that declares ComGate's capability pauses for ComGate (hosted-entry.ts): the cardholder's device then makes the
9
+ * gateway's own calls for that payment over the end-to-end TLS relay (payment-core processors/comgate.js). Only the
10
+ * link exactly as ComGate writes it is the entry; any other parameter would be handed on to the gateway's own
11
+ * route, which these rules never see.
12
+ *
13
+ * COMGATE_GATEWAY_HOSTS is payment-core's COMGATE_GATEWAY_HOSTS, and isComgateEntryUrl is payment-core's rule of
14
+ * the same name; hosted-entry.test.mjs pins both to payment-core on every case payment-core's own tests list.
15
+ */
16
+ export const COMGATE_PSP = 'comgate';
17
+ /** The dark-launch capability the API serves ComGate's recognizer behind (payment-core definitions.js). */
18
+ export const COMGATE_CAPABILITY = 'comgate_hosted_payment_page';
19
+ /** The four gateway hosts ComGate's create answer names, each a host of its own entry. */
20
+ export const COMGATE_GATEWAY_HOSTS = Object.freeze(['pay1.comgate.cz', 'pay2.comgate.cz', 'pay3.comgate.cz', 'pay4.comgate.cz']);
21
+ const COMGATE_ENTRY_PATH = '/init';
22
+ // The id the gateway's router takes: three groups of four letters or digits.
23
+ const TRANS_ID = /^[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}$/;
24
+ /**
25
+ * The hosts that take a card, or part of one, for ComGate: the gateway's API (payments.comgate.cz behind pay1 and pay2,
26
+ * payments-gcp.comgate.cz behind pay3 and pay4), where the gateway posts the card (/client/instructions/card-process,
27
+ * check-card) and ComGate's Web Checkout SDK posts its own (/checkout/provider/*, /checkout/card/check-card), and the
28
+ * card frames' hosts (sec.comgate.cz, sec-gcp.comgate.cz), which post the card's first digits to their /bin-checker.
29
+ * The card is already encrypted in ComGate's frame by then, so no body rule could see it: once ComGate is served, this
30
+ * build fails every request to these hosts but a GET, so the card the agent typed never reaches ComGate.
31
+ */
32
+ export const COMGATE_CARD_HOSTS = Object.freeze(['payments.comgate.cz', 'payments-gcp.comgate.cz', 'sec.comgate.cz', 'sec-gcp.comgate.cz']);
33
+ /** The Fetch.enable globs attachToCdp arms for the card hosts, only while ComGate is served (cdp.ts). */
34
+ export const COMGATE_CARD_PATTERNS = Object.freeze(COMGATE_CARD_HOSTS.map((host) => `*${host}*`));
35
+ // A gateway link, as ComGate writes one: the registry reads ComGate as served when it takes this as a GET entry.
36
+ const COMGATE_SAMPLE_ENTRY = 'https://pay1.comgate.cz/init?id=AAAA-BBBB-CCCC';
37
+ /** Whether this URL is on one of ComGate's card hosts (https, no credentials, any port, a trailing dot or not). */
38
+ export function isComgateCardHost(url) {
39
+ let parsed;
40
+ try {
41
+ parsed = new URL(url);
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ return parsed.protocol === 'https:' && !parsed.username && !parsed.password
47
+ && COMGATE_CARD_HOSTS.includes(parsed.hostname.toLowerCase().replace(/\.$/, ''));
48
+ }
49
+ /** Whether this build's registry serves ComGate's entry: a company Agentcard turned ComGate on for, on a build that declares it. */
50
+ export function servesComgate(vault) {
51
+ return typeof vault?.isCardRequest === 'function' && vault.isCardRequest(COMGATE_SAMPLE_ENTRY, 'GET');
52
+ }
53
+ /**
54
+ * Whether an adapter must hand this request to the pre-claim gates: it is on one of ComGate's card hosts and this
55
+ * build's registry serves ComGate. attachToPlaywright's route predicate asks this, as attachToCdp arms the hosts.
56
+ */
57
+ export function isArmedComgateUrl(vault, url) {
58
+ return isComgateCardHost(url) && servesComgate(vault);
59
+ }
60
+ /**
61
+ * Whether a URL is ComGate's gateway link exactly as ComGate's create answer writes it: https, one of the four
62
+ * gateway hosts in lowercase, the default port, no credentials or fragment, the path /init, and a query of the one
63
+ * `id` parameter holding a transaction id. A string that parses to another spelling is not it.
64
+ */
65
+ export function isComgateEntryUrl(raw) {
66
+ if (typeof raw !== 'string' || raw.length > 256)
67
+ return false;
68
+ let url;
69
+ try {
70
+ url = new URL(raw);
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ if (url.href !== raw || url.protocol !== 'https:' || url.port || url.username || url.password || url.hash)
76
+ return false;
77
+ if (!COMGATE_GATEWAY_HOSTS.includes(url.hostname) || url.pathname !== COMGATE_ENTRY_PATH)
78
+ return false;
79
+ return url.search.startsWith('?id=') && TRANS_ID.test(url.search.slice(4));
80
+ }
@@ -38,7 +38,7 @@ declare function isPreparedSecureAcceptanceRequest(url: any, method: any, body:
38
38
  declare function secureAcceptanceMerchantEntry(profileId: any, merchantOrigin: any, entries?: any): any;
39
39
  declare function secureAcceptanceMerchantRefusal(environment: any, profileId: any, merchantOrigin: any, accessKey: any, entries?: any): "unsupported_environment" | "invalid_profile_id" | "secure_acceptance_merchant_unreviewed" | "secure_acceptance_merchant_pending" | "secure_acceptance_access_key_unreviewed" | "secure_acceptance_merchant_observe" | null;
40
40
  declare function secureAcceptanceCardType(number: any): "001" | "002" | "003" | "004" | null;
41
- declare function secureAcceptanceCardRefusal(environment: any, card: any): "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "invalid_card_number" | "live_host_refuses_documented_test_card" | "card_network_unsupported" | "invalid_expiry" | "invalid_cvn" | null;
41
+ declare function secureAcceptanceCardRefusal(environment: any, card: any): "invalid_card_number" | "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "live_host_refuses_documented_test_card" | "card_network_unsupported" | "invalid_expiry" | "invalid_cvn" | null;
42
42
  declare function isSecureAcceptanceDeviceRequest(templateBody: any, deviceBody: any, environment: any): boolean;
43
43
  declare function secureAcceptanceDeviceRequest(request: any, card: any, options: any): {
44
44
  url: any;
@@ -81,7 +81,7 @@ declare function eprotectMerchantPin(paypageId: any, merchantOrigin: any, pins?:
81
81
  declare function eprotectMerchantRefusal(environment: any, paypageId: any, merchantOrigin: any, pins?: any): "invalid_paypage_id" | "unsupported_environment" | "eprotect_merchant_unreviewed" | null;
82
82
  declare function defaultRandom(bytes: any): void;
83
83
  declare function eprotectEncrypt(text: any, key: any, random?: typeof defaultRandom): string;
84
- declare function eprotectCardRefusal(environment: any, cardNumber: any): "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "invalid_card_number" | "live_host_refuses_documented_test_card" | null;
84
+ declare function eprotectCardRefusal(environment: any, cardNumber: any): "invalid_card_number" | "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "live_host_refuses_documented_test_card" | null;
85
85
  declare function eprotectDeviceRequest(templateUrl: any, card: any, sessionKey: any, random?: typeof defaultRandom): {
86
86
  url: string;
87
87
  method: string;
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 8149714daf5515a2fd3ec90d5aa0c7eb58a66d5ce79c3e3f0ba81c29d2946dc3
3
+ // artifact-sha256: a65199bcbf0b67546130fb4f2c12ba72c8f51a2ff5b4e3054e2bfcc29b06f95d
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);
@@ -25,11 +25,11 @@ declare function hipayUsername(headers: any): string | null;
25
25
  declare function hipayRequestRefusal(request: any): any;
26
26
  declare function isPreparedHipayRequest(url: any, method: any, body: any, environment: any, headers: any): boolean;
27
27
  declare function hipayPinOriginUsable(origin: any): boolean;
28
- declare var HIPAY_MERCHANT_PINS: readonly never[];
29
- declare function hipayOriginPin(merchantOrigin: any, pins?: readonly never[]): null;
30
- declare function hipayPreparationRefusal(environment: any, merchantOrigin: any, pins?: readonly never[]): "unsupported_environment" | "hipay_merchant_unreviewed" | null;
31
- declare function hipayMerchantPin(merchantOrigin: any, username: any, pins?: readonly never[]): null;
32
- declare function hipayMerchantRefusal(environment: any, merchantOrigin: any, username: any, pins?: readonly never[]): "hipay_headers_refused" | "unsupported_environment" | "hipay_merchant_unreviewed" | null;
28
+ declare var HIPAY_MERCHANT_PINS: readonly any[];
29
+ declare function hipayOriginPin(merchantOrigin: any, pins?: readonly any[]): any;
30
+ declare function hipayPreparationRefusal(environment: any, merchantOrigin: any, pins?: readonly any[]): "unsupported_environment" | "hipay_merchant_unreviewed" | null;
31
+ declare function hipayMerchantPin(merchantOrigin: any, username: any, pins?: readonly any[]): any;
32
+ declare function hipayMerchantRefusal(environment: any, merchantOrigin: any, username: any, pins?: readonly any[]): "hipay_headers_refused" | "unsupported_environment" | "hipay_merchant_unreviewed" | null;
33
33
  declare function hipayRefusalMessage(code: any): any;
34
34
  declare function injectHipayCard(body: any, card: any): {
35
35
  body: string;