@agent-cards/sdk 0.24.0 → 0.24.1

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 (40) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +61 -4
  3. package/dist/adyen-merchant-hosted.generated.d.ts +1 -1
  4. package/dist/adyen-merchant-hosted.generated.js +128 -35
  5. package/dist/agent-amount.generated.js +1 -1
  6. package/dist/aurus.d.ts +33 -0
  7. package/dist/aurus.js +75 -0
  8. package/dist/builtin-registry.generated.js +1 -1
  9. package/dist/capabilities.generated.js +1 -1
  10. package/dist/card-fields.generated.js +1756 -433
  11. package/dist/cardlink-vpos.d.ts +43 -0
  12. package/dist/cardlink-vpos.js +90 -0
  13. package/dist/cdp.js +13 -0
  14. package/dist/checkout-com.generated.js +5 -1
  15. package/dist/client.d.ts +66 -0
  16. package/dist/client.js +66 -0
  17. package/dist/cybersource-flex.generated.d.ts +39 -1
  18. package/dist/cybersource-flex.generated.js +100 -11
  19. package/dist/eghl.d.ts +40 -0
  20. package/dist/eghl.js +72 -0
  21. package/dist/gmo.generated.js +7 -2
  22. package/dist/hosted-entry.js +2 -0
  23. package/dist/paddle-tokenex.generated.js +7 -2
  24. package/dist/payrails.generated.js +7 -2
  25. package/dist/pre-claim.d.ts +2 -0
  26. package/dist/pre-claim.js +46 -2
  27. package/dist/preflight-catalog.json +154 -1
  28. package/dist/preflight-schemas.json +14 -0
  29. package/dist/preflight.generated.d.ts +5 -0
  30. package/dist/preflight.generated.js +40 -3
  31. package/dist/preparation.d.ts +7 -0
  32. package/dist/preparation.js +21 -0
  33. package/dist/primer.generated.js +1778 -455
  34. package/dist/shiji-sts.generated.js +7 -2
  35. package/dist/stripe-checkout.generated.js +1741 -470
  36. package/dist/substitutions.generated.js +94 -1
  37. package/dist/tap-payments.generated.js +7 -2
  38. package/dist/twoc2p.generated.js +7 -2
  39. package/examples/preflight/kernel-native/inventory.json +1 -1
  40. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 30e71492a40034d2902de57f0000892645e620526fdf00b2072fa1160a7875cb
3
+ // artifact-sha256: f21676a30bdae7f57fc6f082de081b702b2e8cb4d7af10779b1d674cfd256b1d
4
4
  // src/card-number-key.js
5
5
  var CARD_NUMBER_KEY = /^(number|card_number|cardnumber|cardNum|card_num|pan)$/i;
6
6
  // src/json-path.js
@@ -101,8 +101,8 @@ function parseConvergeBody(body) {
101
101
  return parsed;
102
102
  }
103
103
  function convergeAmountCents(value) {
104
- const text9 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
105
- const m = typeof text9 === "string" ? AMOUNT.exec(text9) : null;
104
+ const text10 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
105
+ const m = typeof text10 === "string" ? AMOUNT.exec(text10) : null;
106
106
  if (!m)
107
107
  return null;
108
108
  const cents2 = Number(m[1]) * 100 + Number(((m[2] ?? "") + "00").slice(0, 2));
@@ -357,8 +357,8 @@ var CONTROL = /[\u0000-\u001f\u007f]/;
357
357
  var cardLikeName = (name) => (name.match(/[0-9]/g) ?? []).length >= 12;
358
358
  var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
359
359
  var sameKeys = (value, keys) => {
360
- const own19 = Object.keys(value);
361
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
360
+ const own23 = Object.keys(value);
361
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
362
362
  };
363
363
  var refuse4 = (code) => Object.freeze({ verdict: "refuse", code });
364
364
  var CARD4 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -582,9 +582,9 @@ var K = /* @__PURE__ */ new Uint32Array([
582
582
  3329325298
583
583
  ]);
584
584
  var rotr = (x, n) => x >>> n | x << 32 - n;
585
- function utf8(text9) {
585
+ function utf8(text10) {
586
586
  const out = [];
587
- for (const char of text9) {
587
+ for (const char of text10) {
588
588
  let cp = char.codePointAt(0);
589
589
  if (cp >= 55296 && cp <= 57343)
590
590
  cp = 65533;
@@ -659,6 +659,7 @@ var BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
659
659
  var SHA256_HEX = /^[0-9a-f]{64}$/;
660
660
  var RSA_ALGORITHM = [48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0];
661
661
  var MODULUS_BYTES = [128, 256, 384, 512];
662
+ var SMALL_MODULUS_BYTES = 64;
662
663
  var TYPED_ARRAY = Object.getPrototypeOf(Uint8Array.prototype);
663
664
  var typedArrayName = Object.getOwnPropertyDescriptor(TYPED_ARRAY, Symbol.toStringTag).get;
664
665
  function parseRsaPublicKey(key) {
@@ -667,6 +668,9 @@ function parseRsaPublicKey(key) {
667
668
  const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
668
669
  if (named !== void 0 && named !== 17)
669
670
  throw refuse6("key");
671
+ const sized = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "bits") ? key.bits : void 0;
672
+ if (sized !== void 0 && sized !== 512)
673
+ throw refuse6("key");
670
674
  if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
671
675
  throw refuse6("key");
672
676
  if (typeof pin10 !== "string" || !SHA256_HEX.test(pin10))
@@ -699,7 +703,8 @@ function parseRsaPublicKey(key) {
699
703
  if (exponent.end !== rsa.end)
700
704
  throw refuse6("key");
701
705
  const n = modulus.bytes;
702
- if (!MODULUS_BYTES.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
706
+ const sizes = sized === 512 ? [SMALL_MODULUS_BYTES] : MODULUS_BYTES;
707
+ if (!sizes.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
703
708
  throw refuse6("key");
704
709
  const e = exponent.bytes;
705
710
  const expected = named === 17 ? [17] : [1, 0, 1];
@@ -771,8 +776,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
771
776
  var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
772
777
  var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
773
778
  var sameKeys2 = (value, keys) => {
774
- const own19 = Object.keys(value);
775
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
779
+ const own23 = Object.keys(value);
780
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
776
781
  };
777
782
  var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
778
783
  var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -1261,8 +1266,8 @@ var TEXT_LIMIT = 256;
1261
1266
  var CONTROL4 = /[\u0000-\u001f\u007f]/;
1262
1267
  var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1263
1268
  var sameKeys3 = (value, keys) => {
1264
- const own19 = Object.keys(value);
1265
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
1269
+ const own23 = Object.keys(value);
1270
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
1266
1271
  };
1267
1272
  var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
1268
1273
  var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
@@ -1292,13 +1297,13 @@ function billingFields(value) {
1292
1297
  if (names.length > MAX_FIELDS)
1293
1298
  return false;
1294
1299
  return names.every((name) => {
1295
- const field3 = value[name];
1300
+ const field5 = value[name];
1296
1301
  if (!FIELD_NAME.test(name))
1297
1302
  return false;
1298
- if (!record6(field3))
1299
- return billingText(field3);
1300
- const nested = Object.keys(field3);
1301
- return nested.length <= MAX_NESTED_FIELDS && nested.every((key) => FIELD_NAME.test(key) && billingText(field3[key]));
1303
+ if (!record6(field5))
1304
+ return billingText(field5);
1305
+ const nested = Object.keys(field5);
1306
+ return nested.length <= MAX_NESTED_FIELDS && nested.every((key) => FIELD_NAME.test(key) && billingText(field5[key]));
1302
1307
  });
1303
1308
  }
1304
1309
  function wixPaymentsBodyVerdict(body) {
@@ -1464,8 +1469,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
1464
1469
  var CARD_PAYMENT = "PAYMENT_CARD";
1465
1470
  var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1466
1471
  var sameKeys4 = (value, keys) => {
1467
- const own19 = Object.keys(value);
1468
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
1472
+ const own23 = Object.keys(value);
1473
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
1469
1474
  };
1470
1475
  var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
1471
1476
  var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -1695,8 +1700,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
1695
1700
  var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
1696
1701
  var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1697
1702
  var sameKeys5 = (value, keys) => {
1698
- const own19 = Object.keys(value);
1699
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
1703
+ const own23 = Object.keys(value);
1704
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
1700
1705
  };
1701
1706
  var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
1702
1707
  var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -2112,7 +2117,7 @@ var luhn2 = (digits3) => {
2112
2117
  return sum % 10 === 0;
2113
2118
  };
2114
2119
  var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
2115
- var holdsCardShape = (text9, shape = NETWORK) => (text9.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
2120
+ var holdsCardShape = (text10, shape = NETWORK) => (text10.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
2116
2121
  var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
2117
2122
  var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
2118
2123
  var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -2340,13 +2345,13 @@ var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch
2340
2345
  function typed(value, limit = 256) {
2341
2346
  return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
2342
2347
  }
2343
- function decodeBase64(text9) {
2344
- if (typeof text9 !== "string" || !BASE643.test(text9) || text9.length % 4 !== 0)
2348
+ function decodeBase64(text10) {
2349
+ if (typeof text10 !== "string" || !BASE643.test(text10) || text10.length % 4 !== 0)
2345
2350
  return null;
2346
2351
  let bits = 0;
2347
2352
  let value = 0;
2348
2353
  let out = "";
2349
- for (const ch of text9.replace(/=+$/, "")) {
2354
+ for (const ch of text10.replace(/=+$/, "")) {
2350
2355
  value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
2351
2356
  bits += 6;
2352
2357
  if (bits >= 8) {
@@ -2356,8 +2361,8 @@ function decodeBase64(text9) {
2356
2361
  }
2357
2362
  return out;
2358
2363
  }
2359
- function soundDevice(text9) {
2360
- const json = decodeBase64(text9);
2364
+ function soundDevice(text10) {
2365
+ const json = decodeBase64(text10);
2361
2366
  if (json === null)
2362
2367
  return false;
2363
2368
  let value;
@@ -2475,17 +2480,17 @@ function sumupBodyVerdict(body, url) {
2475
2480
  var SALTED = /* @__PURE__ */ Object.freeze([83, 97, 108, 116, 101, 100, 95, 95]);
2476
2481
  var B64 = /^[A-Za-z0-9+/]+={0,2}$/;
2477
2482
  var FIELD_LIMIT = 1024;
2478
- function decodeCanonical(text9) {
2479
- if (typeof text9 !== "string" || text9.length === 0 || text9.length % 4 !== 0 || !B64.test(text9))
2483
+ function decodeCanonical(text10) {
2484
+ if (typeof text10 !== "string" || text10.length === 0 || text10.length % 4 !== 0 || !B64.test(text10))
2480
2485
  return null;
2481
2486
  let binary;
2482
2487
  try {
2483
- binary = atob(text9);
2488
+ binary = atob(text10);
2484
2489
  }
2485
2490
  catch {
2486
2491
  return null;
2487
2492
  }
2488
- if (btoa(binary) !== text9)
2493
+ if (btoa(binary) !== text10)
2489
2494
  return null;
2490
2495
  return Uint8Array.from(binary, (char) => char.charCodeAt(0));
2491
2496
  }
@@ -2727,8 +2732,8 @@ var TEXT_LIMIT3 = 256;
2727
2732
  var CONTROL7 = /[\u0000-\u001f\u007f]/;
2728
2733
  var record13 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2729
2734
  var sameKeys7 = (value, keys) => {
2730
- const own19 = Object.keys(value);
2731
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
2735
+ const own23 = Object.keys(value);
2736
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
2732
2737
  };
2733
2738
  var plainText3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT3 && !CONTROL7.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
2734
2739
  var refuse19 = (code) => Object.freeze({ verdict: "refuse", code });
@@ -3424,7 +3429,7 @@ var YEAR11 = /^[0-9]{2}$/;
3424
3429
  var CODE4 = /^[0-9]{3}$/;
3425
3430
  var NAME_LIMIT3 = 100;
3426
3431
  var NAME_WORD = /[a-z]+/gi;
3427
- var printable2 = (text9) => [...text9].every((character) => {
3432
+ var printable2 = (text10) => [...text10].every((character) => {
3428
3433
  const point = character.codePointAt(0);
3429
3434
  return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
3430
3435
  });
@@ -3433,8 +3438,8 @@ var HOSTNAME = /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](
3433
3438
  var PUBLISHABLE_KEY = /^[A-Za-z0-9]{16,64}$/;
3434
3439
  var record18 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
3435
3440
  var sameKeys8 = (value, keys) => {
3436
- const own19 = Object.keys(value);
3437
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
3441
+ const own23 = Object.keys(value);
3442
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
3438
3443
  };
3439
3444
  var refuse24 = (code) => Object.freeze({ verdict: "refuse", code });
3440
3445
  var CARD23 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -3804,7 +3809,7 @@ var POSTAL_CODE3 = /^[A-Za-z0-9_]{0,16}$/;
3804
3809
  var COUNTRY4 = /^[A-Z]{2}$/;
3805
3810
  var TEXT_LIMIT7 = 256;
3806
3811
  var CONTROL10 = /[\u0000-\u001f\u007f]/;
3807
- var cardLike2 = (text9) => (text9.match(/[0-9]/g) ?? []).length >= 12;
3812
+ var cardLike2 = (text10) => (text10.match(/[0-9]/g) ?? []).length >= 12;
3808
3813
  var text5 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT7 && !CONTROL10.test(value) && !cardLike2(value);
3809
3814
  var record21 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
3810
3815
  var own5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
@@ -4125,11 +4130,11 @@ var LONG_TEXT_LIMIT = BODY_LIMIT25;
4125
4130
  var record22 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
4126
4131
  var owns6 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
4127
4132
  var sameKeys9 = (value, keys) => {
4128
- const own19 = Object.keys(value);
4129
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
4133
+ const own23 = Object.keys(value);
4134
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
4130
4135
  };
4131
4136
  var exact3 = (pattern, value) => typeof value === "string" && pattern.test(value);
4132
- var printable3 = (text9) => [...text9].every((character) => {
4137
+ var printable3 = (text10) => [...text10].every((character) => {
4133
4138
  const point = character.codePointAt(0);
4134
4139
  return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
4135
4140
  });
@@ -4202,7 +4207,7 @@ function companyStore(value) {
4202
4207
  return record22(value) && sameKeys9(value, COMPANY_KEYS) && whole(value.CompanyNumber, 1) && COMPANY_KEYS.slice(1).every((key) => key.startsWith("Show") ? flag(value[key]) : pageText(value[key]));
4203
4208
  }
4204
4209
  var SUM_TEXT = /^(?:0*[1-9][0-9]*(?:\.[0-9]+)?|0+\.[0-9]*[1-9][0-9]*)$/;
4205
- var sumText = (text9, sum) => text9 === null || typeof text9 === "string" && SUM_TEXT.test(text9) && Number.parseFloat(text9) === sum;
4210
+ var sumText = (text10, sum) => text10 === null || typeof text10 === "string" && SUM_TEXT.test(text10) && Number.parseFloat(text10) === sum;
4206
4211
  function chosenProduct(value) {
4207
4212
  return record22(value) && sameKeys9(value, PRODUCT_KEYS) && whole(value.MinQuantity) && whole(value.MaxQuantity) && whole(value.JumpsInQuantity) && value.SelectedBuyQuantity === 1 && Array.isArray(value.QuantityOptions) && value.QuantityOptions.length === 0 && pageText(value.Comments) && flag(value.IsManualSum) && Array.isArray(value.PaymentsOptions) && flag(value.IsCouponActive) && typeof value.ManualPrice === "number" && sumText(value.ManualPriceTxt, value.ManualPrice) && flag(value.IsVatFree) && Array.isArray(value.SpecialPrices) && (value.PreConfiguredPrice === null || typeof value.PreConfiguredPrice === "number") && flag(value.IsPreSelected) && typeof value.CurrentInventory === "number" && flag(value.CheckInventory) && exact3(PRODUCT_ID, value.uid) && pageText(value.imageUrl) && typeof value.name === "string" && pageText(value.name) && pageText(value.description) && typeof value.BasePrice === "number" && typeof value.PriceBeforeDiscount === "number" && whole(value.BaseISOCurrency) && typeof value.PriceToShow === "number" && typeof value.PriceBeforeDiscountToShow === "number" && flag(value.IsCurrent);
4208
4213
  }
@@ -4433,7 +4438,7 @@ var sameKeys10 = (value, keys) => {
4433
4438
  };
4434
4439
  var refuse28 = (code) => Object.freeze({ verdict: "refuse", code });
4435
4440
  var CARD27 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
4436
- var printable4 = (text9) => [...text9].every((character) => {
4441
+ var printable4 = (text10) => [...text10].every((character) => {
4437
4442
  const point = character.codePointAt(0);
4438
4443
  return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
4439
4444
  });
@@ -4525,8 +4530,8 @@ var POSTAL_CODE4 = /^[A-Za-z0-9 -]{0,16}$/;
4525
4530
  var CIPHERTEXT_B64 = /^[A-Za-z0-9+/]{341}[AQgw]==$/;
4526
4531
  var record24 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
4527
4532
  var sameKeys11 = (value, keys) => {
4528
- const own19 = Object.keys(value);
4529
- return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
4533
+ const own23 = Object.keys(value);
4534
+ return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
4530
4535
  };
4531
4536
  var refuse29 = (code) => Object.freeze({ verdict: "refuse", code });
4532
4537
  var failed = (code) => (
@@ -4995,20 +5000,20 @@ function readBody18(body) {
4995
5000
  function amountValue(value) {
4996
5001
  if (typeof value === "number" && !Number.isFinite(value))
4997
5002
  return false;
4998
- const text9 = typeof value === "number" ? String(value) : value;
4999
- if (typeof text9 !== "string" || !AMOUNT_TEXT.test(text9))
5003
+ const text10 = typeof value === "number" ? String(value) : value;
5004
+ if (typeof text10 !== "string" || !AMOUNT_TEXT.test(text10))
5000
5005
  return false;
5001
- const amount2 = Number(text9);
5006
+ const amount2 = Number(text10);
5002
5007
  return amount2 > 0 && amount2 <= AMOUNT_LIMIT3;
5003
5008
  }
5004
5009
  function billingDetails(value) {
5005
5010
  if (!record27(value) || !inOrder5(value, BILLING_KEYS))
5006
5011
  return false;
5007
5012
  return Object.keys(value).every((key) => {
5008
- const field3 = value[key];
5013
+ const field5 = value[key];
5009
5014
  if (key !== "address")
5010
- return key === "mobile_number" || key === "phone_number" ? typeof field3 === "string" && PHONE4.test(field3) : plainText6(field3);
5011
- return record27(field3) && inOrder5(field3, ADDRESS_KEYS5) && Object.keys(field3).every((name) => plainText6(field3[name]));
5015
+ return key === "mobile_number" || key === "phone_number" ? typeof field5 === "string" && PHONE4.test(field5) : plainText6(field5);
5016
+ return record27(field5) && inOrder5(field5, ADDRESS_KEYS5) && Object.keys(field5).every((name) => plainText6(field5[name]));
5012
5017
  });
5013
5018
  }
5014
5019
  function cardData(value) {
@@ -5196,10 +5201,10 @@ function isPaymobPayUrl(url) {
5196
5201
  var BASE645 = /^[A-Za-z0-9+/]+={0,2}$/;
5197
5202
  var BASE64URL = /^[A-Za-z0-9_-]+$/;
5198
5203
  var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
5199
- function decodeBase642(text9, url) {
5200
- if (typeof text9 !== "string" || text9 === "")
5204
+ function decodeBase642(text10, url) {
5205
+ if (typeof text10 !== "string" || text10 === "")
5201
5206
  return null;
5202
- let body = text9;
5207
+ let body = text10;
5203
5208
  if (url) {
5204
5209
  if (!BASE64URL.test(body) || body.length % 4 === 1)
5205
5210
  return null;
@@ -5232,15 +5237,15 @@ function decodeBase642(text9, url) {
5232
5237
  function jsonOf(bytes) {
5233
5238
  if (!bytes)
5234
5239
  return null;
5235
- let text9;
5240
+ let text10;
5236
5241
  try {
5237
- text9 = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
5242
+ text10 = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
5238
5243
  }
5239
5244
  catch {
5240
5245
  return null;
5241
5246
  }
5242
5247
  try {
5243
- const value = JSON.parse(text9);
5248
+ const value = JSON.parse(text10);
5244
5249
  return record29(value) ? value : null;
5245
5250
  }
5246
5251
  catch {
@@ -5341,7 +5346,7 @@ function namesCardValue3(parsed) {
5341
5346
  return false;
5342
5347
  }
5343
5348
  function addressBlock(value) {
5344
- return record29(value) && Object.keys(value).length <= 32 && Object.entries(value).every(([key, text9]) => FIELD.test(key) && !CARD_MEMBER4.test(key) && (text9 === null || typeof text9 === "string" && TEXT3.test(text9)));
5349
+ return record29(value) && Object.keys(value).length <= 32 && Object.entries(value).every(([key, text10]) => FIELD.test(key) && !CARD_MEMBER4.test(key) && (text10 === null || typeof text10 === "string" && TEXT3.test(text10)));
5345
5350
  }
5346
5351
  function judgeCardPayment(parsed) {
5347
5352
  const source = parsed.source;
@@ -5839,8 +5844,8 @@ function cardNamed2(key) {
5839
5844
  const phrase = words.join(" ");
5840
5845
  return words.some((word) => CARD_WORDS.includes(word)) || ["security code", "codigo seguridad", "codigo verificacion"].some((said) => phrase.includes(said));
5841
5846
  }
5842
- function carriesCardNumber(text9) {
5843
- for (const [run] of text9.matchAll(/[0-9]+(?:[ ._/,-][0-9]+)*/g)) {
5847
+ function carriesCardNumber(text10) {
5848
+ for (const [run] of text10.matchAll(/[0-9]+(?:[ ._/,-][0-9]+)*/g)) {
5844
5849
  const groups = run.split(/[ ._/,-]/);
5845
5850
  for (let first = 0; first < groups.length; first += 1) {
5846
5851
  let digits3 = "";
@@ -5853,17 +5858,17 @@ function carriesCardNumber(text9) {
5853
5858
  }
5854
5859
  return false;
5855
5860
  }
5856
- var wholeCardNumber = (text9) => /^[2-6][0-9]{12,18}$/.test(text9) && luhn7(text9);
5861
+ var wholeCardNumber = (text10) => /^[2-6][0-9]{12,18}$/.test(text10) && luhn7(text10);
5857
5862
  function membersRefusal(root) {
5858
5863
  const pending = [[root, ""]];
5859
5864
  while (pending.length > 0) {
5860
5865
  const [node, path] = pending.pop();
5861
- const own19 = path === "" ? TRANSACTION_MEMBERS : owns7(RECORD_MEMBERS, path) ? RECORD_MEMBERS[path] : null;
5866
+ const own23 = path === "" ? TRANSACTION_MEMBERS : owns7(RECORD_MEMBERS, path) ? RECORD_MEMBERS[path] : null;
5862
5867
  for (const [key, child] of Object.entries(node)) {
5863
5868
  const at = Array.isArray(node) ? path : path === "" ? key : `${path}.${key}`;
5864
5869
  if (at === "checkoutCreditCard")
5865
5870
  continue;
5866
- if (own19 !== null && !own19.includes(key))
5871
+ if (own23 !== null && !own23.includes(key))
5867
5872
  return true;
5868
5873
  if (TEXT_RECORDS.includes(path) && child !== null && typeof child !== "string")
5869
5874
  return true;
@@ -6144,6 +6149,92 @@ function registered(spec, parts) {
6144
6149
  function registerProcessor(spec) {
6145
6150
  return registered(spec, PARTS);
6146
6151
  }
6152
+ // src/processors/aurus.js
6153
+ var AURUS_PSP = "aurus";
6154
+ var AURUS_OPERATION = "aurus.card_request";
6155
+ var AURUS_FRAME_HOST = /^pecst[0-9]{2}\.aurusepay\.com$/;
6156
+ var AURUS_TOKEN_PATH = "/storeservices/ecom/oneTimeToken";
6157
+ var AURUS_PARTS = /* @__PURE__ */ Object.freeze(["Param", "formFactorId", "txnDateTime", "encryptionFlag", "sha256Flag", "hmacAuthData", "payload"]);
6158
+ var URL_LIMIT14 = 256;
6159
+ var BODY_LIMIT35 = 32768;
6160
+ var SERVER = /^es[0-9]{2}\.auruspay\.com$/;
6161
+ var HEX = /^[0-9A-Fa-f]{2,8192}$/;
6162
+ var FORM_FACTOR = /^[0-9]{1,16}$/;
6163
+ var DATE_TIME = /^[0-9]{14}$/;
6164
+ var FRAMED = /^STX[0-9]{1,6}\[FS\][0-9A-Fa-f]{2,16384}\[FS\]7[Bb][0-9A-Fa-f]{0,24576}7[Dd]ETX$/;
6165
+ var refuse37 = (code) => Object.freeze({ verdict: "refuse", code });
6166
+ var CARD36 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6167
+ function aurusTokenUrl(url) {
6168
+ if (typeof url !== "string" || url.length > URL_LIMIT14 || url.includes("#"))
6169
+ return null;
6170
+ let parsed;
6171
+ try {
6172
+ parsed = new URL(url);
6173
+ }
6174
+ catch {
6175
+ return null;
6176
+ }
6177
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !AURUS_FRAME_HOST.test(parsed.hostname) || parsed.pathname !== AURUS_TOKEN_PATH)
6178
+ return null;
6179
+ const query = parsed.search.startsWith("?") ? parsed.search.slice(1).split("&") : [];
6180
+ if (query.length !== 2)
6181
+ return null;
6182
+ const [d1, d2] = query.map((pair) => pair.split("="));
6183
+ if (d1.length !== 2 || d2.length !== 2 || d1[0] !== "d1" || d2[0] !== "d2" || !SERVER.test(d1[1]) || !SERVER.test(d2[1]))
6184
+ return null;
6185
+ return Object.freeze({ host: parsed.hostname });
6186
+ }
6187
+ var isAurusTokenUrl = (url) => aurusTokenUrl(url) !== null;
6188
+ function readBody21(body) {
6189
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT35)
6190
+ return null;
6191
+ const pairs = body.split("&");
6192
+ if (pairs.length !== AURUS_PARTS.length)
6193
+ return null;
6194
+ const value = {};
6195
+ for (const [at, pair] of pairs.entries()) {
6196
+ const cut = pair.indexOf("=");
6197
+ if (cut < 0 || pair.slice(0, cut) !== AURUS_PARTS[at])
6198
+ return null;
6199
+ value[AURUS_PARTS[at]] = pair.slice(cut + 1);
6200
+ }
6201
+ if (!HEX.test(value.Param) || !FORM_FACTOR.test(value.formFactorId) || !DATE_TIME.test(value.txnDateTime) || value.encryptionFlag !== "00" || value.sha256Flag !== "1" || !FRAMED.test(value.hmacAuthData) || !FRAMED.test(value.payload))
6202
+ return null;
6203
+ return value;
6204
+ }
6205
+ function aurusBodyVerdict(body) {
6206
+ return readBody21(body) === null ? refuse37("aurus_body_unsupported") : CARD36;
6207
+ }
6208
+ var aurus_default = /* @__PURE__ */ registerProcessor({
6209
+ psp: AURUS_PSP,
6210
+ definitions: [
6211
+ {
6212
+ psp: "aurus",
6213
+ // The frame's card request, as the header above reads it. No sandbox host is known: Aurus's test instances were
6214
+ // not read, so none is listed and no environment is pinned.
6215
+ // Ships dark: served only to a client that declares `aurus_one_time_token`, and only for a company the backend's
6216
+ // processor gate turns Aurus on for. `(?![\w/.%-])` ends the path for a consumer that tests `match` unanchored.
6217
+ capability: "aurus_one_time_token",
6218
+ match: "pecst[0-9]{2}\\.aurusepay\\.com/storeservices/ecom/oneTimeToken(?![\\w/.%-])",
6219
+ hosts: ["^pecst[0-9]{2}\\.aurusepay\\.com$"],
6220
+ encoding: "form",
6221
+ // The frame's XHR marker. Origin, Referer and cookies never ride.
6222
+ passthroughHeaders: ["^x-requested-with$"]
6223
+ }
6224
+ ],
6225
+ // Only the cardholder's device would send this card, after a person approves; no reviewed list names aurus.
6226
+ refusedOperations: [AURUS_OPERATION],
6227
+ // The frame mints a one-time token and reads nothing: the store's server charges it with its own credentials.
6228
+ settlementReadback: {
6229
+ answer: "none",
6230
+ reason: "tokenization_credential_cannot_read_charges",
6231
+ note: "The tokenization credential cannot read a charge; the shop charges the token later with its own credentials.",
6232
+ source: "https://www.oreillyauto.com/checkout (Aurus's ecom iframe, read 2026-10-31)"
6233
+ },
6234
+ exactUrl: isAurusTokenUrl,
6235
+ bodyGate: (url, body) => url !== void 0 && !isAurusTokenUrl(url) ? refuse37("aurus_url_refused") : aurusBodyVerdict(body),
6236
+ limitations: ["The card frame seals the card in the page under a public key its own script carries; the cardholder's device does not seal for Aurus yet, so a held request opens no approval that pays."]
6237
+ });
6147
6238
  // src/processors/bluesnap.js
6148
6239
  var BLUESNAP_PSP = "bluesnap";
6149
6240
  var BLUESNAP_OPERATION = "bluesnap.card_request";
@@ -6151,7 +6242,7 @@ var BLUESNAP_HOSTS = /* @__PURE__ */ Object.freeze({ 1: "ws1.bluesnap.com", 2: "
6151
6242
  var BLUESNAP_SANDBOX_HOST = "sandpay.bluesnap.com";
6152
6243
  var BLUESNAP_CARD_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "ccNumber", "expDate"]);
6153
6244
  var BLUESNAP_LEG_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "expDate"]);
6154
- var BODY_LIMIT35 = 1024;
6245
+ var BODY_LIMIT36 = 1024;
6155
6246
  var TOKEN_URL2 = /^https:\/\/(ws1|ws2|sandpay)\.bluesnap\.com\/services\/2\/payment-fields-tokens\/([0-9a-f]{64}_[12]?)$/;
6156
6247
  var CARD_NUMBER18 = /^[0-9]{12,19}$/;
6157
6248
  var SECURITY_CODE22 = /^[0-9]{3,4}$/;
@@ -6159,8 +6250,8 @@ var EXPIRY3 = /^(?:0[1-9]|1[0-2])\/20[0-9]{2}$/;
6159
6250
  var SAVED_CARD_KEYS2 = ["last4Digits", "lastFourDigits", "ccType"];
6160
6251
  var record32 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
6161
6252
  var own12 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
6162
- var refuse37 = (code) => Object.freeze({ verdict: "refuse", code });
6163
- var CARD36 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6253
+ var refuse38 = (code) => Object.freeze({ verdict: "refuse", code });
6254
+ var CARD37 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6164
6255
  var LEG = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
6165
6256
  function bluesnapTokenUrl(url) {
6166
6257
  const match = typeof url === "string" ? TOKEN_URL2.exec(url) : null;
@@ -6172,8 +6263,8 @@ function bluesnapTokenUrl(url) {
6172
6263
  function isBluesnapTokenUrl(url) {
6173
6264
  return bluesnapTokenUrl(url) !== null;
6174
6265
  }
6175
- function readBody21(body) {
6176
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT35)
6266
+ function readBody22(body) {
6267
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT36)
6177
6268
  return null;
6178
6269
  try {
6179
6270
  const value = JSON.parse(body);
@@ -6184,18 +6275,18 @@ function readBody21(body) {
6184
6275
  }
6185
6276
  }
6186
6277
  function bluesnapBodyVerdict(body) {
6187
- const value = readBody21(body);
6278
+ const value = readBody22(body);
6188
6279
  if (value === null)
6189
- return refuse37("bluesnap_body_unsupported");
6280
+ return refuse38("bluesnap_body_unsupported");
6190
6281
  const keys = Object.keys(value);
6191
6282
  if (keys.some((key) => SAVED_CARD_KEYS2.includes(key)))
6192
- return refuse37(own12(value, "ccNumber") ? "bluesnap_body_unsupported" : "bluesnap_saved_card");
6283
+ return refuse38(own12(value, "ccNumber") ? "bluesnap_body_unsupported" : "bluesnap_saved_card");
6193
6284
  if (keys.length === 0 || keys.some((key, i) => !BLUESNAP_CARD_KEYS.includes(key) || i > 0 && BLUESNAP_CARD_KEYS.indexOf(keys[i - 1]) >= BLUESNAP_CARD_KEYS.indexOf(key))) {
6194
- return refuse37("bluesnap_body_unsupported");
6285
+ return refuse38("bluesnap_body_unsupported");
6195
6286
  }
6196
6287
  if (own12(value, "ccNumber") && !(typeof value.ccNumber === "string" && CARD_NUMBER18.test(value.ccNumber)) || own12(value, "cvv") && !(typeof value.cvv === "string" && SECURITY_CODE22.test(value.cvv)) || own12(value, "expDate") && !(typeof value.expDate === "string" && EXPIRY3.test(value.expDate)))
6197
- return refuse37("bluesnap_body_unsupported");
6198
- return own12(value, "ccNumber") ? CARD36 : LEG;
6288
+ return refuse38("bluesnap_body_unsupported");
6289
+ return own12(value, "ccNumber") ? CARD37 : LEG;
6199
6290
  }
6200
6291
  var bluesnap_default = /* @__PURE__ */ registerProcessor({
6201
6292
  psp: BLUESNAP_PSP,
@@ -6229,100 +6320,1016 @@ var bluesnap_default = /* @__PURE__ */ registerProcessor({
6229
6320
  exactUrl: isBluesnapTokenUrl,
6230
6321
  bodyGate: (url, body) => url !== void 0 && !isBluesnapTokenUrl(url) ? { verdict: "refuse", code: "bluesnap_url_refused" } : bluesnapBodyVerdict(body)
6231
6322
  });
6232
- // src/processors/iyzico.js
6233
- var IYZICO_PSP = "iyzico";
6234
- var IYZICO_OPERATION = "iyzico.card_request";
6235
- var PATHS = ["/payment/iyzipos/checkoutform/auth/ecom", "/payment/iyzipos/checkoutform/initialize3ds/ecom"];
6236
- var IYZICO_CARD_URLS = /* @__PURE__ */ Object.freeze(["https://api.iyzipay.com", "https://sandbox-api.iyzipay.com"].flatMap((origin) => PATHS.map((path) => `${origin}${path}`)));
6237
- var IYZICO_BODY_KEYS = /* @__PURE__ */ Object.freeze([
6238
- "installment",
6239
- "paidPrice",
6240
- "paymentChannel",
6241
- "paymentCard",
6242
- "buyerProtected",
6243
- "gsmNumber",
6244
- "dccPayment",
6245
- "dccQueryRrn",
6246
- "pwiMetadata"
6323
+ // src/processors/ekashu.js
6324
+ var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
6325
+ var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
6326
+ var EKASHU_SIGNED_FIELDS = Object.freeze([
6327
+ "ekashu_3d_secure_verify",
6328
+ "ekashu_amount",
6329
+ "ekashu_amount_format",
6330
+ "ekashu_auto_confirm",
6331
+ "ekashu_callback_failure_url",
6332
+ "ekashu_callback_include_post",
6333
+ "ekashu_callback_success_url",
6334
+ "ekashu_card_address_editable",
6335
+ "ekashu_card_address_required",
6336
+ "ekashu_card_address_verify",
6337
+ "ekashu_card_email_address_mandatory",
6338
+ "ekashu_card_phone_number_mandatory",
6339
+ "ekashu_card_title_mandatory",
6340
+ "ekashu_card_zip_code_verify",
6341
+ "ekashu_currency",
6342
+ "ekashu_delivery_address_editable",
6343
+ "ekashu_delivery_address_required",
6344
+ "ekashu_delivery_email_address_mandatory",
6345
+ "ekashu_delivery_phone_number_mandatory",
6346
+ "ekashu_delivery_title_mandatory",
6347
+ "ekashu_description",
6348
+ "ekashu_device",
6349
+ "ekashu_duplicate_check",
6350
+ "ekashu_duplicate_minutes",
6351
+ "ekashu_failure_return_text",
6352
+ "ekashu_failure_url",
6353
+ "ekashu_hash_code_format",
6354
+ "ekashu_hash_code_type",
6355
+ "ekashu_hash_code_version",
6356
+ "ekashu_include_post",
6357
+ "ekashu_invoice_address_editable",
6358
+ "ekashu_invoice_address_required",
6359
+ "ekashu_invoice_email_address_mandatory",
6360
+ "ekashu_invoice_phone_number_mandatory",
6361
+ "ekashu_invoice_title_mandatory",
6362
+ "ekashu_locale",
6363
+ "ekashu_payment_methods",
6364
+ "ekashu_reference",
6365
+ "ekashu_request_type",
6366
+ "ekashu_return_text",
6367
+ "ekashu_seller_address",
6368
+ "ekashu_seller_email_address",
6369
+ "ekashu_seller_id",
6370
+ "ekashu_seller_key",
6371
+ "ekashu_seller_name",
6372
+ "ekashu_shortcut_icon",
6373
+ "ekashu_style_sheet",
6374
+ "ekashu_success_url",
6375
+ "ekashu_title",
6376
+ "ekashu_verification_value_mask",
6377
+ "ekashu_verification_value_verify",
6378
+ "ekashu_viewport"
6247
6379
  ]);
6248
- var IYZICO_CARD_KEYS = /* @__PURE__ */ Object.freeze([
6249
- "cardNumber",
6250
- "cardHolderName",
6251
- "expireYear",
6252
- "expireMonth",
6253
- "cvc",
6254
- "registerConsumerCard",
6255
- "registerCard"
6380
+ var REQUIRED = Object.freeze([
6381
+ "ekashu_seller_id",
6382
+ "ekashu_seller_key",
6383
+ "ekashu_amount",
6384
+ "ekashu_currency",
6385
+ "ekashu_reference",
6386
+ "ekashu_hash_code",
6387
+ "ekashu_hash_code_type",
6388
+ "ekashu_hash_code_version",
6389
+ "ekashu_success_url",
6390
+ "ekashu_failure_url",
6391
+ "ekashu_callback_success_url"
6256
6392
  ]);
6257
- var BODY_LIMIT36 = 4096;
6258
- var CARD_NUMBER19 = /^[0-9]{12,19}$/;
6259
- var SECURITY_CODE23 = /^[0-9]{3,4}$/;
6260
- var MONTH19 = /^(?:0?[1-9]|1[0-2])$/;
6261
- var YEAR20 = /^(?:[0-9]{2}|20[0-9]{2})$/;
6262
- var PRICE = /^([1-9][0-9]{0,8}|0)(?:\.([0-9]{1,2}))?$/;
6263
- var CHANNELS = /* @__PURE__ */ Object.freeze(["WEB", "MOBILE_WEB", "MOBILE_IOS", "MOBILE_ANDROID", "MOBILE_WINDOWS"]);
6264
- var METADATA_KEYS3 = /* @__PURE__ */ Object.freeze(["lightRedesign", "pwiGrowthActionDisabled"]);
6265
- var FLAG = /^[A-Za-z_]{1,16}$/;
6266
- var HOLDER5 = /^[^\x00-\x1f\x7f0-9]{3,100}$/u;
6267
- var record33 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
6268
- var own13 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
6269
- var inOrder6 = (value, keys) => {
6270
- let at = 0;
6271
- for (const name of Object.keys(value)) {
6272
- while (at < keys.length && keys[at] !== name)
6273
- at += 1;
6274
- if (at === keys.length)
6275
- return false;
6276
- at += 1;
6393
+ var CARD_KEYS16 = Object.freeze([
6394
+ "ekashu_card_number",
6395
+ "ekashu_expires_end_month",
6396
+ "ekashu_expires_end_year",
6397
+ "ekashu_verification_value",
6398
+ "ekashu_valid_from_month",
6399
+ "ekashu_valid_from_year",
6400
+ "ekashu_issue_number"
6401
+ ]);
6402
+ var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
6403
+ var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
6404
+ var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
6405
+ var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
6406
+ var MAX_ENTRY = 16 * 1024;
6407
+ var MAX_PAGE = 256 * 1024;
6408
+ var EKASHU_SELLERS = Object.freeze([
6409
+ Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
6410
+ ]);
6411
+ var CARD_FIELDS = Object.freeze({
6412
+ number: "ekashu_card_number",
6413
+ month: "ekashu_expires_end_month",
6414
+ year: "ekashu_expires_end_year",
6415
+ cvc: "ekashu_verification_value"
6416
+ });
6417
+ var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
6418
+ var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
6419
+ var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
6420
+ // src/processors/redsys.js
6421
+ var REDSYS_HOSTS = Object.freeze(["sis.redsys.es"]);
6422
+ var REDSYS_ENTRY_PATHS = Object.freeze(["/sis/realizarPago", "/sis/realizarPago/utf-8"]);
6423
+ var REDSYS_MERCHANTS = Object.freeze([]);
6424
+ var MAX_ENTRY2 = 16 * 1024;
6425
+ var MAX_PARAMETERS = 8 * 1024;
6426
+ var FORM_KEY = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
6427
+ var ENTRY_KEYS = Object.freeze(["Ds_SignatureVersion", "Ds_MerchantParameters", "Ds_Signature"]);
6428
+ var REQUIRED2 = Object.freeze([
6429
+ "DS_MERCHANT_AMOUNT",
6430
+ "DS_MERCHANT_CURRENCY",
6431
+ "DS_MERCHANT_MERCHANTCODE",
6432
+ "DS_MERCHANT_ORDER",
6433
+ "DS_MERCHANT_TERMINAL",
6434
+ "DS_MERCHANT_TRANSACTIONTYPE",
6435
+ "DS_MERCHANT_MERCHANTURL",
6436
+ "DS_MERCHANT_URLOK",
6437
+ "DS_MERCHANT_URLKO"
6438
+ ]);
6439
+ var STORED = Object.freeze([
6440
+ "DS_MERCHANT_IDENTIFIER",
6441
+ "DS_MERCHANT_GROUP",
6442
+ "DS_MERCHANT_COF_INI",
6443
+ "DS_MERCHANT_COF_TYPE",
6444
+ "DS_MERCHANT_COF_TXNID"
6445
+ ]);
6446
+ var SPECIAL = Object.freeze([
6447
+ "DS_MERCHANT_DIRECTPAYMENT",
6448
+ "DS_MERCHANT_SUMTOTAL",
6449
+ "DS_MERCHANT_DATEFRECUENCY",
6450
+ "DS_MERCHANT_CHARGEEXPIRYDATE",
6451
+ "DS_MERCHANT_IDOPER"
6452
+ ]);
6453
+ var CARD_PARAMETERS = Object.freeze(["DS_MERCHANT_PAN", "DS_MERCHANT_EXPIRYDATE", "DS_MERCHANT_CVV2"]);
6454
+ var CURRENCIES = Object.freeze({ 978: "eur", 840: "usd", 826: "gbp", 756: "chf" });
6455
+ function decode(text10) {
6456
+ return decodeURIComponent(text10.replace(/\+/g, " "));
6457
+ }
6458
+ function parseRedsysForm(body) {
6459
+ if (typeof body !== "string" || body.length === 0 || body.length > MAX_ENTRY2 || /[^\x21-\x7e]/.test(body))
6460
+ return null;
6461
+ const pairs = [];
6462
+ const seen = /* @__PURE__ */ new Set();
6463
+ for (const chunk of body.split("&")) {
6464
+ const eq = chunk.indexOf("=");
6465
+ if (eq < 1)
6466
+ return null;
6467
+ let key;
6468
+ let value;
6469
+ try {
6470
+ key = decode(chunk.slice(0, eq));
6471
+ value = decode(chunk.slice(eq + 1));
6472
+ }
6473
+ catch {
6474
+ return null;
6475
+ }
6476
+ if (!FORM_KEY.test(key) || value.length > MAX_PARAMETERS || /[\u0000-\u001f\u007f]/.test(value))
6477
+ return null;
6478
+ const folded = key.toLowerCase();
6479
+ if (seen.has(folded))
6480
+ return null;
6481
+ seen.add(folded);
6482
+ pairs.push({ key, value });
6277
6483
  }
6278
- return true;
6279
- };
6280
- var refuse38 = (code) => Object.freeze({ verdict: "refuse", code });
6281
- var CARD37 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6282
- function isIyzicoCardUrl(url) {
6283
- return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
6484
+ return pairs;
6284
6485
  }
6285
- function readBody22(body) {
6286
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT36)
6486
+ var MAX_PAGE2 = 256 * 1024;
6487
+ var CARD_FIELDS2 = Object.freeze({
6488
+ shown: "Sis_card-number",
6489
+ expiry: "SIS_card-expiration",
6490
+ cvc: "Sis_Tarjeta_CVV2",
6491
+ holder: "cardholderName",
6492
+ number: "Sis_Numero_Tarjeta",
6493
+ month: "Sis_Caducidad_Tarjeta_Mes",
6494
+ year: "Sis_Caducidad_Tarjeta_Anno"
6495
+ });
6496
+ var BROWSER_FIELDS = Object.freeze([
6497
+ "browserJavaEnabled",
6498
+ "browserJavascriptEnabled",
6499
+ "browserLanguage",
6500
+ "browserColorDepth",
6501
+ "browserScreenHeight",
6502
+ "browserScreenWidth",
6503
+ "browserTZ",
6504
+ "browserUserAgent"
6505
+ ]);
6506
+ var AS_SERVED = Object.freeze(["cvvObligatorio", "threeDSCompInd", "fuc", "terminal", "merchantOrder", "bcancel"]);
6507
+ var CARD_PAGE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS2), ...BROWSER_FIELDS, ...AS_SERVED]);
6508
+ var VISIBLE2 = /* @__PURE__ */ new Set([CARD_FIELDS2.shown, CARD_FIELDS2.expiry, CARD_FIELDS2.cvc, CARD_FIELDS2.holder]);
6509
+ var METHOD_PAGE = /* @__PURE__ */ new Set(["resultadoMethod", ...BROWSER_FIELDS, "threeDSCompInd"]);
6510
+ var REDSYS_REFUSALS = Object.freeze(["redsys_card_page", "redsys_3ds_challenge", "redsys_declined"]);
6511
+ // src/processors/cardlink_vpos.js
6512
+ var CARDLINK_VPOS_PSP = "cardlink_vpos";
6513
+ var CARDLINK_VPOS_HOSTS = Object.freeze({
6514
+ "vpos.eurocommerce.gr": "worldline",
6515
+ "ecommerce.cardlink.gr": "cardlink",
6516
+ "www.alphaecommerce.gr": "nexi"
6517
+ });
6518
+ var CARDLINK_VPOS_TEST_HOSTS = Object.freeze([
6519
+ "eurocommerce-test.cardlink.gr",
6520
+ "ecommerce-test.cardlink.gr",
6521
+ "alphaecommerce-test.cardlink.gr"
6522
+ ]);
6523
+ var CARDLINK_VPOS_ENTRY_PATH = "/vpos/shophandlermpi";
6524
+ var CARDLINK_VPOS_MERCHANTS = Object.freeze([
6525
+ Object.freeze({ merchant: "Holy Great Monastery of Vatopedi", mid: "0021713862", vposHost: "vpos.eurocommerce.gr", host: "www.vatopedi.gr" })
6526
+ ]);
6527
+ var CARDLINK_VPOS_ENTRY_FIELDS = Object.freeze([
6528
+ "version",
6529
+ "mid",
6530
+ "lang",
6531
+ "deviceCategory",
6532
+ "orderid",
6533
+ "orderDesc",
6534
+ "orderAmount",
6535
+ "currency",
6536
+ "payerEmail",
6537
+ "payerPhone",
6538
+ "billCountry",
6539
+ "billState",
6540
+ "billZip",
6541
+ "billCity",
6542
+ "billAddress",
6543
+ "weight",
6544
+ "dimensions",
6545
+ "shipCountry",
6546
+ "shipState",
6547
+ "shipZip",
6548
+ "shipCity",
6549
+ "shipAddress",
6550
+ "addFraudScore",
6551
+ "maxPayRetries",
6552
+ "reject3dsU",
6553
+ "payMethod",
6554
+ "trType",
6555
+ "extInstallmentoffset",
6556
+ "extInstallmentperiod",
6557
+ "extRecurringfrequency",
6558
+ "extRecurringenddate",
6559
+ "blockScore",
6560
+ "cssUrl",
6561
+ "confirmUrl",
6562
+ "cancelUrl",
6563
+ "extTokenOptions",
6564
+ "extToken",
6565
+ "var1",
6566
+ "var2",
6567
+ "var3",
6568
+ "var4",
6569
+ "var5",
6570
+ "var6",
6571
+ "var7",
6572
+ "var8",
6573
+ "var9",
6574
+ "digest"
6575
+ ]);
6576
+ var KNOWN = new Set(CARDLINK_VPOS_ENTRY_FIELDS);
6577
+ var REQUIRED3 = Object.freeze([
6578
+ "version",
6579
+ "mid",
6580
+ "orderid",
6581
+ "orderDesc",
6582
+ "orderAmount",
6583
+ "currency",
6584
+ "payerEmail",
6585
+ "confirmUrl",
6586
+ "cancelUrl",
6587
+ "digest"
6588
+ ]);
6589
+ var STORED2 = Object.freeze(["extTokenOptions", "extToken"]);
6590
+ var SPECIAL2 = Object.freeze(["extInstallmentoffset", "extInstallmentperiod", "extRecurringfrequency", "extRecurringenddate"]);
6591
+ var CURRENCIES2 = Object.freeze({ EUR: "eur" });
6592
+ var MAX_URL = 512;
6593
+ var MAX_ENTRY3 = 8 * 1024;
6594
+ var MAX_VALUE = 256;
6595
+ var own13 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
6596
+ var field2 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
6597
+ function cardlinkVposEntryHost(raw) {
6598
+ if (typeof raw !== "string" || raw.length > MAX_URL || raw.includes("?") || raw.includes("#"))
6287
6599
  return null;
6600
+ let url;
6288
6601
  try {
6289
- const value = JSON.parse(body);
6290
- return record33(value) && JSON.stringify(value) === body ? value : null;
6602
+ url = new URL(raw);
6291
6603
  }
6292
6604
  catch {
6293
6605
  return null;
6294
6606
  }
6607
+ if (url.href !== raw || url.protocol !== "https:" || url.port || url.username || url.password || !own13(CARDLINK_VPOS_HOSTS, url.hostname) || url.pathname !== CARDLINK_VPOS_ENTRY_PATH)
6608
+ return null;
6609
+ return url.hostname;
6295
6610
  }
6296
- function hundredths(price) {
6297
- const match = typeof price === "number" && Number.isFinite(price) ? PRICE.exec(String(price)) : null;
6298
- const value = match ? Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0")) : 0;
6299
- return value > 0 ? value : null;
6611
+ function isCardlinkVposEntryUrl(raw) {
6612
+ return cardlinkVposEntryHost(raw) !== null;
6300
6613
  }
6301
- var holderName2 = (name) => typeof name === "string" && HOLDER5.test(name) && name.trim().split(/\s+/).filter((word) => word.length > 1).length > 1;
6302
- var metadata = (value) => record33(value) && inOrder6(value, METADATA_KEYS3) && Object.values(value).every((flag3) => Array.isArray(flag3) && flag3.length === 1 && typeof flag3[0] === "string" && FLAG.test(flag3[0]));
6303
- function iyzicoBodyVerdict(body) {
6304
- const value = readBody22(body);
6305
- if (value === null)
6306
- return refuse38("iyzico_body_unsupported");
6307
- const card = value.paymentCard;
6308
- if (record33(card) && (own13(card, "cardToken") || own13(card, "ucsToken") || own13(card, "consumerToken")) && !own13(card, "cardNumber"))
6309
- return refuse38("iyzico_saved_card");
6310
- if (own13(value, "dccPayment") || own13(value, "dccQueryRrn"))
6311
- return refuse38("iyzico_dcc_refused");
6312
- if (own13(value, "gsmNumber") || own13(value, "buyerProtected") && value.buyerProtected !== false || record33(card) && (own13(card, "registerCard") && card.registerCard !== 0 || own13(card, "registerConsumerCard") && card.registerConsumerCard !== false)) {
6313
- return refuse38("iyzico_keeps_card");
6614
+ function parseCardlinkVposForm(body) {
6615
+ if (typeof body !== "string" || body.length === 0 || body.length > MAX_ENTRY3 || /[^\x21-\x7e]/.test(body))
6616
+ return null;
6617
+ const pairs = [];
6618
+ const seen = /* @__PURE__ */ new Set();
6619
+ for (const chunk of body.split("&")) {
6620
+ const eq = chunk.indexOf("=");
6621
+ if (eq < 1)
6622
+ return null;
6623
+ let key;
6624
+ let value;
6625
+ try {
6626
+ key = decodeURIComponent(chunk.slice(0, eq).replace(/\+/g, " "));
6627
+ value = decodeURIComponent(chunk.slice(eq + 1).replace(/\+/g, " "));
6628
+ }
6629
+ catch {
6630
+ return null;
6631
+ }
6632
+ if (!/^[A-Za-z_.][A-Za-z0-9_.-]{0,63}$/.test(key) || value.length > MAX_VALUE || /[\u0000-\u001f\u007f]/.test(value))
6633
+ return null;
6634
+ if (seen.has(key))
6635
+ return null;
6636
+ seen.add(key);
6637
+ pairs.push({ key, value });
6314
6638
  }
6315
- if (Number.isSafeInteger(value.installment) && value.installment > 1)
6316
- return refuse38("iyzico_installments_refused");
6317
- if (!inOrder6(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own13(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own13(value, "pwiMetadata") && !metadata(value.pwiMetadata))
6318
- return refuse38("iyzico_body_unsupported");
6319
- if (!record33(card) || Object.keys(card).join() !== IYZICO_CARD_KEYS.join() || typeof card.cardNumber !== "string" || !CARD_NUMBER19.test(card.cardNumber) || !holderName2(card.cardHolderName) || typeof card.expireYear !== "string" || !YEAR20.test(card.expireYear) || typeof card.expireMonth !== "string" || !MONTH19.test(card.expireMonth) || typeof card.cvc !== "string" || !SECURITY_CODE23.test(card.cvc))
6320
- return refuse38("iyzico_body_unsupported");
6321
- return CARD37;
6639
+ return pairs;
6322
6640
  }
6323
- var iyzico_default = /* @__PURE__ */ registerProcessor({
6324
- psp: IYZICO_PSP,
6325
- definitions: [
6641
+ function cardlinkVposMerchant(mid, vposHost, merchants = CARDLINK_VPOS_MERCHANTS) {
6642
+ if (typeof mid !== "string" || typeof vposHost !== "string" || !Array.isArray(merchants))
6643
+ return null;
6644
+ const found = merchants.filter((row) => !!row && typeof row.merchant === "string" && row.merchant.trim() !== "" && row.mid === mid && row.vposHost === vposHost && typeof row.host === "string" && row.host !== "");
6645
+ return found.length === 1 ? found[0] : null;
6646
+ }
6647
+ function entryAmount(values) {
6648
+ const amount2 = values.get("orderAmount");
6649
+ const code = values.get("currency");
6650
+ const currency = typeof code === "string" && own13(CURRENCIES2, code) ? CURRENCIES2[code] : null;
6651
+ if (!currency || typeof amount2 !== "string" || !/^(?:0|[1-9]\d{0,11})(?:\.\d{1,2})?$/.test(amount2))
6652
+ return null;
6653
+ const [whole2, fraction = ""] = amount2.split(".");
6654
+ const cents2 = Number(whole2) * 100 + Number(fraction.padEnd(2, "0"));
6655
+ return Number.isSafeInteger(cents2) && cents2 > 0 ? { amountCents: cents2, currency } : null;
6656
+ }
6657
+ function httpsUrl(value) {
6658
+ let url;
6659
+ try {
6660
+ url = new URL(value);
6661
+ }
6662
+ catch {
6663
+ return null;
6664
+ }
6665
+ if (url.protocol !== "https:" || url.username || url.password || url.port || url.hash)
6666
+ return null;
6667
+ return url;
6668
+ }
6669
+ function checkCardlinkVposEntry(body, { url = null, merchants = CARDLINK_VPOS_MERCHANTS } = {}) {
6670
+ const vposHost = cardlinkVposEntryHost(url);
6671
+ if (!vposHost)
6672
+ return field2("(url)", "malformed_field");
6673
+ const pairs = parseCardlinkVposForm(body);
6674
+ if (!pairs)
6675
+ return field2("(body)", "malformed");
6676
+ const values = new Map(pairs.map(({ key, value }) => [key, value]));
6677
+ for (const { key } of pairs) {
6678
+ if (KNOWN.has(key))
6679
+ continue;
6680
+ return field2(key, /^(?:card[._]|cvv|cmd$|trid$|st$|paystep$|paymentmethod$)/i.test(key) ? "card_in_entry" : "not_an_entry");
6681
+ }
6682
+ const missing = REQUIRED3.filter((name) => !values.get(name));
6683
+ if (missing.length)
6684
+ return { ok: false, code: "hosted_form_template_incomplete", missing };
6685
+ if (values.get("version") !== "2")
6686
+ return field2("version", "malformed");
6687
+ if (!/^[A-Za-z0-9+/]{43}=$/.test(values.get("digest")))
6688
+ return field2("digest", "unsigned");
6689
+ for (const name of STORED2)
6690
+ if (values.has(name))
6691
+ return field2(name, "stored_credential");
6692
+ for (const name of SPECIAL2)
6693
+ if (values.get(name))
6694
+ return field2(name, "special_flow");
6695
+ for (let i = 1; i <= 9; i += 1)
6696
+ if (/moto\s*=\s*true/i.test(values.get(`var${i}`) ?? ""))
6697
+ return field2(`var${i}`, "moto");
6698
+ if (values.has("trType") && values.get("trType") !== "1")
6699
+ return field2("trType", "not_a_sale");
6700
+ const method = values.get("payMethod");
6701
+ if (method)
6702
+ return field2("payMethod", /^iris$/i.test(method) ? "not_a_card_payment" : "special_flow");
6703
+ const amount2 = entryAmount(values);
6704
+ if (!amount2)
6705
+ return field2(own13(CURRENCIES2, values.get("currency")) ? "orderAmount" : "currency", "malformed");
6706
+ if (!/^\d{1,30}$/.test(values.get("mid")))
6707
+ return field2("mid", "malformed");
6708
+ if (!/^[A-Za-z0-9]{1,50}$/.test(values.get("orderid")))
6709
+ return field2("orderid", "malformed");
6710
+ const seller = cardlinkVposMerchant(values.get("mid"), vposHost, merchants);
6711
+ if (!seller)
6712
+ return field2("mid", "seller_unreviewed");
6713
+ for (const name of ["confirmUrl", "cancelUrl"]) {
6714
+ const target = httpsUrl(values.get(name));
6715
+ if (!target || target.hostname !== seller.host)
6716
+ return field2(name, "callback_host");
6717
+ }
6718
+ return {
6719
+ ok: true,
6720
+ pairs,
6721
+ gated: false,
6722
+ dedupe: [vposHost, values.get("mid"), values.get("orderid"), values.get("orderAmount"), values.get("currency")],
6723
+ seller
6724
+ };
6725
+ }
6726
+ function cardlinkVposEntryAmount(body) {
6727
+ const pairs = parseCardlinkVposForm(body);
6728
+ return pairs ? entryAmount(new Map(pairs.map(({ key, value }) => [key, value]))) : null;
6729
+ }
6730
+ var CARDLINK_VPOS_TDS2_FIELDS = Object.freeze([
6731
+ "TDS2_Navigator_language",
6732
+ "TDS2_Navigator_jsEnabled",
6733
+ "TDS2_Navigator_javaEnabled",
6734
+ "TDS2_Screen_colorDepth",
6735
+ "TDS2_Screen_height",
6736
+ "TDS2_Screen_width",
6737
+ "TDS2_screen_pixelDepth",
6738
+ "TDS2_TimezoneOffset"
6739
+ ]);
6740
+ var PAGE_FIELDS = Object.freeze(["trid", "st", "payStep", "cmd", "startbonus", "bonusdata"]);
6741
+ var WALLET_FIELDS2 = Object.freeze(["walletId", "applePayResponse"]);
6742
+ var CARD38 = Object.freeze({ number: "card.pan", holder: "card.holderName", month: "card.expiryMonth", year: "card.expiryYear", cvc: "card.cvv" });
6743
+ var TEXT_CONTROLS = /* @__PURE__ */ new Set([CARD38.number, CARD38.holder, CARD38.cvc]);
6744
+ var SELECT_CONTROLS = /* @__PURE__ */ new Set([CARD38.month, CARD38.year]);
6745
+ var MAX_PAGE3 = 256 * 1024;
6746
+ var COOKIE_DOMAINS = Object.freeze({
6747
+ "vpos.eurocommerce.gr": "eurocommerce.gr",
6748
+ "ecommerce.cardlink.gr": "cardlink.gr",
6749
+ "www.alphaecommerce.gr": "alphaecommerce.gr"
6750
+ });
6751
+ var POST_REQUIRED = Object.freeze(["trid", "st", "cmd", CARD38.number, CARD38.holder, CARD38.month, CARD38.year, CARD38.cvc, "makepayment"]);
6752
+ var POST_EMPTY = Object.freeze(["payStep", "startbonus", "bonusdata", ...WALLET_FIELDS2]);
6753
+ var POST_ALLOWED = /* @__PURE__ */ new Set([...POST_REQUIRED, ...POST_EMPTY, "paymentMethod", ...CARDLINK_VPOS_TDS2_FIELDS]);
6754
+ var CARDLINK_VPOS_REFUSALS = Object.freeze([
6755
+ "cardlink_vpos_card_refused",
6756
+ "cardlink_vpos_card_page",
6757
+ "cardlink_vpos_3ds_challenge",
6758
+ "cardlink_vpos_declined"
6759
+ ]);
6760
+ var REFUSAL_FOR = Object.freeze({
6761
+ card_refused: "cardlink_vpos_card_refused",
6762
+ card_page: "cardlink_vpos_card_page",
6763
+ challenge: "cardlink_vpos_3ds_challenge",
6764
+ declined: "cardlink_vpos_declined"
6765
+ });
6766
+ var CARDLINK_VPOS_CAPABILITY = "cardlink_vpos_hosted_payment_page";
6767
+ var CARDLINK_VPOS_OPERATION = "cardlink_vpos.hosted_sale";
6768
+ var cardlink_vpos_default = /* @__PURE__ */ registerProcessor({
6769
+ psp: CARDLINK_VPOS_PSP,
6770
+ definitions: [
6771
+ {
6772
+ psp: "cardlink_vpos",
6773
+ // The merchant's signed entry, as the header above reads it: a Document navigation that carries no card. The
6774
+ // cardholder's device repeats it over the end-to-end TLS relay, fills the card into the page the VPOS returns
6775
+ // and posts it in that same session, and the runtime resolves the paused navigation with the hosted_form notice.
6776
+ // Only the entry path on the three live hosts is matched (isCardlinkVposEntryUrl). The card page posts to the same
6777
+ // path, so the SDK fails every other post to these hosts in the agent's browser, and no placeholder card reaches
6778
+ // the VPOS. The test hosts are listed so a live host classifies as live and the create refuses a test row there;
6779
+ // no entry on them is paused. Ships dark: served only to a client that declares
6780
+ // `cardlink_vpos_hosted_payment_page`, and gated off for every company the operator has not turned it on for.
6781
+ capability: CARDLINK_VPOS_CAPABILITY,
6782
+ match: "(?:vpos\\.eurocommerce\\.gr|ecommerce\\.cardlink\\.gr|www\\.alphaecommerce\\.gr)/vpos/shophandlermpi(?![\\w/.%;=!-])",
6783
+ hosts: [
6784
+ "^vpos\\.eurocommerce\\.gr$",
6785
+ "^ecommerce\\.cardlink\\.gr$",
6786
+ "^www\\.alphaecommerce\\.gr$",
6787
+ "^eurocommerce-test\\.cardlink\\.gr$",
6788
+ "^ecommerce-test\\.cardlink\\.gr$",
6789
+ "^alphaecommerce-test\\.cardlink\\.gr$"
6790
+ ],
6791
+ sandboxHosts: ["^eurocommerce-test\\.cardlink\\.gr$", "^ecommerce-test\\.cardlink\\.gr$", "^alphaecommerce-test\\.cardlink\\.gr$"],
6792
+ hostEnvironmentPinned: true,
6793
+ encoding: "form",
6794
+ // A form navigation: no captured header is ever replayed.
6795
+ passthroughHeaders: [],
6796
+ mode: "hosted_form",
6797
+ hostedForm: {
6798
+ // The card goes into the VPOS's own page on the device, never into the entry, which must carry none
6799
+ // (checkCardlinkVposEntry). The entry's rules come with this registration (hostedEntry below), so no policy is
6800
+ // named here.
6801
+ cardIn: "processor_page",
6802
+ required: [...REQUIRED3],
6803
+ // The card page's own fields, which the device fills on that page.
6804
+ card: { number: "card.pan", month: "card.expiryMonth", year: "card.expiryYear", cvc: "card.cvv" },
6805
+ // The host, the mid, the order id and the amount name one payment; the entry's rules read the host from its URL.
6806
+ dedupe: ["(vposHost)", "mid", "orderid", "orderAmount", "currency"]
6807
+ }
6808
+ }
6809
+ ],
6810
+ // Only the cardholder's device repeats an entry, after a person approves; no reviewed list names cardlink_vpos.
6811
+ refusedOperations: [CARDLINK_VPOS_OPERATION],
6812
+ // Not surveyed: the VPOS tells the merchant the result through the browser's return and a copy to its server, both
6813
+ // signed under the merchant's secret, which Agentcard never holds.
6814
+ settlementReadback: "not_surveyed",
6815
+ exactUrl: isCardlinkVposEntryUrl,
6816
+ hostedEntry: (body, { url }) => checkCardlinkVposEntry(body, { url }),
6817
+ amount: (template) => template && isCardlinkVposEntryUrl(template.url) ? cardlinkVposEntryAmount(template.body) : null,
6818
+ limitations: [
6819
+ "The paused request is the merchant's signed entry form, which carries no card; the cardholder's device sends it to Cardlink's VPOS over the end-to-end TLS relay and fills the card into the page the VPOS returns.",
6820
+ "Agentcard takes only a reviewed merchant's entry: its mid and the host it posts to name the merchant the cardholder is shown, and its confirm and cancel URLs must sit on that merchant's own host.",
6821
+ "Agentcard takes one plain payment only and refuses an entry that asks for a stored card, installments, a recurring schedule, a pre-authorization, MOTO or a preselected payment method.",
6822
+ "The VPOS runs EMV 3-D Secure on the card. A frictionless answer pays; a challenge ends the payment on the device with nothing charged.",
6823
+ "The browser receives a submission notice, not the processor result."
6824
+ ]
6825
+ });
6826
+ // src/processors/eghl.js
6827
+ var EGHL_PSP = "eghl";
6828
+ var EGHL_OPERATION = "eghl.hosted_sale";
6829
+ var EGHL_HOST = "securepay.e-ghl.com";
6830
+ var EGHL_SANDBOX_HOST = "test2pay.ghl.com";
6831
+ var LIVE_PATH = "/ipg/payment.aspx";
6832
+ var SANDBOX_PATH = "/ipgsg/payment.aspx";
6833
+ var MAX_URL2 = 8192;
6834
+ var field3 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
6835
+ function eghlEntry(raw) {
6836
+ if (typeof raw !== "string" || raw.length > MAX_URL2 || raw.includes("#"))
6837
+ return null;
6838
+ let url;
6839
+ try {
6840
+ url = new URL(raw);
6841
+ }
6842
+ catch {
6843
+ return null;
6844
+ }
6845
+ if (url.href !== raw || url.protocol !== "https:" || url.port || url.username || url.password || url.search.length < 2)
6846
+ return null;
6847
+ const path = url.pathname.toLowerCase();
6848
+ const query = url.search.slice(1);
6849
+ if (url.hostname === EGHL_HOST && path === LIVE_PATH)
6850
+ return Object.freeze({ test: false, query });
6851
+ if (url.hostname === EGHL_SANDBOX_HOST && path === SANDBOX_PATH)
6852
+ return Object.freeze({ test: true, query });
6853
+ return null;
6854
+ }
6855
+ function isEghlEntryUrl(raw) {
6856
+ return eghlEntry(raw) !== null;
6857
+ }
6858
+ var EGHL_MERCHANTS = Object.freeze([
6859
+ Object.freeze({ merchant: "BookXcess", serviceId: "BXS", payee: "BookXcess Sdn Bhd", returnHosts: Object.freeze(["shopify.ghl.com:11443"]), test: false })
6860
+ ]);
6861
+ var SERVICE_ID2 = /^[A-Za-z0-9]{3}$/;
6862
+ var HOST = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+(?::[1-9]\d{0,4})?$/;
6863
+ function eghlMerchant(serviceId, { test = false, merchants = EGHL_MERCHANTS } = {}) {
6864
+ if (typeof serviceId !== "string" || !SERVICE_ID2.test(serviceId) || !Array.isArray(merchants))
6865
+ return null;
6866
+ const found = merchants.filter((row) => !!row && typeof row.merchant === "string" && row.merchant.trim() !== "" && typeof row.payee === "string" && row.payee.trim() !== "" && row.serviceId === serviceId && row.test === test && Array.isArray(row.returnHosts) && row.returnHosts.length > 0 && row.returnHosts.every((host) => typeof host === "string" && HOST.test(host)));
6867
+ return found.length === 1 ? found[0] : null;
6868
+ }
6869
+ var REQUIRED4 = Object.freeze([
6870
+ "TransactionType",
6871
+ "PymtMethod",
6872
+ "ServiceID",
6873
+ "PaymentID",
6874
+ "OrderNumber",
6875
+ "MerchantReturnURL",
6876
+ "MerchantCallBackURL",
6877
+ "Amount",
6878
+ "CurrencyCode",
6879
+ "HashValue"
6880
+ ]);
6881
+ var CARD_KEYS17 = /* @__PURE__ */ new Set(["cardno", "cardexp", "cardcvv2", "cardholder", "param2", "param4", "cvv2", "epmonth2", "epyear2", "custocp"]);
6882
+ var SECRET_KEYS = /* @__PURE__ */ new Set(["password"]);
6883
+ var STORED_KEYS2 = /* @__PURE__ */ new Set([
6884
+ "tokentype",
6885
+ "token",
6886
+ "cardid",
6887
+ "precheckoutid",
6888
+ "reqtoken",
6889
+ "pairingtoken",
6890
+ "reqverifier",
6891
+ "pairingverifier",
6892
+ "checkoutresourceurl"
6893
+ ]);
6894
+ var SPECIAL_KEYS = /* @__PURE__ */ new Set(["eppmonth", "promocode"]);
6895
+ var RESULT_KEYS = Object.freeze(["MerchantReturnURL", "MerchantCallBackURL", "MerchantApprovalURL", "MerchantUnApprovalURL"]);
6896
+ var CURRENCIES3 = /* @__PURE__ */ new Set(["MYR", "SGD", "USD", "PHP", "THB"]);
6897
+ var AMOUNT3 = /^(0|[1-9]\d{0,8})\.(\d{2})$/;
6898
+ function httpsUrl2(value) {
6899
+ let url;
6900
+ try {
6901
+ url = new URL(value);
6902
+ }
6903
+ catch {
6904
+ return null;
6905
+ }
6906
+ if (url.protocol !== "https:" || url.username || url.password || url.hash)
6907
+ return null;
6908
+ return url;
6909
+ }
6910
+ function entryFields(text10) {
6911
+ const pairs = parseRedsysForm(text10);
6912
+ if (!pairs)
6913
+ return null;
6914
+ return { pairs, values: new Map(pairs.map(({ key, value }) => [key.toLowerCase(), value])) };
6915
+ }
6916
+ function entryAmount2(values) {
6917
+ const currency = values.get("currencycode");
6918
+ const amount2 = AMOUNT3.exec(values.get("amount") ?? "");
6919
+ if (!amount2 || typeof currency !== "string" || !CURRENCIES3.has(currency))
6920
+ return null;
6921
+ const cents2 = Number(amount2[1]) * 100 + Number(amount2[2]);
6922
+ return cents2 > 0 && Number.isSafeInteger(cents2) ? { amountCents: cents2, currency: currency.toLowerCase() } : null;
6923
+ }
6924
+ function checkEghlEntry(body, { url = null, merchants = EGHL_MERCHANTS } = {}) {
6925
+ if (body !== void 0 && body !== null && body !== "")
6926
+ return field3("(body)", "not_an_entry");
6927
+ const entry = eghlEntry(url);
6928
+ if (!entry)
6929
+ return field3("(url)", "malformed_field");
6930
+ const fields = entryFields(entry.query);
6931
+ if (!fields)
6932
+ return field3("(query)", "malformed");
6933
+ const { pairs, values } = fields;
6934
+ for (const { key, value } of pairs) {
6935
+ if (value === "")
6936
+ continue;
6937
+ const folded = key.toLowerCase();
6938
+ if (CARD_KEYS17.has(folded))
6939
+ return field3(key, "card_in_entry");
6940
+ if (SECRET_KEYS.has(folded))
6941
+ return field3(key, "not_an_entry");
6942
+ if (STORED_KEYS2.has(folded))
6943
+ return field3(key, "stored_credential");
6944
+ if (SPECIAL_KEYS.has(folded))
6945
+ return field3(key, "special_flow");
6946
+ }
6947
+ const missing = REQUIRED4.filter((name) => !values.get(name.toLowerCase()));
6948
+ if (missing.length)
6949
+ return { ok: false, code: "hosted_form_template_incomplete", missing };
6950
+ if (values.get("transactiontype") !== "SALE")
6951
+ return field3("TransactionType", "not_a_sale");
6952
+ if (!["ANY", "CC"].includes(values.get("pymtmethod")))
6953
+ return field3("PymtMethod", "special_flow");
6954
+ if (!/^[0-9A-Fa-f]{64}$/.test(values.get("hashvalue")))
6955
+ return field3("HashValue", "unsigned");
6956
+ if (!entryAmount2(values))
6957
+ return field3(CURRENCIES3.has(values.get("currencycode")) ? "Amount" : "CurrencyCode", "malformed");
6958
+ if (!SERVICE_ID2.test(values.get("serviceid")))
6959
+ return field3("ServiceID", "malformed");
6960
+ if (!/^[A-Za-z0-9._-]{1,20}$/.test(values.get("paymentid")))
6961
+ return field3("PaymentID", "malformed");
6962
+ if (values.get("ordernumber").length > 20)
6963
+ return field3("OrderNumber", "malformed");
6964
+ const pageTimeout = values.get("pagetimeout");
6965
+ if (pageTimeout !== void 0 && !/^[1-9]\d{1,4}$/.test(pageTimeout))
6966
+ return field3("PageTimeout", "malformed");
6967
+ const seller = eghlMerchant(values.get("serviceid"), { test: entry.test, merchants });
6968
+ if (!seller)
6969
+ return field3("ServiceID", "seller_unreviewed");
6970
+ for (const name of RESULT_KEYS) {
6971
+ const value = values.get(name.toLowerCase());
6972
+ if (!value)
6973
+ continue;
6974
+ const target = httpsUrl2(value);
6975
+ if (!target || !seller.returnHosts.includes(target.host) || [EGHL_HOST, EGHL_SANDBOX_HOST].includes(target.hostname))
6976
+ return field3(name, "callback_host");
6977
+ }
6978
+ return { ok: true, pairs, gated: false, dedupe: [values.get("serviceid"), values.get("paymentid")], sandbox: entry.test, seller };
6979
+ }
6980
+ function eghlEntryAmount(body, url) {
6981
+ if (body !== void 0 && body !== null && body !== "")
6982
+ return null;
6983
+ const entry = eghlEntry(url);
6984
+ const fields = entry ? entryFields(entry.query) : null;
6985
+ return fields ? entryAmount2(fields.values) : null;
6986
+ }
6987
+ var MAX_PAGE4 = 1024 * 1024;
6988
+ var NEVER_SENT = new Set(["expressCheckoutType", "c2pRememberMeBrowser", "CustOCP", "CustRecurr", "CustAddress"].map((name) => name.toLowerCase()));
6989
+ var PAGE_REQUIRED = Object.freeze([
6990
+ "TransactionType",
6991
+ "ServiceID",
6992
+ "MerchantName",
6993
+ "PaymentID",
6994
+ "Amount",
6995
+ "BaseTxnAmount",
6996
+ "CurrencyCode",
6997
+ "BaseCurrencyCode",
6998
+ "HashValue",
6999
+ "Param2",
7000
+ "Param4",
7001
+ "CardExp",
7002
+ "CVV2",
7003
+ "PymtMethod"
7004
+ ]);
7005
+ var EGHL_REFUSALS = Object.freeze(["eghl_failed", "eghl_cancelled"]);
7006
+ var MAX_ANSWER = 256 * 1024;
7007
+ var RESULT_FIELDS = Object.freeze(["TxnStatus", "ServiceID", "PaymentID", "Amount", "CurrencyCode"]);
7008
+ var eghl_default = /* @__PURE__ */ registerProcessor({
7009
+ psp: EGHL_PSP,
7010
+ definitions: [
7011
+ {
7012
+ psp: "eghl",
7013
+ // The merchant's entry to eGHL's payment page, as the header above reads it: a GET Document navigation whose
7014
+ // query names the payment and which carries no card. The cardholder's device repeats it over the end-to-end TLS
7015
+ // relay and pays on the page eGHL returns to it, and the runtime resolves the paused navigation with the
7016
+ // hosted_form notice. Only the entry is matched (isEghlEntryUrl): the card page's own card post goes to the same
7017
+ // path as a POST. The path is matched in any letter case, as IIS reads it; `(?![\\w/.%-])` ends it for a consumer
7018
+ // that tests `match` unanchored. Ships dark: served only to a client that declares `eghl_hosted_payment_page`, and
7019
+ // gated off for every company the operator has not allowlisted.
7020
+ capability: "eghl_hosted_payment_page",
7021
+ match: "securepay\\.e-ghl\\.com/[Ii][Pp][Gg]/[Pp][Aa][Yy][Mm][Ee][Nn][Tt]\\.[Aa][Ss][Pp][Xx](?![\\w/.%-])|test2pay\\.ghl\\.com/[Ii][Pp][Gg][Ss][Gg]/[Pp][Aa][Yy][Mm][Ee][Nn][Tt]\\.[Aa][Ss][Pp][Xx](?![\\w/.%-])",
7022
+ hosts: ["^securepay\\.e-ghl\\.com$", "^test2pay\\.ghl\\.com$"],
7023
+ sandboxHosts: ["^test2pay\\.ghl\\.com$"],
7024
+ hostEnvironmentPinned: true,
7025
+ // `encoding` describes the card page's own card post, which the device makes as the page does, since the entry
7026
+ // has no body. No captured header is ever replayed.
7027
+ encoding: "form",
7028
+ passthroughHeaders: [],
7029
+ // The paused request is the navigation itself, a GET with the payment in its query.
7030
+ request: { method: "GET", cardIn: "processor_page", response: "document" },
7031
+ mode: "hosted_form",
7032
+ hostedForm: {
7033
+ // The card goes into eGHL's page on the device, never into the entry (checkEghlEntry refuses one there). The
7034
+ // entry's own rules come with this registration (hostedEntry below), so no policy is named here.
7035
+ cardIn: "processor_page",
7036
+ required: ["TransactionType", "PymtMethod", "ServiceID", "PaymentID", "OrderNumber", "MerchantReturnURL", "MerchantCallBackURL", "Amount", "CurrencyCode", "HashValue"],
7037
+ // The card page's own inputs in its card form (frmProcessPayment, read card free on 2026-11-05): the number in
7038
+ // Param2, the expiry in CardExp as YYYYMM, which the page builds from its month and year selects, the code in
7039
+ // CVV2. The cardholder's name goes in Param4.
7040
+ card: { number: "Param2", expiry: "CardExp", cvc: "CVV2" },
7041
+ // eGHL takes one PaymentID once per merchant.
7042
+ dedupe: ["ServiceID", "PaymentID"]
7043
+ }
7044
+ }
7045
+ ],
7046
+ // Only the cardholder's device repeats an entry, after a person approves; no reviewed list names eghl.
7047
+ refusedOperations: [EGHL_OPERATION],
7048
+ // Not surveyed: eGHL tells the merchant's server the result (MerchantCallBackURL), and its return carries a hash only
7049
+ // the merchant can check.
7050
+ settlementReadback: "not_surveyed",
7051
+ exactUrl: isEghlEntryUrl,
7052
+ amount: (template) => template && typeof template === "object" ? eghlEntryAmount(template.body, template.url) : null,
7053
+ hostedEntry: (body, { url = null } = {}) => checkEghlEntry(body, { url }),
7054
+ limitations: [
7055
+ "The paused request is the merchant's redirect to eGHL's payment page, a GET whose query names the payment and carries no card; the cardholder's device repeats it over the end-to-end TLS relay and pays on the page eGHL returns.",
7056
+ "Agentcard takes an entry only for a merchant it reviewed, by the ServiceID inside the merchant's signed entry, and the approval names that merchant and the amount the entry names.",
7057
+ "eGHL runs 3-D Secure on the card. A challenge ends the payment on the device with nothing charged.",
7058
+ "eGHL sends the buyer to the merchant's return page with a result only the merchant can verify, so the browser receives a submission notice, not the processor result."
7059
+ ]
7060
+ });
7061
+ // src/processors/frisbii.js
7062
+ var FRISBII_PSP = "frisbii";
7063
+ var FRISBII_OPERATION = "frisbii.card_request";
7064
+ var FRISBII_HOSTS = /* @__PURE__ */ Object.freeze({ "card.reepay.com": "reepay", "card.frisbii.com": "frisbii" });
7065
+ var FRISBII_TOKEN_PATH = "/v1/token/";
7066
+ var FRISBII_REFUSED_PATHS = /* @__PURE__ */ Object.freeze({
7067
+ "/v1/token/cof/": "frisbii_stored_card_unsupported",
7068
+ "/v1/token/create_click_to_pay": "frisbii_click_to_pay_unsupported"
7069
+ });
7070
+ var BODY_LIMIT37 = 8192;
7071
+ var URL_LIMIT15 = 256;
7072
+ var CARD_NUMBER19 = /^[0-9]{12,19}$/;
7073
+ var MONTH19 = /^(?:0[1-9]|1[0-2])$/;
7074
+ var YEAR20 = /^[0-9]{2}$/;
7075
+ var SECURITY_CODE23 = /^(?:[0-9]{3,4})?$/;
7076
+ var IDENTIFIER2 = /^[A-Za-z0-9_-]{8,128}$/;
7077
+ var SCA_RULES = /* @__PURE__ */ Object.freeze([
7078
+ "DO_NOT_USE_SCA",
7079
+ "MUST_USE_SCA_AUTH",
7080
+ "MUST_USE_SCA_PREAUTH",
7081
+ "USE_SCA_IF_AVAILABLE_AUTH",
7082
+ "USE_SCA_IF_AVAILABLE_PREAUTH"
7083
+ ]);
7084
+ var BODY_ORDER = /* @__PURE__ */ Object.freeze([
7085
+ "number",
7086
+ "month",
7087
+ "year",
7088
+ "cvv",
7089
+ "cardTypeOverride",
7090
+ "click_to_pay_encrypt",
7091
+ "billing_address",
7092
+ "pkey",
7093
+ "recurring",
7094
+ "cardholder_name",
7095
+ "intent",
7096
+ "recurringAverageAmount",
7097
+ "agreementFilter",
7098
+ "strongAuthenticationRule",
7099
+ "tokenStrongAuthenticationRequest"
7100
+ ]);
7101
+ var BODY_REQUIRED = /* @__PURE__ */ Object.freeze(["number", "month", "year", "cvv", "pkey", "recurring", "strongAuthenticationRule"]);
7102
+ var BODY_REFUSED = /* @__PURE__ */ Object.freeze(["cardTypeOverride", "click_to_pay_encrypt", "billing_address"]);
7103
+ var SCA_ORDER = /* @__PURE__ */ Object.freeze(["amount", "currency", "orderId", "orderText", "merchantScaData", "returnUrl", "tokenBrowserInfo"]);
7104
+ var BROWSER_ORDER = /* @__PURE__ */ Object.freeze([
7105
+ "javascriptEnabled",
7106
+ "challengeWindowSize",
7107
+ "colorDepth",
7108
+ "javaEnabled",
7109
+ "screenHeight",
7110
+ "screenWidth",
7111
+ "tz"
7112
+ ]);
7113
+ var LABEL = /^[A-Za-z0-9_-]{1,64}$/;
7114
+ var record33 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7115
+ var own14 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7116
+ var refuse39 = (code) => Object.freeze({ verdict: "refuse", code });
7117
+ var CARD39 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7118
+ var text9 = (value, max) => typeof value === "string" && value.length <= max;
7119
+ var absentOrNull = (value) => value === void 0 || value === null;
7120
+ var inOrder6 = (value, order) => Object.keys(value).every((key) => order.includes(key)) && Object.keys(value).join() === order.filter((key) => own14(value, key)).join();
7121
+ function frisbiiTokenUrl(url) {
7122
+ if (typeof url !== "string" || url.length > URL_LIMIT15 || url.includes("#"))
7123
+ return null;
7124
+ let parsed;
7125
+ try {
7126
+ parsed = new URL(url);
7127
+ }
7128
+ catch {
7129
+ return null;
7130
+ }
7131
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own14(FRISBII_HOSTS, parsed.hostname) || parsed.pathname !== FRISBII_TOKEN_PATH)
7132
+ return null;
7133
+ const match = /^\?session=([A-Za-z0-9_-]{8,128})$/.exec(parsed.search);
7134
+ return match ? Object.freeze({ host: parsed.hostname, brand: FRISBII_HOSTS[parsed.hostname], session: match[1] }) : null;
7135
+ }
7136
+ var isFrisbiiTokenUrl = (url) => frisbiiTokenUrl(url) !== null;
7137
+ function frisbiiRefusedFlowUrl(url) {
7138
+ if (typeof url !== "string" || url.length > URL_LIMIT15 || url.includes("#"))
7139
+ return null;
7140
+ let parsed;
7141
+ try {
7142
+ parsed = new URL(url);
7143
+ }
7144
+ catch {
7145
+ return null;
7146
+ }
7147
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own14(FRISBII_HOSTS, parsed.hostname) || !own14(FRISBII_REFUSED_PATHS, parsed.pathname))
7148
+ return null;
7149
+ return FRISBII_REFUSED_PATHS[parsed.pathname];
7150
+ }
7151
+ function luhn9(digits3) {
7152
+ let sum = 0;
7153
+ for (let at = digits3.length - 1, double = false; at >= 0; at -= 1, double = !double) {
7154
+ let digit = digits3.charCodeAt(at) - 48;
7155
+ if (double)
7156
+ digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
7157
+ sum += digit;
7158
+ }
7159
+ return sum % 10 === 0;
7160
+ }
7161
+ function readBody23(body) {
7162
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT37)
7163
+ return null;
7164
+ try {
7165
+ const value = JSON.parse(body);
7166
+ return record33(value) && JSON.stringify(value) === body ? value : null;
7167
+ }
7168
+ catch {
7169
+ return null;
7170
+ }
7171
+ }
7172
+ function browserInfo(info) {
7173
+ return record33(info) && Object.keys(info).join() === BROWSER_ORDER.join() && info.javascriptEnabled === true && typeof info.javaEnabled === "boolean" && /^size_[0-9]{3}x[0-9]{3}$/.test(info.challengeWindowSize) && [info.colorDepth, info.screenHeight, info.screenWidth].every((n) => Number.isSafeInteger(n) && n >= 0 && n <= 1e5) && Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440;
7174
+ }
7175
+ function scaBlock(block, target) {
7176
+ if (!record33(block) || !inOrder6(block, SCA_ORDER) || !own14(block, "returnUrl") || !own14(block, "tokenBrowserInfo"))
7177
+ return false;
7178
+ if (!Number.isSafeInteger(block.amount) || block.amount < 0 || typeof block.currency !== "string" || !/^[A-Z]{3}$/.test(block.currency))
7179
+ return false;
7180
+ if (!(absentOrNull(block.orderId) || text9(block.orderId, 128)) || !(absentOrNull(block.orderText) || text9(block.orderText, 512)))
7181
+ return false;
7182
+ if (!(absentOrNull(block.merchantScaData) || record33(block.merchantScaData)))
7183
+ return false;
7184
+ if (!text9(block.returnUrl, 2048) || !browserInfo(block.tokenBrowserInfo))
7185
+ return false;
7186
+ const back = /^https:\/\/checkout\.(reepay|frisbii)\.com\/return\.001\.html\?id=([A-Za-z0-9_-]{8,128})(?:&[A-Za-z0-9_.~%=+/-]*)*$/.exec(block.returnUrl);
7187
+ return back !== null && (target === null || back[1] === target.brand && back[2] === target.session);
7188
+ }
7189
+ function frisbiiBodyVerdict(body, url) {
7190
+ const value = readBody23(body);
7191
+ if (value === null || !inOrder6(value, BODY_ORDER) || !BODY_REQUIRED.every((key) => own14(value, key)) || BODY_REFUSED.some((key) => own14(value, key)))
7192
+ return refuse39("frisbii_body_unsupported");
7193
+ if (value.recurring === true || value.intent === "CHARGE_AND_STORE")
7194
+ return refuse39("frisbii_card_on_file");
7195
+ const target = url === void 0 ? null : frisbiiTokenUrl(url);
7196
+ if (url !== void 0 && target === null)
7197
+ return refuse39("frisbii_body_unsupported");
7198
+ const sound = typeof value.number === "string" && CARD_NUMBER19.test(value.number) && luhn9(value.number) && typeof value.month === "string" && MONTH19.test(value.month) && typeof value.year === "string" && YEAR20.test(value.year) && typeof value.cvv === "string" && SECURITY_CODE23.test(value.cvv) && typeof value.pkey === "string" && IDENTIFIER2.test(value.pkey) && value.recurring === false && (value.cardholder_name === void 0 || text9(value.cardholder_name, 64)) && (value.intent === void 0 || value.intent === "CHARGE") && (absentOrNull(value.recurringAverageAmount) || Number.isSafeInteger(value.recurringAverageAmount) && value.recurringAverageAmount >= 0) && (absentOrNull(value.agreementFilter) || typeof value.agreementFilter === "string" && LABEL.test(value.agreementFilter) || Array.isArray(value.agreementFilter) && value.agreementFilter.length <= 16 && value.agreementFilter.every((entry) => typeof entry === "string" && LABEL.test(entry))) && SCA_RULES.includes(value.strongAuthenticationRule) && (value.tokenStrongAuthenticationRequest === void 0 || scaBlock(value.tokenStrongAuthenticationRequest, target));
7199
+ return sound ? CARD39 : refuse39("frisbii_body_unsupported");
7200
+ }
7201
+ var frisbii_default = /* @__PURE__ */ registerProcessor({
7202
+ psp: FRISBII_PSP,
7203
+ definitions: [
7204
+ {
7205
+ psp: "frisbii",
7206
+ // The hosted page's card request, as the header above reads it, on both brands' card hosts. A test account
7207
+ // shares the live hosts, so no sandbox host is marked. The match reads the host and the path and ends with it. It
7208
+ // also takes the page's two other card paths, /v1/token/cof/ and /v1/token/create_click_to_pay, so the pause
7209
+ // decision holds them, and the body gate refuses every body there; the exact-URL rule below holds the session
7210
+ // query of the card request. Ships dark: served only to a client that declares `frisbii_card_token`, and only for a company
7211
+ // the backend's processor gate turns Frisbii on for.
7212
+ capability: "frisbii_card_token",
7213
+ match: "card\\.(?:reepay|frisbii)\\.com/v1/token/(?:cof/|create_click_to_pay)?",
7214
+ hosts: ["^card\\.reepay\\.com$", "^card\\.frisbii\\.com$"],
7215
+ encoding: "json",
7216
+ // The page sends no header but its content type. Origin, Referer and cookies never ride.
7217
+ passthroughHeaders: [],
7218
+ jsonCardFields: [["number"]]
7219
+ }
7220
+ ],
7221
+ // Only the cardholder's device would send this card, after a person approves; no reviewed list names frisbii.
7222
+ refusedOperations: [FRISBII_OPERATION],
7223
+ // Not surveyed: the card request mints a token and moves no money, and the page then charges the session with it
7224
+ // in a card-free request. Whether the session's own read (checkout-api /v1/checkout/<session>) can confirm that
7225
+ // charge was not read.
7226
+ settlementReadback: "not_surveyed",
7227
+ exactUrl: (url) => isFrisbiiTokenUrl(url) || frisbiiRefusedFlowUrl(url) !== null,
7228
+ // A stored card's token and Click to Pay are refused whatever their body; the card request is judged by its body.
7229
+ bodyGate: (url, body) => {
7230
+ if (url === void 0)
7231
+ return frisbiiBodyVerdict(body);
7232
+ const flow = frisbiiRefusedFlowUrl(url);
7233
+ if (flow !== null)
7234
+ return refuse39(flow);
7235
+ return isFrisbiiTokenUrl(url) ? frisbiiBodyVerdict(body, url) : refuse39("frisbii_url_refused");
7236
+ },
7237
+ limitations: ["A live Frisbii card goes only to a merchant account a reviewed pin lists, and none is pinned yet."]
7238
+ });
7239
+ // src/processors/iyzico.js
7240
+ var IYZICO_PSP = "iyzico";
7241
+ var IYZICO_OPERATION = "iyzico.card_request";
7242
+ var PATHS = ["/payment/iyzipos/checkoutform/auth/ecom", "/payment/iyzipos/checkoutform/initialize3ds/ecom"];
7243
+ var IYZICO_CARD_URLS = /* @__PURE__ */ Object.freeze(["https://api.iyzipay.com", "https://sandbox-api.iyzipay.com"].flatMap((origin) => PATHS.map((path) => `${origin}${path}`)));
7244
+ var IYZICO_BODY_KEYS = /* @__PURE__ */ Object.freeze([
7245
+ "installment",
7246
+ "paidPrice",
7247
+ "paymentChannel",
7248
+ "paymentCard",
7249
+ "buyerProtected",
7250
+ "gsmNumber",
7251
+ "dccPayment",
7252
+ "dccQueryRrn",
7253
+ "pwiMetadata"
7254
+ ]);
7255
+ var IYZICO_CARD_KEYS = /* @__PURE__ */ Object.freeze([
7256
+ "cardNumber",
7257
+ "cardHolderName",
7258
+ "expireYear",
7259
+ "expireMonth",
7260
+ "cvc",
7261
+ "registerConsumerCard",
7262
+ "registerCard"
7263
+ ]);
7264
+ var BODY_LIMIT38 = 4096;
7265
+ var CARD_NUMBER20 = /^[0-9]{12,19}$/;
7266
+ var SECURITY_CODE24 = /^[0-9]{3,4}$/;
7267
+ var MONTH20 = /^(?:0?[1-9]|1[0-2])$/;
7268
+ var YEAR21 = /^(?:[0-9]{2}|20[0-9]{2})$/;
7269
+ var PRICE = /^([1-9][0-9]{0,8}|0)(?:\.([0-9]{1,2}))?$/;
7270
+ var CHANNELS = /* @__PURE__ */ Object.freeze(["WEB", "MOBILE_WEB", "MOBILE_IOS", "MOBILE_ANDROID", "MOBILE_WINDOWS"]);
7271
+ var METADATA_KEYS3 = /* @__PURE__ */ Object.freeze(["lightRedesign", "pwiGrowthActionDisabled"]);
7272
+ var FLAG = /^[A-Za-z_]{1,16}$/;
7273
+ var HOLDER5 = /^[^\x00-\x1f\x7f0-9]{3,100}$/u;
7274
+ var record34 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7275
+ var own15 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7276
+ var inOrder7 = (value, keys) => {
7277
+ let at = 0;
7278
+ for (const name of Object.keys(value)) {
7279
+ while (at < keys.length && keys[at] !== name)
7280
+ at += 1;
7281
+ if (at === keys.length)
7282
+ return false;
7283
+ at += 1;
7284
+ }
7285
+ return true;
7286
+ };
7287
+ var refuse40 = (code) => Object.freeze({ verdict: "refuse", code });
7288
+ var CARD40 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7289
+ function isIyzicoCardUrl(url) {
7290
+ return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
7291
+ }
7292
+ function readBody24(body) {
7293
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT38)
7294
+ return null;
7295
+ try {
7296
+ const value = JSON.parse(body);
7297
+ return record34(value) && JSON.stringify(value) === body ? value : null;
7298
+ }
7299
+ catch {
7300
+ return null;
7301
+ }
7302
+ }
7303
+ function hundredths(price) {
7304
+ const match = typeof price === "number" && Number.isFinite(price) ? PRICE.exec(String(price)) : null;
7305
+ const value = match ? Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0")) : 0;
7306
+ return value > 0 ? value : null;
7307
+ }
7308
+ var holderName2 = (name) => typeof name === "string" && HOLDER5.test(name) && name.trim().split(/\s+/).filter((word) => word.length > 1).length > 1;
7309
+ var metadata = (value) => record34(value) && inOrder7(value, METADATA_KEYS3) && Object.values(value).every((flag3) => Array.isArray(flag3) && flag3.length === 1 && typeof flag3[0] === "string" && FLAG.test(flag3[0]));
7310
+ function iyzicoBodyVerdict(body) {
7311
+ const value = readBody24(body);
7312
+ if (value === null)
7313
+ return refuse40("iyzico_body_unsupported");
7314
+ const card = value.paymentCard;
7315
+ if (record34(card) && (own15(card, "cardToken") || own15(card, "ucsToken") || own15(card, "consumerToken")) && !own15(card, "cardNumber"))
7316
+ return refuse40("iyzico_saved_card");
7317
+ if (own15(value, "dccPayment") || own15(value, "dccQueryRrn"))
7318
+ return refuse40("iyzico_dcc_refused");
7319
+ if (own15(value, "gsmNumber") || own15(value, "buyerProtected") && value.buyerProtected !== false || record34(card) && (own15(card, "registerCard") && card.registerCard !== 0 || own15(card, "registerConsumerCard") && card.registerConsumerCard !== false)) {
7320
+ return refuse40("iyzico_keeps_card");
7321
+ }
7322
+ if (Number.isSafeInteger(value.installment) && value.installment > 1)
7323
+ return refuse40("iyzico_installments_refused");
7324
+ if (!inOrder7(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own15(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own15(value, "pwiMetadata") && !metadata(value.pwiMetadata))
7325
+ return refuse40("iyzico_body_unsupported");
7326
+ if (!record34(card) || Object.keys(card).join() !== IYZICO_CARD_KEYS.join() || typeof card.cardNumber !== "string" || !CARD_NUMBER20.test(card.cardNumber) || !holderName2(card.cardHolderName) || typeof card.expireYear !== "string" || !YEAR21.test(card.expireYear) || typeof card.expireMonth !== "string" || !MONTH20.test(card.expireMonth) || typeof card.cvc !== "string" || !SECURITY_CODE24.test(card.cvc))
7327
+ return refuse40("iyzico_body_unsupported");
7328
+ return CARD40;
7329
+ }
7330
+ var iyzico_default = /* @__PURE__ */ registerProcessor({
7331
+ psp: IYZICO_PSP,
7332
+ definitions: [
6326
7333
  {
6327
7334
  psp: "iyzico",
6328
7335
  // The Checkout Form's card payment, as the header above reads it. Sandbox has its own host, so the device sends
@@ -6351,7 +7358,7 @@ var iyzico_default = /* @__PURE__ */ registerProcessor({
6351
7358
  source: "https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve"
6352
7359
  },
6353
7360
  exactUrl: isIyzicoCardUrl,
6354
- bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ? refuse38("iyzico_url_refused") : iyzicoBodyVerdict(body)
7361
+ bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ? refuse40("iyzico_url_refused") : iyzicoBodyVerdict(body)
6355
7362
  });
6356
7363
  // src/processors/midtrans.js
6357
7364
  var MIDTRANS_PSP = "midtrans";
@@ -6359,15 +7366,15 @@ var MIDTRANS_OPERATION = "midtrans.card_request";
6359
7366
  var MIDTRANS_TOKEN_URL = "https://api.midtrans.com/v2/token";
6360
7367
  var MIDTRANS_SANDBOX_TOKEN_URL = "https://api.sandbox.midtrans.com/v2/token";
6361
7368
  var MIDTRANS_TOKEN_KEYS = /* @__PURE__ */ Object.freeze(["card_cvv", "card_number", "card_exp_month", "card_exp_year", "installment_term"]);
6362
- var BODY_LIMIT37 = 4096;
6363
- var CARD_NUMBER20 = /^[0-9]{12,19}$/;
6364
- var SECURITY_CODE24 = /^[0-9]{3,4}$/;
6365
- var MONTH20 = /^(?:0[1-9]|1[0-2])$/;
6366
- var YEAR21 = /^20[0-9]{2}$/;
7369
+ var BODY_LIMIT39 = 4096;
7370
+ var CARD_NUMBER21 = /^[0-9]{12,19}$/;
7371
+ var SECURITY_CODE25 = /^[0-9]{3,4}$/;
7372
+ var MONTH21 = /^(?:0[1-9]|1[0-2])$/;
7373
+ var YEAR22 = /^20[0-9]{2}$/;
6367
7374
  var TERM = /^[0-9]{1,3}$/;
6368
- var record34 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
6369
- var own14 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
6370
- var inOrder7 = (value, keys) => {
7375
+ var record35 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7376
+ var own16 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7377
+ var inOrder8 = (value, keys) => {
6371
7378
  let at = 0;
6372
7379
  for (const name of Object.keys(value)) {
6373
7380
  while (at < keys.length && keys[at] !== name)
@@ -6378,18 +7385,18 @@ var inOrder7 = (value, keys) => {
6378
7385
  }
6379
7386
  return true;
6380
7387
  };
6381
- var refuse39 = (code) => Object.freeze({ verdict: "refuse", code });
6382
- var CARD38 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7388
+ var refuse41 = (code) => Object.freeze({ verdict: "refuse", code });
7389
+ var CARD41 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6383
7390
  function isMidtransTokenUrl(url) {
6384
7391
  return url === MIDTRANS_TOKEN_URL || url === MIDTRANS_SANDBOX_TOKEN_URL;
6385
7392
  }
6386
- function readBody23(body) {
6387
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT37)
7393
+ function readBody25(body) {
7394
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT39)
6388
7395
  return null;
6389
7396
  let value;
6390
7397
  try {
6391
7398
  value = JSON.parse(body);
6392
- if (!record34(value) || JSON.stringify(value) !== body)
7399
+ if (!record35(value) || JSON.stringify(value) !== body)
6393
7400
  return null;
6394
7401
  }
6395
7402
  catch {
@@ -6398,20 +7405,20 @@ function readBody23(body) {
6398
7405
  return value;
6399
7406
  }
6400
7407
  function midtransBodyVerdict(body) {
6401
- const value = readBody23(body);
6402
- if (value === null || !inOrder7(value, MIDTRANS_TOKEN_KEYS)) {
6403
- if (record34(value) && (own14(value, "token_id") || own14(value, "two_click")) && !own14(value, "card_number"))
6404
- return refuse39("midtrans_saved_card");
6405
- return refuse39("midtrans_body_unsupported");
6406
- }
6407
- if (!own14(value, "card_cvv") || !own14(value, "card_number") || !own14(value, "card_exp_month") || !own14(value, "card_exp_year")) {
6408
- return refuse39("midtrans_body_unsupported");
6409
- }
6410
- if (typeof value.card_cvv !== "string" || !SECURITY_CODE24.test(value.card_cvv) || typeof value.card_number !== "string" || !CARD_NUMBER20.test(value.card_number) || typeof value.card_exp_month !== "string" || !MONTH20.test(value.card_exp_month) || typeof value.card_exp_year !== "string" || !YEAR21.test(value.card_exp_year))
6411
- return refuse39("midtrans_body_unsupported");
6412
- if (own14(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
6413
- return refuse39("midtrans_body_unsupported");
6414
- return CARD38;
7408
+ const value = readBody25(body);
7409
+ if (value === null || !inOrder8(value, MIDTRANS_TOKEN_KEYS)) {
7410
+ if (record35(value) && (own16(value, "token_id") || own16(value, "two_click")) && !own16(value, "card_number"))
7411
+ return refuse41("midtrans_saved_card");
7412
+ return refuse41("midtrans_body_unsupported");
7413
+ }
7414
+ if (!own16(value, "card_cvv") || !own16(value, "card_number") || !own16(value, "card_exp_month") || !own16(value, "card_exp_year")) {
7415
+ return refuse41("midtrans_body_unsupported");
7416
+ }
7417
+ if (typeof value.card_cvv !== "string" || !SECURITY_CODE25.test(value.card_cvv) || typeof value.card_number !== "string" || !CARD_NUMBER21.test(value.card_number) || typeof value.card_exp_month !== "string" || !MONTH21.test(value.card_exp_month) || typeof value.card_exp_year !== "string" || !YEAR22.test(value.card_exp_year))
7418
+ return refuse41("midtrans_body_unsupported");
7419
+ if (own16(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
7420
+ return refuse41("midtrans_body_unsupported");
7421
+ return CARD41;
6415
7422
  }
6416
7423
  var midtrans_default = /* @__PURE__ */ registerProcessor({
6417
7424
  psp: MIDTRANS_PSP,
@@ -6429,18 +7436,111 @@ var midtrans_default = /* @__PURE__ */ registerProcessor({
6429
7436
  sandboxHosts: ["^api\\.sandbox\\.midtrans\\.com$"],
6430
7437
  hostEnvironmentPinned: true,
6431
7438
  encoding: "json",
6432
- // Snap's own headers: the publishable client key (Authorization Basic) and X-Service. Origin, Referer and
6433
- // cookies never ride.
6434
- passthroughHeaders: ["^authorization$", "^x-service$"],
6435
- jsonCardFields: [["card_number"]]
7439
+ // Snap's own headers: the publishable client key (Authorization Basic) and X-Service. Origin, Referer and
7440
+ // cookies never ride.
7441
+ passthroughHeaders: ["^authorization$", "^x-service$"],
7442
+ jsonCardFields: [["card_number"]]
7443
+ }
7444
+ ],
7445
+ // Only the cardholder's device sends a token, after a person approves; no reviewed list names midtrans.
7446
+ refusedOperations: [MIDTRANS_OPERATION],
7447
+ // Not surveyed: the token moves no money, and the merchant's own charge names its status by the order id alone.
7448
+ settlementReadback: "not_surveyed",
7449
+ exactUrl: isMidtransTokenUrl,
7450
+ bodyGate: (url, body) => url !== void 0 && !isMidtransTokenUrl(url) ? { verdict: "refuse", code: "midtrans_url_refused" } : midtransBodyVerdict(body)
7451
+ });
7452
+ // src/processors/monei.js
7453
+ var MONEI_PSP = "monei";
7454
+ var MONEI_OPERATION = "monei.card_request";
7455
+ var MONEI_TOKENS_URL = "https://api.monei.com/v1/tokens";
7456
+ var BODY_LIMIT40 = 1024;
7457
+ var PAYMENT_ID = /^(?:[0-9a-f]{32}|[0-9a-f]{40})$/;
7458
+ var MONEI_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "expMonth", "expYear", "cvc"]);
7459
+ var NUMBER8 = /^[0-9]{12,19}$/;
7460
+ var MONTH22 = /^(?:0[1-9]|1[0-2])$/;
7461
+ var YEAR23 = /^[0-9]{2}$/;
7462
+ var CODE8 = /^[0-9]{3,4}$/;
7463
+ var record36 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7464
+ var keysAre2 = (value, keys) => {
7465
+ const found = Object.keys(value);
7466
+ return found.length === keys.length && found.every((key, at) => key === keys[at]);
7467
+ };
7468
+ var refuse42 = (code) => Object.freeze({ verdict: "refuse", code });
7469
+ var CARD42 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7470
+ function luhn10(digits3) {
7471
+ let sum = 0;
7472
+ for (let at = 0; at < digits3.length; at += 1) {
7473
+ let digit = Number(digits3[digits3.length - 1 - at]);
7474
+ if (at % 2 === 1) {
7475
+ digit *= 2;
7476
+ if (digit > 9)
7477
+ digit -= 9;
7478
+ }
7479
+ sum += digit;
7480
+ }
7481
+ return sum % 10 === 0;
7482
+ }
7483
+ function isMoneiTokensUrl(url) {
7484
+ return url === MONEI_TOKENS_URL;
7485
+ }
7486
+ function readBody26(body) {
7487
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT40)
7488
+ return null;
7489
+ try {
7490
+ const value = JSON.parse(body);
7491
+ return record36(value) && JSON.stringify(value) === body ? value : null;
7492
+ }
7493
+ catch {
7494
+ return null;
7495
+ }
7496
+ }
7497
+ function moneiBodyVerdict(body, url) {
7498
+ if (url !== void 0 && !isMoneiTokensUrl(url))
7499
+ return refuse42("monei_url_refused");
7500
+ const value = readBody26(body);
7501
+ if (value === null || !keysAre2(value, ["paymentId", "paymentMethod"]) || typeof value.paymentId !== "string" || !PAYMENT_ID.test(value.paymentId))
7502
+ return refuse42("monei_body_unsupported");
7503
+ const method = value.paymentMethod;
7504
+ if (!record36(method) || !keysAre2(method, ["card"]) || !record36(method.card) || !keysAre2(method.card, MONEI_CARD_KEYS))
7505
+ return refuse42("monei_body_unsupported");
7506
+ const { number, expMonth, expYear, cvc } = method.card;
7507
+ if (![number, expMonth, expYear, cvc].every((part) => typeof part === "string"))
7508
+ return refuse42("monei_body_unsupported");
7509
+ if (!NUMBER8.test(number) || !luhn10(number) || !MONTH22.test(expMonth) || !YEAR23.test(expYear) || !CODE8.test(cvc))
7510
+ return refuse42("monei_body_unsupported");
7511
+ return CARD42;
7512
+ }
7513
+ var MONEI_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
7514
+ Object.freeze({ merchant: "Genuins", accountIds: Object.freeze(["8d58ab4c-4ad0-4053-b18f-79d80e9ee158"]), merchantUrls: Object.freeze(["https://genuins.com/"]) })
7515
+ ]);
7516
+ var monei_default = /* @__PURE__ */ registerProcessor({
7517
+ psp: MONEI_PSP,
7518
+ definitions: [
7519
+ {
7520
+ psp: "monei",
7521
+ // The card frame's token request, as the header above reads it. One host serves test and live payments alike,
7522
+ // so no sandbox host is marked: MONEI's record of the payment names its mode, and the device sends a test payment
7523
+ // only MONEI's documented test cards (moneiDeviceRefusal). The frame sets no deadline on the fetch, so the
7524
+ // cardholder approves at the shopper's Pay. `(?![\w/.%-])` ends the path for a consumer that tests `match`
7525
+ // unanchored, and the exact-URL rule below holds the rest. Ships dark: served only to a client that declares
7526
+ // `monei_card_token`, and gated off for every company until the backend's gate names one.
7527
+ capability: "monei_card_token",
7528
+ match: "api\\.monei\\.com/v1/tokens(?![\\w/.%-])",
7529
+ hosts: ["^api\\.monei\\.com$"],
7530
+ encoding: "json",
7531
+ // The frame's two device headers. Origin, Referer and cookies never ride.
7532
+ passthroughHeaders: ["^x-client-env$", "^x-client-fingerprint$"],
7533
+ jsonCardFields: [["paymentMethod", "card", "number"]]
6436
7534
  }
6437
7535
  ],
6438
- // Only the cardholder's device sends a token, after a person approves; no reviewed list names midtrans.
6439
- refusedOperations: [MIDTRANS_OPERATION],
6440
- // Not surveyed: the token moves no money, and the merchant's own charge names its status by the order id alone.
7536
+ // Only the cardholder's device sends a card, after a person approves; no reviewed list names monei.
7537
+ refusedOperations: [MONEI_OPERATION],
7538
+ // Not surveyed: the card request mints a token and moves no money; MONEI's confirm, which the page sends, charges it.
6441
7539
  settlementReadback: "not_surveyed",
6442
- exactUrl: isMidtransTokenUrl,
6443
- bodyGate: (url, body) => url !== void 0 && !isMidtransTokenUrl(url) ? { verdict: "refuse", code: "midtrans_url_refused" } : midtransBodyVerdict(body)
7540
+ exactUrl: isMoneiTokensUrl,
7541
+ bodyGate: (url, body) => moneiBodyVerdict(body, url)
7542
+ // No amount reader: the request names none. MONEI's record of the payment names it, and the device holds that record
7543
+ // to the approved amount before it writes any card.
6444
7544
  });
6445
7545
  // src/processors/oceanpayment.js
6446
7546
  var OCEANPAYMENT_PSP = "oceanpayment";
@@ -6471,10 +7571,10 @@ var OCEANPAYMENT_FORM_FIELDS = /* @__PURE__ */ Object.freeze([
6471
7571
  "methods",
6472
7572
  "reference"
6473
7573
  ]);
6474
- var URL_LIMIT14 = 2048;
6475
- var BODY_LIMIT38 = 8192;
7574
+ var URL_LIMIT16 = 2048;
7575
+ var BODY_LIMIT41 = 8192;
6476
7576
  var SEND_PAY = /^\/gateway\/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}$/;
6477
- var own15 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7577
+ var own17 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
6478
7578
  var exact4 = (pattern, value) => typeof value === "string" && pattern.test(value);
6479
7579
  var CARD_RUN = /[0-9]{12}/;
6480
7580
  var printable5 = (max) => (value) => typeof value === "string" && value.length <= max && /^[\x20-\x7e]*$/.test(value) && !CARD_RUN.test(value);
@@ -6512,7 +7612,7 @@ var SHAPES2 = /* @__PURE__ */ new Map([
6512
7612
  ["button", (v) => v === ""]
6513
7613
  ]);
6514
7614
  function oceanpaymentSendPayUrl(url) {
6515
- if (typeof url !== "string" || url.length > URL_LIMIT14 || url.includes("?") || url.includes("#"))
7615
+ if (typeof url !== "string" || url.length > URL_LIMIT16 || url.includes("?") || url.includes("#"))
6516
7616
  return null;
6517
7617
  let parsed;
6518
7618
  try {
@@ -6521,7 +7621,7 @@ function oceanpaymentSendPayUrl(url) {
6521
7621
  catch {
6522
7622
  return null;
6523
7623
  }
6524
- if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own15(OCEANPAYMENT_HOSTS, parsed.hostname) || !SEND_PAY.test(parsed.pathname))
7624
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own17(OCEANPAYMENT_HOSTS, parsed.hostname) || !SEND_PAY.test(parsed.pathname))
6525
7625
  return null;
6526
7626
  return Object.freeze({ host: parsed.hostname, environment: OCEANPAYMENT_HOSTS[parsed.hostname] });
6527
7627
  }
@@ -6549,7 +7649,7 @@ function formDecode2(raw) {
6549
7649
  return formEncode3(value) === raw ? value : null;
6550
7650
  }
6551
7651
  function readPairs2(body) {
6552
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT38)
7652
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT41)
6553
7653
  return null;
6554
7654
  const pairs = [];
6555
7655
  for (const chunk of body.split("&")) {
@@ -6634,7 +7734,7 @@ var PAYMENTWALL_PSP = "paymentwall";
6634
7734
  var PAYMENTWALL_OPERATION = "paymentwall.card_request";
6635
7735
  var PAYMENTWALL_TOKEN_URL = "https://pwgateway.com/api/token";
6636
7736
  var PAYMENTWALL_SANDBOX_TOKEN_URL = "https://api.paymentwall.com/api/brick/token";
6637
- var BODY_LIMIT39 = 2048;
7737
+ var BODY_LIMIT42 = 2048;
6638
7738
  var KEY3 = "public_key";
6639
7739
  var PUBLIC_KEY2 = /^(?:t_)?[A-Za-z0-9]{16,64}$/;
6640
7740
  var SHAPES3 = /* @__PURE__ */ Object.freeze({
@@ -6644,9 +7744,9 @@ var SHAPES3 = /* @__PURE__ */ Object.freeze({
6644
7744
  "card[exp_year]": /^(?:[0-9]{2}|20[0-9]{2})$/,
6645
7745
  "card[cvv]": /^[0-9]{3,4}$/
6646
7746
  });
6647
- var refuse40 = (code) => Object.freeze({ verdict: "refuse", code });
6648
- var CARD39 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6649
- function luhn9(digits3) {
7747
+ var refuse43 = (code) => Object.freeze({ verdict: "refuse", code });
7748
+ var CARD43 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7749
+ function luhn11(digits3) {
6650
7750
  let sum = 0;
6651
7751
  for (let at = 0; at < digits3.length; at += 1) {
6652
7752
  let digit = Number(digits3[digits3.length - 1 - at]);
@@ -6673,7 +7773,7 @@ function paymentwallKeyEnvironment(publicKey) {
6673
7773
  return publicKey.startsWith("t_") ? "sandbox" : "production";
6674
7774
  }
6675
7775
  function readPairs3(body) {
6676
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT39 || !/^[A-Za-z0-9_[\]=&]+$/.test(body))
7776
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT42 || !/^[A-Za-z0-9_[\]=&]+$/.test(body))
6677
7777
  return null;
6678
7778
  const pairs = /* @__PURE__ */ new Map();
6679
7779
  for (const chunk of body.split("&")) {
@@ -6689,21 +7789,21 @@ function readPairs3(body) {
6689
7789
  }
6690
7790
  function paymentwallBodyVerdict(body, url) {
6691
7791
  if (url !== void 0 && !isPaymentwallTokenUrl(url))
6692
- return refuse40("paymentwall_url_refused");
7792
+ return refuse43("paymentwall_url_refused");
6693
7793
  const pairs = readPairs3(body);
6694
7794
  if (pairs === null)
6695
- return refuse40("paymentwall_body_unsupported");
7795
+ return refuse43("paymentwall_body_unsupported");
6696
7796
  if (pairs.has("card[token]") && !pairs.has("card[number]"))
6697
- return refuse40("paymentwall_saved_card");
7797
+ return refuse43("paymentwall_saved_card");
6698
7798
  const keys = Object.keys(SHAPES3);
6699
7799
  if (pairs.size !== keys.length || !keys.every((key) => pairs.has(key) && SHAPES3[key].test(pairs.get(key)))) {
6700
- return refuse40("paymentwall_body_unsupported");
7800
+ return refuse43("paymentwall_body_unsupported");
6701
7801
  }
6702
- if (!luhn9(pairs.get("card[number]")))
6703
- return refuse40("paymentwall_body_unsupported");
7802
+ if (!luhn11(pairs.get("card[number]")))
7803
+ return refuse43("paymentwall_body_unsupported");
6704
7804
  if (url !== void 0 && paymentwallKeyEnvironment(pairs.get(KEY3)) !== paymentwallUrlEnvironment(url))
6705
- return refuse40("paymentwall_key_refused");
6706
- return CARD39;
7805
+ return refuse43("paymentwall_key_refused");
7806
+ return CARD43;
6707
7807
  }
6708
7808
  var paymentwall_default = /* @__PURE__ */ registerProcessor({
6709
7809
  psp: PAYMENTWALL_PSP,
@@ -6732,112 +7832,15 @@ var paymentwall_default = /* @__PURE__ */ registerProcessor({
6732
7832
  exactUrl: isPaymentwallTokenUrl,
6733
7833
  bodyGate: (url, body) => paymentwallBodyVerdict(body, url)
6734
7834
  });
6735
- // src/processors/ekashu.js
6736
- var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
6737
- var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
6738
- var EKASHU_SIGNED_FIELDS = Object.freeze([
6739
- "ekashu_3d_secure_verify",
6740
- "ekashu_amount",
6741
- "ekashu_amount_format",
6742
- "ekashu_auto_confirm",
6743
- "ekashu_callback_failure_url",
6744
- "ekashu_callback_include_post",
6745
- "ekashu_callback_success_url",
6746
- "ekashu_card_address_editable",
6747
- "ekashu_card_address_required",
6748
- "ekashu_card_address_verify",
6749
- "ekashu_card_email_address_mandatory",
6750
- "ekashu_card_phone_number_mandatory",
6751
- "ekashu_card_title_mandatory",
6752
- "ekashu_card_zip_code_verify",
6753
- "ekashu_currency",
6754
- "ekashu_delivery_address_editable",
6755
- "ekashu_delivery_address_required",
6756
- "ekashu_delivery_email_address_mandatory",
6757
- "ekashu_delivery_phone_number_mandatory",
6758
- "ekashu_delivery_title_mandatory",
6759
- "ekashu_description",
6760
- "ekashu_device",
6761
- "ekashu_duplicate_check",
6762
- "ekashu_duplicate_minutes",
6763
- "ekashu_failure_return_text",
6764
- "ekashu_failure_url",
6765
- "ekashu_hash_code_format",
6766
- "ekashu_hash_code_type",
6767
- "ekashu_hash_code_version",
6768
- "ekashu_include_post",
6769
- "ekashu_invoice_address_editable",
6770
- "ekashu_invoice_address_required",
6771
- "ekashu_invoice_email_address_mandatory",
6772
- "ekashu_invoice_phone_number_mandatory",
6773
- "ekashu_invoice_title_mandatory",
6774
- "ekashu_locale",
6775
- "ekashu_payment_methods",
6776
- "ekashu_reference",
6777
- "ekashu_request_type",
6778
- "ekashu_return_text",
6779
- "ekashu_seller_address",
6780
- "ekashu_seller_email_address",
6781
- "ekashu_seller_id",
6782
- "ekashu_seller_key",
6783
- "ekashu_seller_name",
6784
- "ekashu_shortcut_icon",
6785
- "ekashu_style_sheet",
6786
- "ekashu_success_url",
6787
- "ekashu_title",
6788
- "ekashu_verification_value_mask",
6789
- "ekashu_verification_value_verify",
6790
- "ekashu_viewport"
6791
- ]);
6792
- var REQUIRED = Object.freeze([
6793
- "ekashu_seller_id",
6794
- "ekashu_seller_key",
6795
- "ekashu_amount",
6796
- "ekashu_currency",
6797
- "ekashu_reference",
6798
- "ekashu_hash_code",
6799
- "ekashu_hash_code_type",
6800
- "ekashu_hash_code_version",
6801
- "ekashu_success_url",
6802
- "ekashu_failure_url",
6803
- "ekashu_callback_success_url"
6804
- ]);
6805
- var CARD_KEYS16 = Object.freeze([
6806
- "ekashu_card_number",
6807
- "ekashu_expires_end_month",
6808
- "ekashu_expires_end_year",
6809
- "ekashu_verification_value",
6810
- "ekashu_valid_from_month",
6811
- "ekashu_valid_from_year",
6812
- "ekashu_issue_number"
6813
- ]);
6814
- var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
6815
- var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
6816
- var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
6817
- var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
6818
- var MAX_ENTRY = 16 * 1024;
6819
- var MAX_PAGE = 256 * 1024;
6820
- var EKASHU_SELLERS = Object.freeze([
6821
- Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
6822
- ]);
6823
- var CARD_FIELDS = Object.freeze({
6824
- number: "ekashu_card_number",
6825
- month: "ekashu_expires_end_month",
6826
- year: "ekashu_expires_end_year",
6827
- cvc: "ekashu_verification_value"
6828
- });
6829
- var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
6830
- var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
6831
- var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
6832
7835
  // src/processors/payplug.js
6833
7836
  var PAYPLUG_PSP = "payplug";
6834
7837
  var PAYPLUG_OPERATION = "payplug.hosted_sale";
6835
7838
  var PAYPLUG_HOST = "secure.payplug.com";
6836
7839
  var ENTRY_PATH = /^\/pay\/(?:(test)\/)?([A-Za-z0-9]{22})$/;
6837
- var MAX_URL = 256;
6838
- var field2 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
7840
+ var MAX_URL3 = 256;
7841
+ var field4 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
6839
7842
  function payplugEntry(raw) {
6840
- if (typeof raw !== "string" || raw.length > MAX_URL || raw.includes("?") || raw.includes("#"))
7843
+ if (typeof raw !== "string" || raw.length > MAX_URL3 || raw.includes("?") || raw.includes("#"))
6841
7844
  return null;
6842
7845
  let url;
6843
7846
  try {
@@ -6859,7 +7862,7 @@ var PAYPLUG_MERCHANTS = Object.freeze([
6859
7862
  ]);
6860
7863
  var ACCOUNT_ID = /^[A-Za-z0-9-]{1,64}$/;
6861
7864
  function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
6862
- if (typeof checkoutOrigin !== "string" || checkoutOrigin.length > MAX_URL || !Array.isArray(merchants))
7865
+ if (typeof checkoutOrigin !== "string" || checkoutOrigin.length > MAX_URL3 || !Array.isArray(merchants))
6863
7866
  return null;
6864
7867
  let url;
6865
7868
  try {
@@ -6875,16 +7878,16 @@ function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
6875
7878
  }
6876
7879
  function checkPayplugEntry(body, { url = null, checkoutOrigin = null, merchants = PAYPLUG_MERCHANTS } = {}) {
6877
7880
  if (body !== void 0 && body !== null && body !== "")
6878
- return field2("(body)", "not_an_entry");
7881
+ return field4("(body)", "not_an_entry");
6879
7882
  const entry = payplugEntry(url);
6880
7883
  if (!entry)
6881
- return field2("(url)", "malformed_field");
7884
+ return field4("(url)", "malformed_field");
6882
7885
  const seller = payplugMerchant(checkoutOrigin, merchants);
6883
7886
  if (!seller)
6884
- return field2("(checkout_origin)", "seller_unreviewed");
7887
+ return field4("(checkout_origin)", "seller_unreviewed");
6885
7888
  return { ok: true, pairs: [], gated: false, dedupe: [entry.id], paymentId: entry.id, sandbox: entry.test, seller };
6886
7889
  }
6887
- var MAX_PAGE2 = 512 * 1024;
7890
+ var MAX_PAGE5 = 512 * 1024;
6888
7891
  var PAYPLUG_REFUSALS = Object.freeze(["payplug_failed", "payplug_expired", "payplug_cancelled"]);
6889
7892
  var payplug_default = /* @__PURE__ */ registerProcessor({
6890
7893
  psp: PAYPLUG_PSP,
@@ -6934,11 +7937,129 @@ var payplug_default = /* @__PURE__ */ registerProcessor({
6934
7937
  "PayPlug sends the buyer to the merchant's return page whether the payment succeeded or not, so the browser receives a submission notice, not the processor result."
6935
7938
  ]
6936
7939
  });
7940
+ // src/processors/paystack.js
7941
+ var PAYSTACK_PSP = "paystack";
7942
+ var PAYSTACK_OPERATION = "paystack.card_request";
7943
+ var PAYSTACK_CHARGE_URL = "https://standard.paystack.co/charge/";
7944
+ var PAYSTACK_BODY_KEYS = /* @__PURE__ */ Object.freeze([
7945
+ "clientdata",
7946
+ "last4",
7947
+ "trans",
7948
+ "access_code",
7949
+ "device",
7950
+ "offset",
7951
+ "remember_card",
7952
+ "card_holder_name",
7953
+ "transaction_type"
7954
+ ]);
7955
+ var OPTIONAL = /* @__PURE__ */ new Set(["access_code", "card_holder_name", "transaction_type"]);
7956
+ var BODY_LIMIT43 = 4096;
7957
+ var CIPHERTEXT_BYTES2 = [62, 63, 64];
7958
+ var BASE646 = /^[A-Za-z0-9+/]+={0,2}$/;
7959
+ var SHAPES4 = /* @__PURE__ */ Object.freeze({
7960
+ last4: /^[0-9]{4}$/,
7961
+ trans: /^[0-9]{1,20}$/,
7962
+ access_code: /^[A-Za-z0-9]{1,64}$/,
7963
+ device: /^[\x21-\x7e]{1,512}$/,
7964
+ offset: /^-?[0-9]{1,3}$/,
7965
+ remember_card: /^false$/,
7966
+ // A name carries no digit, so no card number can ride in it.
7967
+ card_holder_name: /^[^\x00-\x1f\x7f0-9]{1,128}$/u,
7968
+ transaction_type: /^[a-z_]{1,32}$/
7969
+ });
7970
+ var own18 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7971
+ var refuse44 = (code) => Object.freeze({ verdict: "refuse", code });
7972
+ function paystackFormValue(value) {
7973
+ return encodeURIComponent(String(value)).replace(/%20/g, "+").replace(/[!'()*~]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
7974
+ }
7975
+ function paystackFormBody(entries) {
7976
+ return entries.map(([key, value]) => `${paystackFormValue(key)}=${paystackFormValue(value)}`).join("&");
7977
+ }
7978
+ function isPaystackChargeUrl(url) {
7979
+ return url === PAYSTACK_CHARGE_URL;
7980
+ }
7981
+ function isCiphertext2(value) {
7982
+ if (value.length % 4 !== 0 || !BASE646.test(value))
7983
+ return false;
7984
+ let binary;
7985
+ try {
7986
+ binary = atob(value);
7987
+ }
7988
+ catch {
7989
+ return false;
7990
+ }
7991
+ return btoa(binary) === value && CIPHERTEXT_BYTES2.includes(binary.length);
7992
+ }
7993
+ function readForm3(body) {
7994
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT43)
7995
+ return null;
7996
+ const entries = [];
7997
+ for (const part of body.split("&")) {
7998
+ const at = part.indexOf("=");
7999
+ if (at <= 0)
8000
+ return null;
8001
+ try {
8002
+ entries.push([decodeURIComponent(part.slice(0, at).replace(/\+/g, " ")), decodeURIComponent(part.slice(at + 1).replace(/\+/g, " "))]);
8003
+ }
8004
+ catch {
8005
+ return null;
8006
+ }
8007
+ }
8008
+ return paystackFormBody(entries) === body ? entries : null;
8009
+ }
8010
+ function paystackBodyVerdict(body) {
8011
+ const entries = readForm3(body);
8012
+ if (entries === null)
8013
+ return refuse44("paystack_body_unsupported");
8014
+ const keys = entries.map(([key]) => key);
8015
+ if (keys.includes("subscription"))
8016
+ return refuse44("paystack_subscription");
8017
+ if (keys.includes("remember_card") && entries.find(([key]) => key === "remember_card")[1] !== "false")
8018
+ return refuse44("paystack_saved_card");
8019
+ const expected = PAYSTACK_BODY_KEYS.filter((key) => !OPTIONAL.has(key) || keys.includes(key));
8020
+ if (keys.length !== expected.length || keys.some((key, i) => key !== expected[i]))
8021
+ return refuse44("paystack_body_unsupported");
8022
+ const fields = Object.fromEntries(entries);
8023
+ if (!isCiphertext2(fields.clientdata))
8024
+ return refuse44("paystack_body_unsupported");
8025
+ for (const [key, shape] of Object.entries(SHAPES4)) {
8026
+ if (own18(fields, key) && !shape.test(fields[key]))
8027
+ return refuse44("paystack_body_unsupported");
8028
+ }
8029
+ return Object.freeze({ verdict: "card", fields: Object.freeze(fields) });
8030
+ }
8031
+ var paystack_default = /* @__PURE__ */ registerProcessor({
8032
+ psp: PAYSTACK_PSP,
8033
+ definitions: [
8034
+ {
8035
+ psp: "paystack",
8036
+ // The card page's charge, as the header above reads it. Live and test transactions share standard.paystack.co,
8037
+ // so no sandbox host is listed and no environment is pinned. Ships dark: served only to a client that declares
8038
+ // `paystack_pinned_key`, and only for a company the backend's processor gate turns Paystack on for.
8039
+ // `(?![\w/.%?#-])` ends the path for a consumer that tests `match` unanchored; the exact-URL rule takes no query.
8040
+ capability: "paystack_pinned_key",
8041
+ match: "standard\\.paystack\\.co/charge/(?![\\w/.%?#-])",
8042
+ hosts: ["^standard\\.paystack\\.co$"],
8043
+ encoding: "form",
8044
+ // The browser's language rides as the page sent it; Origin, Referer and cookies never do (the page sends no cookie).
8045
+ passthroughHeaders: ["^accept-language$"],
8046
+ cardFields: ["clientdata"]
8047
+ }
8048
+ ],
8049
+ // Only the cardholder's device sends this charge, after a person approves; no reviewed list names paystack.
8050
+ refusedOperations: [PAYSTACK_OPERATION],
8051
+ // Not surveyed: reading a charge back takes the merchant's secret key, which Agentcard never holds.
8052
+ settlementReadback: "not_surveyed",
8053
+ exactUrl: isPaystackChargeUrl,
8054
+ bodyGate: (url, body) => url !== void 0 && !isPaystackChargeUrl(url) ? refuse44("paystack_url_refused") : paystackBodyVerdict(body),
8055
+ // No amount reader: the charge names none, so the agent's pair is the figure the cardholder approves.
8056
+ limitations: ["The charge names no merchant and no amount: Paystack's transaction binds both, so the cardholder approves the agent's figure for whichever Paystack merchant opened the checkout."]
8057
+ });
6937
8058
  // src/processors/processout.js
6938
8059
  var PROCESSOUT_PSP = "processout";
6939
8060
  var PROCESSOUT_OPERATION = "processout.card_request";
6940
- var URL_LIMIT15 = 512;
6941
- var BODY_LIMIT40 = 4096;
8061
+ var URL_LIMIT17 = 512;
8062
+ var BODY_LIMIT44 = 4096;
6942
8063
  var CARD_URL2 = /^https:\/\/api\.processout\.com\/cards\?legacyrequest=true&project_id=((?:test-)?proj_[A-Za-z0-9]{16,64})&x-Content-Type=application\/json&x-API-Version=1\.3\.0\.0&x-Authorization=Basic%20([A-Za-z0-9+/]{4,256}={0,2})$/;
6943
8064
  var PAGE_KEYS2 = /* @__PURE__ */ Object.freeze(["name", "contact", "preferred_scheme"]);
6944
8065
  var CONTACT_KEYS = /* @__PURE__ */ Object.freeze(["address1", "address2", "city", "state", "country_code", "zip"]);
@@ -6953,31 +8074,31 @@ var DEVICE_KEYS4 = /* @__PURE__ */ Object.freeze([
6953
8074
  ]);
6954
8075
  var PROCESSOUT_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "exp_month", "exp_year", "cvc2"]);
6955
8076
  var BODY_KEYS3 = /* @__PURE__ */ new Set([...PAGE_KEYS2, "device", ...DEVICE_KEYS4, ...PROCESSOUT_CARD_KEYS]);
6956
- var NUMBER8 = /^[0-9]{12,19}$/;
6957
- var MONTH21 = /^(?:[1-9]|1[0-2])$/;
6958
- var YEAR22 = /^20[0-9]{2}$/;
6959
- var CODE8 = /^[0-9]{3,4}$/;
8077
+ var NUMBER9 = /^[0-9]{12,19}$/;
8078
+ var MONTH23 = /^(?:[1-9]|1[0-2])$/;
8079
+ var YEAR24 = /^20[0-9]{2}$/;
8080
+ var CODE9 = /^[0-9]{3,4}$/;
6960
8081
  var TEXT_LIMIT14 = 256;
6961
8082
  var SCHEME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
6962
8083
  var LANGUAGE5 = /^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8}){0,4}$/;
6963
8084
  var PAN_LIKE7 = /(?:[0-9][^0-9A-Za-z]*){12,}/;
6964
- var record35 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
6965
- var own16 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
6966
- var refuse41 = (code) => Object.freeze({ verdict: "refuse", code });
6967
- var CARD40 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
6968
- var BASE646 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
6969
- function base64Of(text9) {
8085
+ var record37 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
8086
+ var own19 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
8087
+ var refuse45 = (code) => Object.freeze({ verdict: "refuse", code });
8088
+ var CARD44 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
8089
+ var BASE647 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8090
+ function base64Of(text10) {
6970
8091
  let out = "";
6971
- for (let at = 0; at < text9.length; at += 3) {
6972
- const a = text9.charCodeAt(at);
6973
- const b = at + 1 < text9.length ? text9.charCodeAt(at + 1) : NaN;
6974
- const c = at + 2 < text9.length ? text9.charCodeAt(at + 2) : NaN;
6975
- out += BASE646[a >> 2] + BASE646[(a & 3) << 4 | (Number.isNaN(b) ? 0 : b >> 4)] + (Number.isNaN(b) ? "=" : BASE646[(b & 15) << 2 | (Number.isNaN(c) ? 0 : c >> 6)]) + (Number.isNaN(c) ? "=" : BASE646[c & 63]);
8092
+ for (let at = 0; at < text10.length; at += 3) {
8093
+ const a = text10.charCodeAt(at);
8094
+ const b = at + 1 < text10.length ? text10.charCodeAt(at + 1) : NaN;
8095
+ const c = at + 2 < text10.length ? text10.charCodeAt(at + 2) : NaN;
8096
+ out += BASE647[a >> 2] + BASE647[(a & 3) << 4 | (Number.isNaN(b) ? 0 : b >> 4)] + (Number.isNaN(b) ? "=" : BASE647[(b & 15) << 2 | (Number.isNaN(c) ? 0 : c >> 6)]) + (Number.isNaN(c) ? "=" : BASE647[c & 63]);
6976
8097
  }
6977
8098
  return out;
6978
8099
  }
6979
8100
  var basicOf = (projectId) => base64Of(`${projectId}:`);
6980
- function luhn10(digits3) {
8101
+ function luhn12(digits3) {
6981
8102
  let sum = 0;
6982
8103
  for (let at = 0; at < digits3.length; at += 1) {
6983
8104
  let digit = Number(digits3[digits3.length - 1 - at]);
@@ -6991,7 +8112,7 @@ function luhn10(digits3) {
6991
8112
  return sum % 10 === 0;
6992
8113
  }
6993
8114
  function processoutCardTarget(url) {
6994
- if (typeof url !== "string" || url.length > URL_LIMIT15)
8115
+ if (typeof url !== "string" || url.length > URL_LIMIT17)
6995
8116
  return null;
6996
8117
  const match = CARD_URL2.exec(url);
6997
8118
  if (!match || match[2] !== basicOf(match[1]))
@@ -7001,12 +8122,12 @@ function processoutCardTarget(url) {
7001
8122
  function isProcessoutCardUrl(url) {
7002
8123
  return processoutCardTarget(url) !== null;
7003
8124
  }
7004
- function readBody24(body) {
7005
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT40)
8125
+ function readBody27(body) {
8126
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT44)
7006
8127
  return null;
7007
8128
  try {
7008
8129
  const value = JSON.parse(body);
7009
- return record35(value) && JSON.stringify(value) === body ? value : null;
8130
+ return record37(value) && JSON.stringify(value) === body ? value : null;
7010
8131
  }
7011
8132
  catch {
7012
8133
  return null;
@@ -7024,31 +8145,31 @@ var DEVICE_RULES = /* @__PURE__ */ Object.freeze({
7024
8145
  });
7025
8146
  function soundDevice3(value) {
7026
8147
  const device = value.device;
7027
- if (!record35(device) || !own16(device, "request_origin") || !own16(device, "app_timezone_offset"))
8148
+ if (!record37(device) || !own19(device, "request_origin") || !own19(device, "app_timezone_offset"))
7028
8149
  return false;
7029
- return DEVICE_KEYS4.every((key) => own16(device, key) ? DEVICE_RULES[key](device[key]) && own16(value, key) && value[key] === device[key] : !own16(value, key)) && Object.keys(device).every((key) => DEVICE_KEYS4.includes(key));
8150
+ return DEVICE_KEYS4.every((key) => own19(device, key) ? DEVICE_RULES[key](device[key]) && own19(value, key) && value[key] === device[key] : !own19(value, key)) && Object.keys(device).every((key) => DEVICE_KEYS4.includes(key));
7030
8151
  }
7031
8152
  function soundPageData(value) {
7032
- if (own16(value, "name") && !pageText2(value.name))
8153
+ if (own19(value, "name") && !pageText2(value.name))
7033
8154
  return false;
7034
- if (own16(value, "preferred_scheme") && !(value.preferred_scheme === null || typeof value.preferred_scheme === "string" && SCHEME.test(value.preferred_scheme)))
8155
+ if (own19(value, "preferred_scheme") && !(value.preferred_scheme === null || typeof value.preferred_scheme === "string" && SCHEME.test(value.preferred_scheme)))
7035
8156
  return false;
7036
8157
  const contact = value.contact;
7037
- return record35(contact) && Object.keys(contact).every((key) => CONTACT_KEYS.includes(key) && pageText2(contact[key]));
8158
+ return record37(contact) && Object.keys(contact).every((key) => CONTACT_KEYS.includes(key) && pageText2(contact[key]));
7038
8159
  }
7039
8160
  function processoutBodyVerdict(body, url) {
7040
8161
  if (url !== void 0 && processoutCardTarget(url) === null)
7041
- return refuse41("processout_url_refused");
7042
- const value = readBody24(body);
8162
+ return refuse45("processout_url_refused");
8163
+ const value = readBody27(body);
7043
8164
  if (value === null || !Object.keys(value).every((key) => BODY_KEYS3.has(key)))
7044
- return refuse41("processout_body_unsupported");
8165
+ return refuse45("processout_body_unsupported");
7045
8166
  if (!PROCESSOUT_CARD_KEYS.every((key) => typeof value[key] === "string"))
7046
- return refuse41("processout_body_unsupported");
7047
- if (!NUMBER8.test(value.number) || !luhn10(value.number) || !MONTH21.test(value.exp_month) || !YEAR22.test(value.exp_year) || !CODE8.test(value.cvc2))
7048
- return refuse41("processout_body_unsupported");
8167
+ return refuse45("processout_body_unsupported");
8168
+ if (!NUMBER9.test(value.number) || !luhn12(value.number) || !MONTH23.test(value.exp_month) || !YEAR24.test(value.exp_year) || !CODE9.test(value.cvc2))
8169
+ return refuse45("processout_body_unsupported");
7049
8170
  if (!soundPageData(value) || !soundDevice3(value))
7050
- return refuse41("processout_body_unsupported");
7051
- return CARD40;
8171
+ return refuse45("processout_body_unsupported");
8172
+ return CARD44;
7052
8173
  }
7053
8174
  var processout_default = /* @__PURE__ */ registerProcessor({
7054
8175
  psp: PROCESSOUT_PSP,
@@ -7091,17 +8212,17 @@ var USAEPAY_HOSTS = /* @__PURE__ */ Object.freeze({
7091
8212
  "sandbox.usaepay.com": "sandbox"
7092
8213
  });
7093
8214
  var USAEPAY_PAYMENT_KEYS_PATH = "/api/v2/pub/payment_keys";
7094
- var BODY_LIMIT41 = 512;
7095
- var URL_LIMIT16 = 256;
7096
- var CARD_NUMBER21 = /^[0-9]{13,19}$/;
8215
+ var BODY_LIMIT45 = 512;
8216
+ var URL_LIMIT18 = 256;
8217
+ var CARD_NUMBER22 = /^[0-9]{13,19}$/;
7097
8218
  var EXPIRATION2 = /^(?:0[1-9]|1[0-2])[0-9]{2}$/;
7098
- var SECURITY_CODE25 = /^(?:[0-9]{3,4})?$/;
7099
- var record36 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7100
- var own17 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7101
- var refuse42 = (code) => Object.freeze({ verdict: "refuse", code });
7102
- var CARD41 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
8219
+ var SECURITY_CODE26 = /^(?:[0-9]{3,4})?$/;
8220
+ var record38 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
8221
+ var own20 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
8222
+ var refuse46 = (code) => Object.freeze({ verdict: "refuse", code });
8223
+ var CARD45 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7103
8224
  function usaepayPaymentKeysUrl(url) {
7104
- if (typeof url !== "string" || url.length > URL_LIMIT16 || url.includes("?") || url.includes("#"))
8225
+ if (typeof url !== "string" || url.length > URL_LIMIT18 || url.includes("?") || url.includes("#"))
7105
8226
  return null;
7106
8227
  let parsed;
7107
8228
  try {
@@ -7110,12 +8231,12 @@ function usaepayPaymentKeysUrl(url) {
7110
8231
  catch {
7111
8232
  return null;
7112
8233
  }
7113
- if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own17(USAEPAY_HOSTS, parsed.hostname) || parsed.pathname !== USAEPAY_PAYMENT_KEYS_PATH)
8234
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own20(USAEPAY_HOSTS, parsed.hostname) || parsed.pathname !== USAEPAY_PAYMENT_KEYS_PATH)
7114
8235
  return null;
7115
8236
  return Object.freeze({ host: parsed.hostname, environment: USAEPAY_HOSTS[parsed.hostname] });
7116
8237
  }
7117
8238
  var isUsaepayPaymentKeysUrl = (url) => usaepayPaymentKeysUrl(url) !== null;
7118
- function luhn11(digits3) {
8239
+ function luhn13(digits3) {
7119
8240
  let sum = 0;
7120
8241
  for (let at = digits3.length - 1, double = false; at >= 0; at -= 1, double = !double) {
7121
8242
  let digit = digits3.charCodeAt(at) - 48;
@@ -7125,23 +8246,23 @@ function luhn11(digits3) {
7125
8246
  }
7126
8247
  return sum % 10 === 0;
7127
8248
  }
7128
- function readBody25(body) {
7129
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT41)
8249
+ function readBody28(body) {
8250
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT45)
7130
8251
  return null;
7131
8252
  try {
7132
8253
  const value = JSON.parse(body);
7133
- return record36(value) && JSON.stringify(value) === body ? value : null;
8254
+ return record38(value) && JSON.stringify(value) === body ? value : null;
7134
8255
  }
7135
8256
  catch {
7136
8257
  return null;
7137
8258
  }
7138
8259
  }
7139
8260
  function usaepayBodyVerdict(body) {
7140
- const value = readBody25(body);
8261
+ const value = readBody28(body);
7141
8262
  const card = value === null ? null : value.creditcard;
7142
- if (value === null || Object.keys(value).join() !== "creditcard" || !record36(card) || Object.keys(card).join() !== "number,expiration,cvc" || typeof card.number !== "string" || !CARD_NUMBER21.test(card.number) || !luhn11(card.number) || typeof card.expiration !== "string" || !EXPIRATION2.test(card.expiration) || typeof card.cvc !== "string" || !SECURITY_CODE25.test(card.cvc))
7143
- return refuse42("usaepay_body_unsupported");
7144
- return CARD41;
8263
+ if (value === null || Object.keys(value).join() !== "creditcard" || !record38(card) || Object.keys(card).join() !== "number,expiration,cvc" || typeof card.number !== "string" || !CARD_NUMBER22.test(card.number) || !luhn13(card.number) || typeof card.expiration !== "string" || !EXPIRATION2.test(card.expiration) || typeof card.cvc !== "string" || !SECURITY_CODE26.test(card.cvc))
8264
+ return refuse46("usaepay_body_unsupported");
8265
+ return CARD45;
7145
8266
  }
7146
8267
  var usaepay_default = /* @__PURE__ */ registerProcessor({
7147
8268
  psp: USAEPAY_PSP,
@@ -7173,9 +8294,204 @@ var usaepay_default = /* @__PURE__ */ registerProcessor({
7173
8294
  source: "https://help.usaepay.info/developer/payjs-v2/ , https://help.usaepay.info/api/rest/"
7174
8295
  },
7175
8296
  exactUrl: isUsaepayPaymentKeysUrl,
7176
- bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ? refuse42("usaepay_url_refused") : usaepayBodyVerdict(body)
8297
+ bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ? refuse46("usaepay_url_refused") : usaepayBodyVerdict(body)
7177
8298
  // No amount reader: the request names none, so the agent's pair is the figure the cardholder approves.
7178
8299
  });
8300
+ // src/processors/viva_wallet.js
8301
+ var VIVA_WALLET_PSP = "viva_wallet";
8302
+ var VIVA_WALLET_OPERATION = "viva_wallet.card_request";
8303
+ var VIVA_WALLET_HOSTS = /* @__PURE__ */ Object.freeze({ "www.vivapayments.com": "production", "demo.vivapayments.com": "sandbox" });
8304
+ var VIVA_WALLET_CHARGE_TOKENS_PATH = "/web2/checkout/v2/chargetokens";
8305
+ var VIVA_WALLET_BODY_KEYS = /* @__PURE__ */ Object.freeze([
8306
+ "orderCode",
8307
+ "amount",
8308
+ "currencyCode",
8309
+ "holderName",
8310
+ "holderMail",
8311
+ "cvc",
8312
+ "number",
8313
+ "expirationMonth",
8314
+ "expirationYear",
8315
+ "installments",
8316
+ "customer",
8317
+ "rememberCard",
8318
+ "friendlyName",
8319
+ "maskedNumber",
8320
+ "bankId",
8321
+ "selectedBrand",
8322
+ "cardholderBrandSelection",
8323
+ "dccOptions",
8324
+ "dccAccepted",
8325
+ "offerCodes",
8326
+ "loyaltySupported",
8327
+ "redeemedAmount",
8328
+ "retrievalReferenceNumber",
8329
+ "scaRequestedTransactionId",
8330
+ "merchantTrns",
8331
+ "captchaToken"
8332
+ ]);
8333
+ var BODY_LIMIT46 = 16384;
8334
+ var URL_LIMIT19 = 256;
8335
+ var ORDER_CODE = /^[0-9]{16}$/;
8336
+ var CARD_NUMBER23 = /^[0-9]{13,19}$/;
8337
+ var MONTH24 = /^(?:0[1-9]|1[0-2])$/;
8338
+ var YEAR25 = /^[0-9]{2}$/;
8339
+ var SECURITY_CODE27 = /^[0-9]{3,4}$/;
8340
+ var CAPTCHA_TOKEN = /^[A-Za-z0-9_.-]{20,8192}$/;
8341
+ var MEMBER_NAME = /^[A-Za-z][A-Za-z0-9]{0,31}$/;
8342
+ var SHORT_ID = /^[A-Za-z0-9_-]{1,64}$/;
8343
+ var TEXT4 = /^[^\u0000-\u001f\u007f]{0,200}$/;
8344
+ var CARD_DIGITS2 = /[0-9]{12,}/;
8345
+ var record39 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
8346
+ var own21 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
8347
+ var refuse47 = (code) => Object.freeze({ verdict: "refuse", code });
8348
+ var CARD46 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
8349
+ var inOrder9 = (value, keys) => {
8350
+ let at = 0;
8351
+ for (const name of Object.keys(value)) {
8352
+ while (at < keys.length && keys[at] !== name)
8353
+ at += 1;
8354
+ if (at === keys.length)
8355
+ return false;
8356
+ at += 1;
8357
+ }
8358
+ return true;
8359
+ };
8360
+ var cardDigits2 = (text10) => CARD_DIGITS2.test(text10.replace(/[^0-9A-Za-z]/g, ""));
8361
+ var plainText8 = (value) => typeof value === "string" && TEXT4.test(value) && !cardDigits2(value);
8362
+ var scalar = (value) => value === null || typeof value === "boolean" || Number.isSafeInteger(value) && Math.abs(value) < 1e9 || plainText8(value);
8363
+ var flatRecord = (value, limit) => record39(value) && Object.keys(value).length <= limit && Object.entries(value).every(([key, item]) => MEMBER_NAME.test(key) && scalar(item));
8364
+ function vivaWalletChargeTokensUrl(url) {
8365
+ if (typeof url !== "string" || url.length > URL_LIMIT19 || url.includes("?") || url.includes("#"))
8366
+ return null;
8367
+ let parsed;
8368
+ try {
8369
+ parsed = new URL(url);
8370
+ }
8371
+ catch {
8372
+ return null;
8373
+ }
8374
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own21(VIVA_WALLET_HOSTS, parsed.hostname) || parsed.pathname !== VIVA_WALLET_CHARGE_TOKENS_PATH)
8375
+ return null;
8376
+ return Object.freeze({ host: parsed.hostname, environment: VIVA_WALLET_HOSTS[parsed.hostname] });
8377
+ }
8378
+ var isVivaWalletChargeTokensUrl = (url) => vivaWalletChargeTokensUrl(url) !== null;
8379
+ function luhn14(digits3) {
8380
+ let sum = 0;
8381
+ for (let at = digits3.length - 1, double = false; at >= 0; at -= 1, double = !double) {
8382
+ let digit = digits3.charCodeAt(at) - 48;
8383
+ if (double)
8384
+ digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
8385
+ sum += digit;
8386
+ }
8387
+ return sum % 10 === 0;
8388
+ }
8389
+ function vivaWalletMaskedNumber(number) {
8390
+ return `${number.slice(0, 6)}${"X".repeat(Math.max(0, number.length - 10))}${number.slice(-4)}`;
8391
+ }
8392
+ function readBody29(body) {
8393
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT46)
8394
+ return null;
8395
+ try {
8396
+ const value = JSON.parse(body);
8397
+ return record39(value) && JSON.stringify(value) === body ? value : null;
8398
+ }
8399
+ catch {
8400
+ return null;
8401
+ }
8402
+ }
8403
+ function currencyNumber(value) {
8404
+ if (Number.isSafeInteger(value) && value > 0 && value < 1e3)
8405
+ return value;
8406
+ return typeof value === "string" && /^[0-9]{3}$/.test(value) ? Number(value) : null;
8407
+ }
8408
+ function vivaWalletBodyVerdict(body) {
8409
+ const value = readBody29(body);
8410
+ if (value === null || !Object.keys(value).every((key) => VIVA_WALLET_BODY_KEYS.includes(key))) {
8411
+ return value !== null && (own21(value, "creditCardId") || own21(value, "token")) ? refuse47("viva_wallet_stored_card") : refuse47("viva_wallet_body_unsupported");
8412
+ }
8413
+ if (value.rememberCard !== false)
8414
+ return refuse47(value.rememberCard === true ? "viva_wallet_keep_on_file" : "viva_wallet_body_unsupported");
8415
+ if (value.dccAccepted === true)
8416
+ return refuse47("viva_wallet_currency_conversion");
8417
+ if (own21(value, "dccAccepted") && value.dccAccepted !== false)
8418
+ return refuse47("viva_wallet_body_unsupported");
8419
+ if (own21(value, "scaRequestedTransactionId"))
8420
+ return refuse47("viva_wallet_retry_refused");
8421
+ if (!(value.installments === 0 || value.installments === 1)) {
8422
+ return refuse47(Number.isSafeInteger(value.installments) && value.installments > 1 ? "viva_wallet_installments" : "viva_wallet_body_unsupported");
8423
+ }
8424
+ if (!inOrder9(value, VIVA_WALLET_BODY_KEYS) || ["offerCodes", "loyaltySupported", "redeemedAmount", "retrievalReferenceNumber", "merchantTrns"].some((key) => own21(value, key)))
8425
+ return refuse47("viva_wallet_body_unsupported");
8426
+ const number = value.number;
8427
+ const sound = typeof value.orderCode === "string" && ORDER_CODE.test(value.orderCode) && Number.isSafeInteger(value.amount) && value.amount > 0 && currencyNumber(value.currencyCode) !== null && plainText8(value.holderName) && value.holderName.trim() !== "" && plainText8(value.holderMail) && (value.cvc === null || typeof value.cvc === "string" && SECURITY_CODE27.test(value.cvc)) && typeof number === "string" && CARD_NUMBER23.test(number) && luhn14(number) && typeof value.expirationMonth === "string" && MONTH24.test(value.expirationMonth) && typeof value.expirationYear === "string" && YEAR25.test(value.expirationYear) && flatRecord(value.customer, 12) && (!own21(value, "friendlyName") || plainText8(value.friendlyName)) && value.maskedNumber === vivaWalletMaskedNumber(number) && (!own21(value, "bankId") || typeof value.bankId === "string" && SHORT_ID.test(value.bankId) || Number.isSafeInteger(value.bankId) && value.bankId >= 0) && (!own21(value, "selectedBrand") || value.selectedBrand === null || flatRecord(value.selectedBrand, 16)) && (!own21(value, "cardholderBrandSelection") || typeof value.cardholderBrandSelection === "boolean") && (!own21(value, "dccOptions") || flatRecord(value.dccOptions, 16)) && (!own21(value, "captchaToken") || typeof value.captchaToken === "string" && CAPTCHA_TOKEN.test(value.captchaToken));
8428
+ return sound ? CARD46 : refuse47("viva_wallet_body_unsupported");
8429
+ }
8430
+ var VIVA_WALLET_CURRENCIES = /* @__PURE__ */ Object.freeze({
8431
+ 978: "eur",
8432
+ 826: "gbp",
8433
+ 946: "ron",
8434
+ 985: "pln",
8435
+ 203: "czk",
8436
+ 348: "huf",
8437
+ 752: "sek",
8438
+ 208: "dkk"
8439
+ });
8440
+ function vivaWalletAmount(body) {
8441
+ if (vivaWalletBodyVerdict(body).verdict !== "card")
8442
+ return null;
8443
+ const value = JSON.parse(body);
8444
+ const currency = VIVA_WALLET_CURRENCIES[currencyNumber(value.currencyCode)];
8445
+ return currency ? { amountCents: value.amount, currency } : null;
8446
+ }
8447
+ var VIVA_WALLET_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
8448
+ Object.freeze({
8449
+ id: "klimaka_donation",
8450
+ merchant: "Klimaka",
8451
+ tradeName: "ΚΛΙΜΑΚΑ ΑΜΚΕ",
8452
+ orderCodes: Object.freeze(["7871752880772607"]),
8453
+ origin: "https://www.vivapayments.com",
8454
+ currencyCode: 978
8455
+ }),
8456
+ Object.freeze({
8457
+ id: "desmos_donation",
8458
+ merchant: "Desmos",
8459
+ tradeName: "DESMOS",
8460
+ orderCodes: Object.freeze(["8156257435672606"]),
8461
+ origin: "https://www.vivapayments.com",
8462
+ currencyCode: 978
8463
+ })
8464
+ ]);
8465
+ var CARD_MEMBERS = Object.freeze(["cvc", "number", "expirationMonth", "expirationYear", "maskedNumber"]);
8466
+ var viva_wallet_default = /* @__PURE__ */ registerProcessor({
8467
+ psp: VIVA_WALLET_PSP,
8468
+ definitions: [
8469
+ {
8470
+ psp: "viva_wallet",
8471
+ // The page's card request, as the header above reads it. demo.vivapayments.com is Viva's sandbox, pinned to test
8472
+ // rows, which send only Viva's documented test cards (hostEnvironmentPinned, device-replay.js S7).
8473
+ // Ships dark: served only to a client that declares `viva_smart_checkout_chargetoken`, and only for a company the
8474
+ // backend's processor gate turns Viva Wallet on for. `(?![\w/.%-])` ends the path for a consumer that tests `match`
8475
+ // unanchored.
8476
+ capability: "viva_smart_checkout_chargetoken",
8477
+ match: "(?:www|demo)\\.vivapayments\\.com/web2/checkout/v2/chargetokens(?![\\w/.%-])",
8478
+ hosts: ["^www\\.vivapayments\\.com$", "^demo\\.vivapayments\\.com$"],
8479
+ sandboxHosts: ["^demo\\.vivapayments\\.com$"],
8480
+ hostEnvironmentPinned: true,
8481
+ encoding: "json",
8482
+ // The page sends no Authorization; Origin, Referer, cookies and the reCAPTCHA state never ride.
8483
+ passthroughHeaders: [],
8484
+ jsonCardFields: [["number"]]
8485
+ }
8486
+ ],
8487
+ // Only the cardholder's device sends this card, after a person approves; no reviewed list names viva_wallet.
8488
+ refusedOperations: [VIVA_WALLET_OPERATION],
8489
+ settlementReadback: "not_surveyed",
8490
+ exactUrl: isVivaWalletChargeTokensUrl,
8491
+ bodyGate: (url, body) => url !== void 0 && !isVivaWalletChargeTokensUrl(url) ? refuse47("viva_wallet_url_refused") : vivaWalletBodyVerdict(body),
8492
+ // The body names the order's amount in cents and its numeric currency, which the page's card-free charge repeats.
8493
+ amount: (template) => record39(template) && isVivaWalletChargeTokensUrl(template.url) ? vivaWalletAmount(template.body) : null
8494
+ });
7179
8495
  // src/processors/vtex_payments.js
7180
8496
  var VTEX_PAYMENTS_PSP = "vtex_payments";
7181
8497
  var VTEX_PAYMENTS_OPERATION = "vtex_payments.card_request";
@@ -7224,27 +8540,27 @@ var VTEX_PAYMENTS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
7224
8540
  Object.freeze({ account: "alssports", origin: "https://www.als.com", merchant: "Al's Sporting Goods", currency: "USD" }),
7225
8541
  Object.freeze({ account: "roadrunnersports", origin: "https://www.roadrunnersports.com", merchant: "Road Runner Sports", currency: "USD" })
7226
8542
  ]);
7227
- var BODY_LIMIT42 = 16384;
8543
+ var BODY_LIMIT47 = 16384;
7228
8544
  var ACCOUNT_HOST = /^([a-z0-9]{1,63})\.vtexvault\.com$/;
7229
8545
  var PATH = /^\/api\/payments\/transactions\/([0-9A-Fa-f]{32})\/payments$/;
7230
8546
  var ORDER_GROUP = /^[0-9]{6,24}$/;
7231
- var BASE647 = /^[A-Za-z0-9+/]{4,1020}={0,2}$/;
7232
- var CARD_NUMBER22 = /^[0-9]{12,19}$/;
7233
- var SECURITY_CODE26 = /^[0-9]{3,4}$/;
8547
+ var BASE648 = /^[A-Za-z0-9+/]{4,1020}={0,2}$/;
8548
+ var CARD_NUMBER24 = /^[0-9]{12,19}$/;
8549
+ var SECURITY_CODE28 = /^[0-9]{3,4}$/;
7234
8550
  var DUE_DATE = /^(?:0[1-9]|1[0-2])\/[0-9]{2}$/;
7235
8551
  var CURRENCY6 = /^[A-Z]{3}$/;
7236
8552
  var TRANSACTION_ID = /^[0-9A-Fa-f]{32}$/;
7237
8553
  var MERCHANT_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
7238
- var SHORT_ID = /^[A-Za-z0-9_-]{1,64}$/;
8554
+ var SHORT_ID2 = /^[A-Za-z0-9_-]{1,64}$/;
7239
8555
  var FINGERPRINT4 = /^[A-Za-z0-9_.:=+/-]{1,256}$/;
7240
- var TEXT4 = /^[^\u0000-\u001f\u007f]{1,200}$/;
7241
- var CARD_DIGITS2 = /[0-9]{12,}/;
8556
+ var TEXT5 = /^[^\u0000-\u001f\u007f]{1,200}$/;
8557
+ var CARD_DIGITS3 = /[0-9]{12,}/;
7242
8558
  var DEVICE_INFO_KEYS = Object.freeze(["sw", "sh", "cd", "tz", "lang", "java", "sourceApplication"]);
7243
- var record37 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7244
- var own18 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
7245
- var refuse43 = (code) => Object.freeze({ verdict: "refuse", code });
7246
- var CARD42 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
7247
- var inOrder8 = (value, keys) => {
8559
+ var record40 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
8560
+ var own22 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
8561
+ var refuse48 = (code) => Object.freeze({ verdict: "refuse", code });
8562
+ var CARD47 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
8563
+ var inOrder10 = (value, keys) => {
7248
8564
  let at = 0;
7249
8565
  for (const name of Object.keys(value)) {
7250
8566
  while (at < keys.length && keys[at] !== name)
@@ -7255,8 +8571,8 @@ var inOrder8 = (value, keys) => {
7255
8571
  }
7256
8572
  return true;
7257
8573
  };
7258
- var cardDigits2 = (text9) => CARD_DIGITS2.test(text9.replace(/[^0-9A-Za-z]/g, ""));
7259
- var plainText8 = (value) => typeof value === "string" && TEXT4.test(value) && !cardDigits2(value);
8574
+ var cardDigits3 = (text10) => CARD_DIGITS3.test(text10.replace(/[^0-9A-Za-z]/g, ""));
8575
+ var plainText9 = (value) => typeof value === "string" && TEXT5.test(value) && !cardDigits3(value);
7260
8576
  var count = (value) => Number.isSafeInteger(value) && value >= 0;
7261
8577
  var BASE64_ALPHABET2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7262
8578
  function base64Text2(input) {
@@ -7280,10 +8596,10 @@ function base64Text2(input) {
7280
8596
  }
7281
8597
  return out;
7282
8598
  }
7283
- function deviceInfoSound(text9) {
7284
- if (typeof text9 !== "string" || !BASE647.test(text9))
8599
+ function deviceInfoSound(text10) {
8600
+ if (typeof text10 !== "string" || !BASE648.test(text10))
7285
8601
  return false;
7286
- const decoded = base64Text2(text9);
8602
+ const decoded = base64Text2(text10);
7287
8603
  if (decoded === null)
7288
8604
  return false;
7289
8605
  let info;
@@ -7293,18 +8609,18 @@ function deviceInfoSound(text9) {
7293
8609
  catch {
7294
8610
  return false;
7295
8611
  }
7296
- if (!record37(info) || !Object.keys(info).every((key) => DEVICE_INFO_KEYS.includes(key)))
8612
+ if (!record40(info) || !Object.keys(info).every((key) => DEVICE_INFO_KEYS.includes(key)))
7297
8613
  return false;
7298
8614
  for (const key of ["sw", "sh", "cd"])
7299
- if (own18(info, key) && !(count(info[key]) && info[key] <= 1e5))
8615
+ if (own22(info, key) && !(count(info[key]) && info[key] <= 1e5))
7300
8616
  return false;
7301
- if (own18(info, "tz") && !(Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440))
8617
+ if (own22(info, "tz") && !(Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440))
7302
8618
  return false;
7303
- if (own18(info, "lang") && !(typeof info.lang === "string" && /^[A-Za-z]{0,8}$/.test(info.lang)))
8619
+ if (own22(info, "lang") && !(typeof info.lang === "string" && /^[A-Za-z]{0,8}$/.test(info.lang)))
7304
8620
  return false;
7305
- if (own18(info, "java") && typeof info.java !== "boolean")
8621
+ if (own22(info, "java") && typeof info.java !== "boolean")
7306
8622
  return false;
7307
- return !own18(info, "sourceApplication") || typeof info.sourceApplication === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(info.sourceApplication);
8623
+ return !own22(info, "sourceApplication") || typeof info.sourceApplication === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(info.sourceApplication);
7308
8624
  }
7309
8625
  function vtexPaymentsCardTarget(url) {
7310
8626
  if (typeof url !== "string" || url.length > 8192)
@@ -7350,8 +8666,8 @@ function isVtexPaymentsCardUrl(url) {
7350
8666
  const target = vtexPaymentsCardTarget(url);
7351
8667
  return target !== null && !target.fallback;
7352
8668
  }
7353
- function readBody26(body) {
7354
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT42)
8669
+ function readBody30(body) {
8670
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT47)
7355
8671
  return null;
7356
8672
  let value;
7357
8673
  try {
@@ -7365,13 +8681,13 @@ function readBody26(body) {
7365
8681
  return value;
7366
8682
  }
7367
8683
  function cardLine(line) {
7368
- if (!record37(line))
8684
+ if (!record40(line))
7369
8685
  return false;
7370
- const fields = record37(line.fields) ? line.fields : {};
7371
- return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" || own18(line, "accountId") || own18(fields, "accountId") || own18(fields, "cardNumber") || own18(fields, "validationCode") || own18(fields, "dueDate");
8686
+ const fields = record40(line.fields) ? line.fields : {};
8687
+ return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" || own22(line, "accountId") || own22(fields, "accountId") || own22(fields, "cardNumber") || own22(fields, "validationCode") || own22(fields, "dueDate");
7372
8688
  }
7373
8689
  function addressSound(address2) {
7374
- if (!record37(address2) || !inOrder8(address2, VTEX_PAYMENTS_ADDRESS_KEYS))
8690
+ if (!record40(address2) || !inOrder10(address2, VTEX_PAYMENTS_ADDRESS_KEYS))
7375
8691
  return false;
7376
8692
  for (const [key, value] of Object.entries(address2)) {
7377
8693
  if (key === "addressType") {
@@ -7380,60 +8696,60 @@ function addressSound(address2) {
7380
8696
  continue;
7381
8697
  }
7382
8698
  if (key === "addressId") {
7383
- if (!(typeof value === "string" && SHORT_ID.test(value)))
8699
+ if (!(typeof value === "string" && SHORT_ID2.test(value)))
7384
8700
  return false;
7385
8701
  continue;
7386
8702
  }
7387
8703
  if (value === null && (key === "complement" || key === "reference"))
7388
8704
  continue;
7389
- if (!(value === "" || plainText8(value)))
8705
+ if (!(value === "" || plainText9(value)))
7390
8706
  return false;
7391
8707
  }
7392
8708
  return true;
7393
8709
  }
7394
8710
  function fieldsSound(fields) {
7395
- if (!record37(fields) || !inOrder8(fields, VTEX_PAYMENTS_FIELD_KEYS) || own18(fields, "metadata"))
8711
+ if (!record40(fields) || !inOrder10(fields, VTEX_PAYMENTS_FIELD_KEYS) || own22(fields, "metadata"))
7396
8712
  return false;
7397
- if (!(typeof fields.cardNumber === "string" && CARD_NUMBER22.test(fields.cardNumber)))
8713
+ if (!(typeof fields.cardNumber === "string" && CARD_NUMBER24.test(fields.cardNumber)))
7398
8714
  return false;
7399
- if (!(typeof fields.validationCode === "string" && SECURITY_CODE26.test(fields.validationCode)))
8715
+ if (!(typeof fields.validationCode === "string" && SECURITY_CODE28.test(fields.validationCode)))
7400
8716
  return false;
7401
8717
  if (!(typeof fields.dueDate === "string" && DUE_DATE.test(fields.dueDate)))
7402
8718
  return false;
7403
- if (!plainText8(fields.holderName))
8719
+ if (!plainText9(fields.holderName))
7404
8720
  return false;
7405
- if (own18(fields, "document") && !(fields.document === "" || plainText8(fields.document) && fields.document.length <= 32))
8721
+ if (own22(fields, "document") && !(fields.document === "" || plainText9(fields.document) && fields.document.length <= 32))
7406
8722
  return false;
7407
- if (own18(fields, "address") && !addressSound(fields.address))
8723
+ if (own22(fields, "address") && !addressSound(fields.address))
7408
8724
  return false;
7409
- if (own18(fields, "deviceFingerprint") && !(typeof fields.deviceFingerprint === "string" && FINGERPRINT4.test(fields.deviceFingerprint)))
8725
+ if (own22(fields, "deviceFingerprint") && !(typeof fields.deviceFingerprint === "string" && FINGERPRINT4.test(fields.deviceFingerprint)))
7410
8726
  return false;
7411
- return !own18(fields, "addressId") || typeof fields.addressId === "string" && SHORT_ID.test(fields.addressId);
8727
+ return !own22(fields, "addressId") || typeof fields.addressId === "string" && SHORT_ID2.test(fields.addressId);
7412
8728
  }
7413
8729
  function vtexPaymentsBodyVerdict(body, target) {
7414
- const lines = readBody26(body);
7415
- if (lines === null || lines.length === 0 || !lines.every(record37))
7416
- return refuse43("vtex_payments_body_unsupported");
8730
+ const lines = readBody30(body);
8731
+ if (lines === null || lines.length === 0 || !lines.every(record40))
8732
+ return refuse48("vtex_payments_body_unsupported");
7417
8733
  const cards = lines.filter(cardLine);
7418
- if (cards.some((line2) => own18(line2, "accountId") || own18(line2.fields ?? {}, "accountId")))
7419
- return refuse43("vtex_payments_saved_card");
8734
+ if (cards.some((line2) => own22(line2, "accountId") || own22(line2.fields ?? {}, "accountId")))
8735
+ return refuse48("vtex_payments_saved_card");
7420
8736
  if (cards.length === 0)
7421
- return refuse43("vtex_payments_body_unsupported");
7422
- if (lines.length !== 1 || own18(lines[0], "id"))
7423
- return refuse43("vtex_payments_split_payment");
8737
+ return refuse48("vtex_payments_body_unsupported");
8738
+ if (lines.length !== 1 || own22(lines[0], "id"))
8739
+ return refuse48("vtex_payments_split_payment");
7424
8740
  const line = lines[0];
7425
- if (!inOrder8(line, VTEX_PAYMENTS_LINE_KEYS) || line.groupName !== "creditCardPaymentGroup")
7426
- return refuse43("vtex_payments_body_unsupported");
7427
- if (!(typeof line.currencyCode === "string" && CURRENCY6.test(line.currencyCode)) || !own18(VTEX_PAYMENTS_NETWORKS, line.paymentSystem) || !Number.isSafeInteger(line.paymentSystem) || !(count(line.value) && line.value > 0))
7428
- return refuse43("vtex_payments_body_unsupported");
7429
- if (line.installments !== 1 || line.referenceValue !== line.value || own18(line, "installmentsInterestRate") && line.installmentsInterestRate !== 0 || own18(line, "installmentsValue") && line.installmentsValue !== line.value)
7430
- return refuse43("vtex_payments_installments");
8741
+ if (!inOrder10(line, VTEX_PAYMENTS_LINE_KEYS) || line.groupName !== "creditCardPaymentGroup")
8742
+ return refuse48("vtex_payments_body_unsupported");
8743
+ if (!(typeof line.currencyCode === "string" && CURRENCY6.test(line.currencyCode)) || !own22(VTEX_PAYMENTS_NETWORKS, line.paymentSystem) || !Number.isSafeInteger(line.paymentSystem) || !(count(line.value) && line.value > 0))
8744
+ return refuse48("vtex_payments_body_unsupported");
8745
+ if (line.installments !== 1 || line.referenceValue !== line.value || own22(line, "installmentsInterestRate") && line.installmentsInterestRate !== 0 || own22(line, "installmentsValue") && line.installmentsValue !== line.value)
8746
+ return refuse48("vtex_payments_installments");
7431
8747
  const transaction = line.transaction;
7432
- if (!record37(transaction) || Object.keys(transaction).join() !== "id,merchantName" || !(typeof transaction.id === "string" && TRANSACTION_ID.test(transaction.id)) || !(typeof transaction.merchantName === "string" && MERCHANT_NAME.test(transaction.merchantName)))
7433
- return refuse43("vtex_payments_body_unsupported");
8748
+ if (!record40(transaction) || Object.keys(transaction).join() !== "id,merchantName" || !(typeof transaction.id === "string" && TRANSACTION_ID.test(transaction.id)) || !(typeof transaction.merchantName === "string" && MERCHANT_NAME.test(transaction.merchantName)))
8749
+ return refuse48("vtex_payments_body_unsupported");
7434
8750
  if (target && transaction.id.toUpperCase() !== target.transactionId.toUpperCase())
7435
- return refuse43("vtex_payments_split_payment");
7436
- return fieldsSound(line.fields) ? CARD42 : refuse43("vtex_payments_body_unsupported");
8751
+ return refuse48("vtex_payments_split_payment");
8752
+ return fieldsSound(line.fields) ? CARD47 : refuse48("vtex_payments_body_unsupported");
7437
8753
  }
7438
8754
  function vtexPaymentsAmount(body) {
7439
8755
  if (vtexPaymentsBodyVerdict(body).verdict !== "card")
@@ -7478,21 +8794,28 @@ var vtex_payments_default = /* @__PURE__ */ registerProcessor({
7478
8794
  return vtexPaymentsBodyVerdict(body);
7479
8795
  const target = vtexPaymentsCardTarget(url);
7480
8796
  if (target === null)
7481
- return refuse43("vtex_payments_url_refused");
7482
- return target.fallback ? refuse43("vtex_payments_fallback_refused") : vtexPaymentsBodyVerdict(body, target);
8797
+ return refuse48("vtex_payments_url_refused");
8798
+ return target.fallback ? refuse48("vtex_payments_fallback_refused") : vtexPaymentsBodyVerdict(body, target);
7483
8799
  },
7484
- amount: (template) => record37(template) && isVtexPaymentsCardUrl(template.url) ? vtexPaymentsAmount(template.body) : null
8800
+ amount: (template) => record40(template) && isVtexPaymentsCardUrl(template.url) ? vtexPaymentsAmount(template.body) : null
7485
8801
  });
7486
8802
  // src/processors/index.generated.js
7487
8803
  var REGISTERED_MODULES = Object.freeze({
8804
+ aurus: aurus_default,
7488
8805
  bluesnap: bluesnap_default,
8806
+ cardlink_vpos: cardlink_vpos_default,
8807
+ eghl: eghl_default,
8808
+ frisbii: frisbii_default,
7489
8809
  iyzico: iyzico_default,
7490
8810
  midtrans: midtrans_default,
8811
+ monei: monei_default,
7491
8812
  oceanpayment: oceanpayment_default,
7492
8813
  paymentwall: paymentwall_default,
7493
8814
  payplug: payplug_default,
8815
+ paystack: paystack_default,
7494
8816
  processout: processout_default,
7495
8817
  usaepay: usaepay_default,
8818
+ viva_wallet: viva_wallet_default,
7496
8819
  vtex_payments: vtex_payments_default
7497
8820
  });
7498
8821
  // src/registry.js
@@ -7681,7 +9004,7 @@ function carriesCardFields(recognizer, body) {
7681
9004
  if (typeof body !== "string" || body === "")
7682
9005
  return false;
7683
9006
  const anyCase = recognizer.caseInsensitiveFormKeys === true;
7684
- const wanted = anyCase ? fields.map((field3) => String(field3).toLowerCase()) : fields;
9007
+ const wanted = anyCase ? fields.map((field5) => String(field5).toLowerCase()) : fields;
7685
9008
  for (const chunk of body.split("&")) {
7686
9009
  const eq = chunk.indexOf("=");
7687
9010
  if (eq <= 0 || eq === chunk.length - 1)
@@ -7773,12 +9096,12 @@ function splitCardLeg(recognizer, body) {
7773
9096
  const absorb = list(split.absorb);
7774
9097
  const pass = list(split.pass);
7775
9098
  const sibling = list(split.siblingKeys);
7776
- const own19 = keys.filter((key) => !sibling.includes(key));
7777
- if (own19.length === 0)
9099
+ const own23 = keys.filter((key) => !sibling.includes(key));
9100
+ if (own23.length === 0)
7778
9101
  return null;
7779
- if (own19.every((key) => absorb.includes(key)))
9102
+ if (own23.every((key) => absorb.includes(key)))
7780
9103
  return "absorb";
7781
- if (own19.every((key) => pass.includes(key)))
9104
+ if (own23.every((key) => pass.includes(key)))
7782
9105
  return "pass";
7783
9106
  return null;
7784
9107
  }