@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.
- package/CHANGELOG.md +41 -2
- package/PREFLIGHT.md +2 -0
- package/README.md +143 -5
- package/dist/card-fields.generated.js +984 -57
- package/dist/cdp.js +146 -10
- package/dist/client.d.ts +104 -3
- package/dist/client.js +233 -23
- package/dist/comgate.d.ts +50 -0
- package/dist/comgate.js +80 -0
- package/dist/cybersource-secure-acceptance.generated.d.ts +1 -1
- package/dist/eprotect.generated.d.ts +1 -1
- package/dist/gmo.generated.js +7 -3
- package/dist/hipay.generated.d.ts +5 -5
- package/dist/hipay.generated.js +5 -2
- package/dist/hold.d.ts +1 -1
- package/dist/hold.js +10 -4
- package/dist/hosted-entry.d.ts +4 -0
- package/dist/hosted-entry.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/paddle-tokenex.generated.js +7 -3
- package/dist/payrails.generated.js +7 -3
- package/dist/pre-claim.d.ts +7 -1
- package/dist/pre-claim.js +127 -20
- package/dist/preflight-catalog.json +58 -0
- package/dist/preflight-schemas.json +4 -0
- package/dist/preflight.generated.js +26 -2
- package/dist/primer.generated.js +1027 -100
- package/dist/przelewy24.d.ts +47 -0
- package/dist/przelewy24.js +88 -0
- package/dist/registry.d.ts +6 -5
- package/dist/registry.js +27 -7
- package/dist/shiji-sts.generated.js +7 -3
- package/dist/stripe-checkout.generated.js +621 -12
- package/dist/tokenex-iframe.d.ts +93 -0
- package/dist/tokenex-iframe.generated.d.ts +81 -0
- package/dist/tokenex-iframe.generated.js +403 -0
- package/dist/tokenex-iframe.js +195 -0
- package/dist/transbank.d.ts +45 -0
- package/dist/transbank.js +73 -0
- package/dist/twoc2p.generated.js +7 -3
- package/examples/preflight/kernel-native/inventory.json +1 -1
- 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.
|
|
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
|
|
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
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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).
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
|
2521
|
-
//
|
|
2522
|
-
//
|
|
2523
|
-
|
|
2524
|
-
|
|
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;
|
package/dist/comgate.js
ADDED
|
@@ -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): "
|
|
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): "
|
|
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;
|
package/dist/gmo.generated.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
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
|
-
|
|
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
|
|
29
|
-
declare function hipayOriginPin(merchantOrigin: any, pins?: readonly
|
|
30
|
-
declare function hipayPreparationRefusal(environment: any, merchantOrigin: any, pins?: readonly
|
|
31
|
-
declare function hipayMerchantPin(merchantOrigin: any, username: any, pins?: readonly
|
|
32
|
-
declare function hipayMerchantRefusal(environment: any, merchantOrigin: any, username: any, pins?: readonly
|
|
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;
|