@agent-cards/sdk 0.23.16 → 0.23.18

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/dist/client.d.ts CHANGED
@@ -249,6 +249,14 @@ export declare const SUPPORTED_REGISTRY_FEATURES: readonly string[];
249
249
  * Wix's token. A second card request from the frame, which Wix's frame sends after a 401
250
250
  * or 403 under a fresh instance, is never answered from the same approval. Served on the
251
251
  * same terms: only to a build that lists it, for a company Agentcard turned Wix on for.
252
+ *
253
+ * `paymongo_checkout_pay`: the card attach PayMongo's hosted checkout sends to its own page
254
+ * URL (checkout.paymongo.com/<session>) as a Next.js Server Action. This build pauses only the
255
+ * page's own card attach and answers it with PayMongo's answer as the API recorded it, under the
256
+ * RSC type the page reads: a paid payment intent, or the step toward PayMongo's 3-D Secure page
257
+ * that the page then runs in the agent's browser. The cardholder's device sends the card through
258
+ * the checkout relay. Served on the same terms: only to a build that lists it, for a company
259
+ * Agentcard turned PayMongo on for.
252
260
  */
253
261
  export declare const SUPPORTED_CAPABILITIES: readonly string[];
254
262
  /**
@@ -1175,6 +1183,10 @@ export declare class CheckoutAuthError extends Error {
1175
1183
  * On PayPal's hosts an order id reads `{order}`:
1176
1184
  * https://www.paypal.com/v2/checkout/orders/{order}/confirm-payment-source.
1177
1185
  * On PayMongo's checkout host the session id reads `{session}`: https://checkout.paymongo.com/{session}.
1186
+ * On GoPay's card frame hosts the card form's token reads `{token}`: https://secure.gopay.com/gp-card-comm/h/{token}.
1187
+ * On komoju.com a session id reads `{session}`: https://komoju.com/api/v1/sessions/{session}/pay.
1188
+ * On Przelewy24's hosts the transaction's token reads `{token}`:
1189
+ * https://secure.przelewy24.pl/trnRequest/{token}.
1178
1190
  * A string that is not a URL keeps the part before any `?` or `#`, with the
1179
1191
  * same segments masked.
1180
1192
  */
package/dist/client.js CHANGED
@@ -233,9 +233,17 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
233
233
  * Wix's token. A second card request from the frame, which Wix's frame sends after a 401
234
234
  * or 403 under a fresh instance, is never answered from the same approval. Served on the
235
235
  * same terms: only to a build that lists it, for a company Agentcard turned Wix on for.
236
+ *
237
+ * `paymongo_checkout_pay`: the card attach PayMongo's hosted checkout sends to its own page
238
+ * URL (checkout.paymongo.com/<session>) as a Next.js Server Action. This build pauses only the
239
+ * page's own card attach and answers it with PayMongo's answer as the API recorded it, under the
240
+ * RSC type the page reads: a paid payment intent, or the step toward PayMongo's 3-D Secure page
241
+ * that the page then runs in the agent's browser. The cardholder's device sends the card through
242
+ * the checkout relay. Served on the same terms: only to a build that lists it, for a company
243
+ * Agentcard turned PayMongo on for.
236
244
  */
237
245
  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,
238
- 'redsys_hosted_payment_page', 'lyra_krypton_payment', 'payfast_card_pay', WIX_PAYMENTS_CAPABILITY];
246
+ 'redsys_hosted_payment_page', 'lyra_krypton_payment', 'payfast_card_pay', WIX_PAYMENTS_CAPABILITY, 'paymongo_checkout_pay'];
239
247
  /**
240
248
  * Processors whose paused request names no amount at all, so the pair the
241
249
  * agent passes is the amount the cardholder approves: authorize() refuses one
@@ -264,13 +272,18 @@ export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CY
264
272
  * and the API holds it to the payment Payfast itself reports. Wix's tokenize request
265
273
  * carries none either: the merchant's page charges Wix's token for its own order, so the
266
274
  * agent's pair, which the prepared checkout carries, is the total the cardholder approves.
275
+ * PayMongo's card attach carries none either: the merchant bound the total, always in
276
+ * Philippine pesos, to the checkout session when it created it, so the agent sends that
277
+ * total, above zero (PAYMONGO_PSP below), and the API holds it to the session PayMongo's
278
+ * own page shows.
267
279
  */
268
280
  const MONERIS_PSP = 'moneris';
269
281
  const PAYFAST_PSP = 'payfast';
270
- const AGENT_AMOUNT_PROCESSORS = [GMO_PSP, PELECARD_PSP, WSPAY_PSP, SECURE_ACCEPTANCE_PSP, MONERIS_PSP, PADDLE_VGS_PSP, PAYFAST_PSP, WIX_PAYMENTS_PSP];
282
+ const PAYMONGO_PSP = 'paymongo';
283
+ 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];
271
284
  /** How AmountRequiredError names a processor. */
272
285
  const PROCESSOR_NAMES = { [GMO_PSP]: 'GMO', [PELECARD_PSP]: 'Pelecard', [WSPAY_PSP]: 'WSPay',
273
- [SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance', [MONERIS_PSP]: 'Moneris', [PADDLE_VGS_PSP]: 'Paddle', [PAYFAST_PSP]: 'Payfast', [WIX_PAYMENTS_PSP]: 'Wix' };
286
+ [SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance', [MONERIS_PSP]: 'Moneris', [PADDLE_VGS_PSP]: 'Paddle', [PAYFAST_PSP]: 'Payfast', [WIX_PAYMENTS_PSP]: 'Wix', [PAYMONGO_PSP]: 'PayMongo' };
274
287
  /**
275
288
  * Processors whose request and answer name no amount at all, so the total the
276
289
  * payment page shows (`pageAmount`) is the one figure that ties the agent's pair
@@ -1000,10 +1013,27 @@ function parseErrorEnvelope(bodyText) {
1000
1013
  }
1001
1014
  return { code: null, details: {} };
1002
1015
  }
1016
+ /**
1017
+ * A slash as the masks below read one: plain, or escaped once or more in either case (%2F, %2f, %252F). A path keeps
1018
+ * an escape as it was written, and the id behind it is the same id, so every slash a mask names reads in any of these
1019
+ * spellings. The slashes right before an id read as a run, and a doubled slash hides nothing either.
1020
+ */
1021
+ const SLASH = '(?:/|%(?:25)*2f)';
1022
+ /** A hyphen inside an id: plain, or escaped once or more in either case (%2D, %252d). */
1023
+ const HYPHEN = '(?:-|%(?:25)*2d)';
1024
+ /**
1025
+ * The masks that find a uuid by its shape take it in any case, with or without its hyphens, each hyphen in any
1026
+ * spelling HYPHEN reads. The pattern reads a percent escape as one unit and keeps it, so the hex digits of an escaped
1027
+ * separator before the id (%2F, %252F, %3D) never start a match and leave the id's last digits showing.
1028
+ */
1029
+ const UUID_OR_ESCAPE = new RegExp(`%(?:25)*[0-9a-f]{2}|[0-9a-f]{8}${HYPHEN}?[0-9a-f]{4}${HYPHEN}?[0-9a-f]{4}${HYPHEN}?[0-9a-f]{4}${HYPHEN}?[0-9a-f]{12}`, 'gi');
1030
+ function maskUuids(path, label) {
1031
+ return path.replace(UUID_OR_ESCAPE, (token) => (token.startsWith('%') ? token : label));
1032
+ }
1003
1033
  const CREDITGUARD_HOST = /(?:^|\.)creditguard\.co\.il\.?$/i;
1034
+ const CREDITGUARD_TXN = new RegExp(`(${SLASH}txn${SLASH}+)[^/]+`, 'gi');
1004
1035
  function maskCreditguardTxId(path) {
1005
- return path.replace(/(\/txn\/)[^/]+/gi, '$1{txId}')
1006
- .replace(/[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}/gi, '{txId}');
1036
+ return maskUuids(path.replace(CREDITGUARD_TXN, '$1{txId}'), '{txId}');
1007
1037
  }
1008
1038
  /**
1009
1039
  * Hosts that put a per-payment secret in the PATH: Monri Components and
@@ -1012,8 +1042,8 @@ function maskCreditguardTxId(path) {
1012
1042
  * public token that secret confirms the payment and reads its status.
1013
1043
  */
1014
1044
  const PATH_SECRET_HOSTS = ['proxy.wspay.biz', 'proxy-test.wspay.biz', 'ipg.monri.com', 'ipgtest.monri.com'];
1015
- /** The segment after a `payment` segment, in any case (the WSPay proxy is IIS) or after an escaped slash. */
1016
- const PATH_SECRET = /(\/payment(?:\/|%2f))[^/]*/gi;
1045
+ /** The segment after a `payment` segment, in any case (the WSPay proxy is IIS) and any spelling of its slashes. */
1046
+ const PATH_SECRET = new RegExp(`(${SLASH}payment${SLASH}+)[^/]*`, 'gi');
1017
1047
  /**
1018
1048
  * Gravy (Gr4vy) gives every merchant hosts of its own under gr4vy.app, and Secure Fields sends the
1019
1049
  * card to /checkout/sessions/<session id>/fields with no auth header, so the session id is that
@@ -1023,10 +1053,9 @@ const PATH_SECRET = /(\/payment(?:\/|%2f))[^/]*/gi;
1023
1053
  * session ids.
1024
1054
  */
1025
1055
  const GRAVY_HOST = /(?:^|\.)gr4vy\.app\.?$/i;
1026
- const GRAVY_SESSION = /(\/checkout\/sessions(?:\/|%2f))[^/]*/gi;
1027
- const GRAVY_SESSION_ID = /[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}/gi;
1056
+ const GRAVY_SESSION = new RegExp(`(${SLASH}checkout${SLASH}sessions${SLASH}+)[^/]*`, 'gi');
1028
1057
  function maskGravySession(path) {
1029
- return path.replace(GRAVY_SESSION, '$1{session}').replace(GRAVY_SESSION_ID, '{session}');
1058
+ return maskUuids(path.replace(GRAVY_SESSION, '$1{session}'), '{session}');
1030
1059
  }
1031
1060
  /**
1032
1061
  * Rapyd's hosted pages send the card to api.rapyd.net (sandboxapi.rapyd.net in test) with no auth
@@ -1037,7 +1066,7 @@ function maskGravySession(path) {
1037
1066
  * after an escaped slash, read {token}.
1038
1067
  */
1039
1068
  const RAPYD_HOST = /(?:^|\.)rapyd\.net\.?$/i;
1040
- const RAPYD_CARD_PAGE = /(\/hosted\/collect\/card(?:\/|%2f))[^/]*/gi;
1069
+ const RAPYD_CARD_PAGE = new RegExp(`(${SLASH}hosted${SLASH}collect${SLASH}card${SLASH}+)[^/]*`, 'gi');
1041
1070
  const RAPYD_PAGE_ID = /(?:checkout|hp_[a-z]+)_[a-z0-9]+/gi;
1042
1071
  function maskRapydToken(path) {
1043
1072
  return path.replace(RAPYD_CARD_PAGE, '$1{token}').replace(RAPYD_PAGE_ID, '{token}');
@@ -1050,7 +1079,7 @@ function maskRapydToken(path) {
1050
1079
  * SetupIntent id stays: confirming one also needs its client_secret, which rides in the body.
1051
1080
  */
1052
1081
  const STRIPE_API_HOST = /^api\.stripe\.com\.?$/i;
1053
- const STRIPE_PAYMENT_PAGE = /(\/payment_pages(?:\/|%2f))[^/]*/gi;
1082
+ const STRIPE_PAYMENT_PAGE = new RegExp(`(${SLASH}payment_pages${SLASH}+)[^/]*`, 'gi');
1054
1083
  function maskStripeSession(path) {
1055
1084
  return path.replace(STRIPE_PAYMENT_PAGE, '$1{session}');
1056
1085
  }
@@ -1061,7 +1090,7 @@ function maskStripeSession(path) {
1061
1090
  * ACI's shape (<32 hex>.<cluster>-vm-tx<nn>) read {checkoutId}.
1062
1091
  */
1063
1092
  const ACI_HOST = /^(?:eu-prod\.|eu-test\.|test\.)?oppwa\.com\.?$/i;
1064
- const ACI_CHECKOUT = /(\/v1\/checkouts(?:\/|%2f))[^/]*/gi;
1093
+ const ACI_CHECKOUT = new RegExp(`(${SLASH}v1${SLASH}checkouts${SLASH}+)[^/]*`, 'gi');
1065
1094
  const ACI_CHECKOUT_ID = /[0-9a-f]{32}\.[a-z0-9]{1,16}-vm-tx[0-9]{1,3}/gi;
1066
1095
  function maskAciCheckout(path) {
1067
1096
  return path.replace(ACI_CHECKOUT, '$1{checkoutId}').replace(ACI_CHECKOUT_ID, '{checkoutId}');
@@ -1071,34 +1100,35 @@ function maskAciCheckout(path) {
1071
1100
  * with no auth header and no CSRF token (payment-core payfast.js): the payment's uuid is the
1072
1101
  * request's only credential, and with it anyone can read that payment page, its amount and its
1073
1102
  * merchant. Every route of the page carries the same uuid, so on every host Payfast owns (payfast.io and
1074
- * payfast.co.za and any name under them) any id of its shape, in any case or after an escaped slash,
1075
- * reads {uuid}.
1103
+ * payfast.co.za and any name under them) any id of its shape, in every spelling maskUuids reads, reads {uuid}.
1076
1104
  */
1077
1105
  const PAYFAST_HOST = /(?:^|\.)payfast\.(?:io|co\.za)\.?$/i;
1078
- const PAYFAST_UUID = /[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}/gi;
1079
1106
  function maskPayfastUuid(path) {
1080
- return path.replace(PAYFAST_UUID, '{uuid}');
1107
+ return maskUuids(path, '{uuid}');
1081
1108
  }
1082
1109
  /**
1083
1110
  * Paddle's checkout frame pays a TokenEx checkout with its own /pay on checkout-service.paddle.com
1084
1111
  * (sandbox-checkout-service in test), and the checkout id in that path is the checkout's only
1085
1112
  * credential there, no cookies (payment-core paddle-tokenex.js): with it, and the card in the body,
1086
1113
  * a payment reaches that checkout. On those hosts the segment between /checkout/ or
1087
- * /transaction-checkout/ and /pay, in any case or after an escaped slash, reads {checkout}.
1114
+ * /transaction-checkout/ and /pay, in any case and any spelling of the slashes around it, reads {checkout}.
1115
+ * The segment ends at the first slash in any spelling, so a long run of them cannot make the pattern try
1116
+ * every way of splitting the run between the segment and the slashes.
1088
1117
  */
1089
1118
  const PADDLE_CHECKOUT_HOST = /^(?:sandbox-)?checkout-service\.paddle\.com\.?$/i;
1090
- const PADDLE_PAY = /(\/(?:checkout|transaction-checkout)(?:\/|%2f))[^/]*(\/pay)/gi;
1119
+ const PADDLE_PAY = new RegExp(`(${SLASH}(?:checkout|transaction-checkout)${SLASH}+)(?:[^/%]|%(?!(?:25)*2f))+(${SLASH}+pay)`, 'gi');
1091
1120
  function maskPaddleCheckout(path) {
1092
1121
  return path.replace(PADDLE_PAY, '$1{checkout}$2');
1093
1122
  }
1094
1123
  /**
1095
1124
  * Lyra's Krypton frame sends its payment to ProcessPayment/2 on the brand's API host with the form
1096
1125
  * token's session id as a `;jsessionid=` path parameter (payment-core lyra.js). With the form token the
1097
- * body carries, that id continues the payment on Lyra's side, so on Lyra's hosts it reads `{session}`,
1098
- * in any case: https://api.systempay.fr/api-payment/V4/Charge/Public/ProcessPayment/2;jsessionid={session}.
1126
+ * body carries, that id continues the payment on Lyra's side, so on Lyra's hosts it reads `{session}`, in any
1127
+ * case and with its `;` or `=` escaped once or more:
1128
+ * https://api.systempay.fr/api-payment/V4/Charge/Public/ProcessPayment/2;jsessionid={session}.
1099
1129
  */
1100
1130
  const LYRA_HOST = /^(?:api\.payzen\.eu|api\.systempay\.fr|api-sogecommerce\.societegenerale\.eu|api\.lyra\.com)\.?$/i;
1101
- const LYRA_SESSION = /;jsessionid=[^/;?#]*/gi;
1131
+ const LYRA_SESSION = /(?:;|%(?:25)*3b)jsessionid(?:=|%(?:25)*3d)[^/;?#]*/gi;
1102
1132
  function maskLyraSession(path) {
1103
1133
  return path.replace(LYRA_SESSION, ';jsessionid={session}');
1104
1134
  }
@@ -1115,6 +1145,33 @@ const PAYMONGO_SESSION = /(?:cs_)?(?:[A-Za-z0-9]|%[0-9A-Fa-f]{2}){24,}/gi;
1115
1145
  function maskPaymongoSession(path) {
1116
1146
  return path.replace(PAYMONGO_SESSION, '{session}');
1117
1147
  }
1148
+ /**
1149
+ * GoPay's card frame posts the card to its own URL,
1150
+ * https://secure.gopay.com/gp-card-comm/h/<hex token>?lang=..&ver=..&SG=<64 hex> (payment-core gopay.js). The
1151
+ * token names that payment's card form, and with the SG, which redactUrl drops with the query, anyone who holds
1152
+ * 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
1153
+ * case or after an escaped slash, reads {token}: https://secure.gopay.com/gp-card-comm/h/{token}.
1154
+ */
1155
+ const GOPAY_CARD_FORM_HOST = /^secure(?:\.sandbox)?\.gopay\.com\.?$/i;
1156
+ const GOPAY_CARD_FORM_TOKEN = new RegExp(`(${SLASH}h${SLASH}+)[^/?#]*`, 'gi');
1157
+ function maskGopayToken(path) {
1158
+ return path.replace(GOPAY_CARD_FORM_TOKEN, '$1{token}');
1159
+ }
1160
+ /**
1161
+ * KOMOJU's Hosted Fields frame pays a session with POST /api/v1/sessions/<id>/pay on komoju.com under
1162
+ * the merchant's publishable key, which is public (payment-core komoju.js): with the session id, anyone
1163
+ * can read that session's amount and buyer email and pay it. On komoju.com the segment after /sessions,
1164
+ * in any case and after any run of slashes, each written plain or escaped once or more, reads {session}:
1165
+ * https://komoju.com/api/v1/sessions/{session}/pay. Then any 25 letters and digits left that end a run read
1166
+ * {session} too, so an id after a dot segment, a backslash or an escape KOMOJU's frame never writes is
1167
+ * masked as well; no other path KOMOJU's card fields use holds such a run.
1168
+ */
1169
+ const KOMOJU_HOST = /^komoju\.com\.?$/i;
1170
+ const KOMOJU_SESSION = new RegExp(`(${SLASH}sessions)(${SLASH}+)[^/]*`, 'gi');
1171
+ const KOMOJU_SESSION_ID = /[a-z0-9]{25}(?![a-z0-9])/gi;
1172
+ function maskKomojuSession(path) {
1173
+ return path.replace(KOMOJU_SESSION, '$1$2{session}').replace(KOMOJU_SESSION_ID, '{session}');
1174
+ }
1118
1175
  /**
1119
1176
  * The processors whose card request carries its own credential in the URL path, with the hosts
1120
1177
  * that send it, the text that names those hosts in a string that is not a URL, and the mask. The
@@ -1124,11 +1181,11 @@ function maskPaymongoSession(path) {
1124
1181
  /**
1125
1182
  * Redsys's hosted payment page names its session in the path of every page and post after the entry
1126
1183
  * (/sis/pagoTarjeta;jsessionid=<id>), and that id is what carries a card post into the session the
1127
- * merchant's signed entry opened. On Redsys's hosts the session id, in any case or escaped, reads
1128
- * {session}. The entry itself carries none.
1184
+ * merchant's signed entry opened. On Redsys's hosts the session id, in any case or escaped once or more,
1185
+ * reads {session}. The entry itself carries none.
1129
1186
  */
1130
1187
  const REDSYS_HOST = /^sis(?:-t)?\.redsys\.es\.?$/i;
1131
- const REDSYS_SESSION = /((?:;|%3b)jsessionid(?:=|%3d))[^/?#;]*/gi;
1188
+ const REDSYS_SESSION = /((?:;|%(?:25)*3b)jsessionid(?:=|%(?:25)*3d))[^/?#;]*/gi;
1132
1189
  function maskRedsysSession(path) {
1133
1190
  return path.replace(REDSYS_SESSION, '$1{session}');
1134
1191
  }
@@ -1139,10 +1196,22 @@ function maskRedsysSession(path) {
1139
1196
  * segment after /orders/, in any case or after an escaped slash, reads {order}.
1140
1197
  */
1141
1198
  const PAYPAL_HOST = /(?:^|\.)paypal\.com\.?$/i;
1142
- const PAYPAL_ORDER = /(\/orders(?:\/|%2f))[^/]*/gi;
1199
+ const PAYPAL_ORDER = new RegExp(`(${SLASH}orders${SLASH}+)[^/]*`, 'gi');
1143
1200
  function maskPaypalOrder(path) {
1144
1201
  return path.replace(PAYPAL_ORDER, '$1{order}');
1145
1202
  }
1203
+ /**
1204
+ * Przelewy24's pay wall names its transaction by one token in the path of every page and post
1205
+ * (/trnRequest/<token>, its method links, /card/p24form/<token>, /trnResult/<token>), and that token
1206
+ * is all a browser needs to open the transaction's pay wall (payment-core processors/przelewy24.js).
1207
+ * On Przelewy24's hosts a token-shaped segment, in any case, after an escaped slash or with its hyphens
1208
+ * escaped, reads {token}.
1209
+ */
1210
+ const PRZELEWY24_HOST = /(?:^|\.)przelewy24\.pl\.?$/i;
1211
+ const PRZELEWY24_TOKEN = new RegExp(`[0-9a-f]{10}${HYPHEN}[0-9a-f]{6}${HYPHEN}[0-9a-f]{6}${HYPHEN}[0-9a-f]{10}`, 'gi');
1212
+ function maskPrzelewy24Token(path) {
1213
+ return path.replace(PRZELEWY24_TOKEN, '{token}');
1214
+ }
1146
1215
  const PATH_CREDENTIALS = [
1147
1216
  { host: CREDITGUARD_HOST, named: /creditguard\.co\.il/i, mask: maskCreditguardTxId },
1148
1217
  { host: GRAVY_HOST, named: /gr4vy\.app/i, mask: maskGravySession },
@@ -1155,6 +1224,9 @@ const PATH_CREDENTIALS = [
1155
1224
  { host: LYRA_HOST, named: /(?:payzen\.eu|systempay\.fr|societegenerale\.eu|lyra\.com)/i, mask: maskLyraSession },
1156
1225
  { host: PAYPAL_HOST, named: /paypal\.com/i, mask: maskPaypalOrder },
1157
1226
  { host: PAYMONGO_CHECKOUT_HOST, named: /checkout\.paymongo\.com/i, mask: maskPaymongoSession },
1227
+ { host: GOPAY_CARD_FORM_HOST, named: /secure(?:\.sandbox)?\.gopay\.com/i, mask: maskGopayToken },
1228
+ { host: KOMOJU_HOST, named: /komoju\.com/i, mask: maskKomojuSession },
1229
+ { host: PRZELEWY24_HOST, named: /przelewy24\.pl/i, mask: maskPrzelewy24Token },
1158
1230
  ];
1159
1231
  /**
1160
1232
  * A URL as it may appear in an error message: origin + path only. A paused
@@ -1178,6 +1250,10 @@ const PATH_CREDENTIALS = [
1178
1250
  * On PayPal's hosts an order id reads `{order}`:
1179
1251
  * https://www.paypal.com/v2/checkout/orders/{order}/confirm-payment-source.
1180
1252
  * On PayMongo's checkout host the session id reads `{session}`: https://checkout.paymongo.com/{session}.
1253
+ * On GoPay's card frame hosts the card form's token reads `{token}`: https://secure.gopay.com/gp-card-comm/h/{token}.
1254
+ * On komoju.com a session id reads `{session}`: https://komoju.com/api/v1/sessions/{session}/pay.
1255
+ * On Przelewy24's hosts the transaction's token reads `{token}`:
1256
+ * https://secure.przelewy24.pl/trnRequest/{token}.
1181
1257
  * A string that is not a URL keeps the part before any `?` or `#`, with the
1182
1258
  * same segments masked.
1183
1259
  */
@@ -2251,10 +2327,10 @@ export class VaultClient {
2251
2327
  // amount_required.
2252
2328
  if (!hasAmount && rec && AGENT_AMOUNT_PROCESSORS.includes(rec.psp))
2253
2329
  throw new AmountRequiredError(rec.psp);
2254
- // A Moneris token is charged later for whatever the merchant's server decides, and a Payfast pay
2255
- // charges the total its payment already holds, so a zero pair would show the cardholder no price
2256
- // at all: it is refused like a missing one.
2257
- if (hasAmount && rec && (rec.psp === MONERIS_PSP || rec.psp === PAYFAST_PSP) && Number(input.amount) <= 0)
2330
+ // A Moneris token is charged later for whatever the merchant's server decides, and a Payfast pay or a
2331
+ // PayMongo attach charges the total its payment or checkout session already holds, so a zero pair
2332
+ // would show the cardholder no price at all: it is refused like a missing one.
2333
+ if (hasAmount && rec && (rec.psp === MONERIS_PSP || rec.psp === PAYFAST_PSP || rec.psp === PAYMONGO_PSP) && Number(input.amount) <= 0)
2258
2334
  throw new AmountRequiredError(rec.psp);
2259
2335
  // Nor is the agent's pair tied to the page by anything but the total the
2260
2336
  // page shows: without it the cardholder could approve one figure while the