@agent-cards/sdk 0.23.18 → 0.23.19

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.
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 0021d69ee6583030342d0f5ed625f1cb4bec88236f01fbf7450e41293f6f450d
3
+ // artifact-sha256: d59cc35c7ffec2b7a8aa6b52e65fd0a6a22465f4e60812b87ec23256ea9e8885
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
@@ -302,11 +302,11 @@ var MONERIS_TOKENIZE_PATH = "/HPPtoken/request.php";
302
302
  function monerisTokenizeEnvironment(url) {
303
303
  if (typeof url !== "string")
304
304
  return null;
305
- for (const environment of
305
+ for (const environment2 of
306
306
  /** @type {const} */
307
307
  ["production", "sandbox"]) {
308
- if (MONERIS_TOKENIZE_HOSTS[environment].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
309
- return environment;
308
+ if (MONERIS_TOKENIZE_HOSTS[environment2].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
309
+ return environment2;
310
310
  }
311
311
  return null;
312
312
  }
@@ -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 own2 = Object.keys(value);
361
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
360
+ const own3 = Object.keys(value);
361
+ return own3.length === keys.length && own3.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" });
@@ -746,13 +746,13 @@ var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
746
746
  sha256: "92529bd289bb24d52a1bdcc42edc9ac0bb1dacbb58f7568573d44771e1287762"
747
747
  })
748
748
  });
749
- function paddleTokenexKey(environment) {
750
- if (environment !== "sandbox" && environment !== "production")
749
+ function paddleTokenexKey(environment2) {
750
+ if (environment2 !== "sandbox" && environment2 !== "production")
751
751
  return null;
752
- return PADDLE_TOKENEX_KEYS[environment] ?? null;
752
+ return PADDLE_TOKENEX_KEYS[environment2] ?? null;
753
753
  }
754
- function paddleTokenexKeyBytes(environment) {
755
- const key = paddleTokenexKey(environment);
754
+ function paddleTokenexKeyBytes(environment2) {
755
+ const key = paddleTokenexKey(environment2);
756
756
  if (!key)
757
757
  return null;
758
758
  try {
@@ -767,8 +767,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
767
767
  var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
768
768
  var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
769
769
  var sameKeys2 = (value, keys) => {
770
- const own2 = Object.keys(value);
771
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
770
+ const own3 = Object.keys(value);
771
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
772
772
  };
773
773
  var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
774
774
  var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -813,11 +813,11 @@ function isBase64OfBytes(value, bytes) {
813
813
  const pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
814
814
  return value.length / 4 * 3 - pad === bytes && btoa(atob(value)) === value;
815
815
  }
816
- function isPaddleTokenexCiphertext(value, environment) {
817
- const bytes = paddleTokenexKeyBytes(environment);
816
+ function isPaddleTokenexCiphertext(value, environment2) {
817
+ const bytes = paddleTokenexKeyBytes(environment2);
818
818
  return bytes !== null && isBase64OfBytes(value, bytes);
819
819
  }
820
- function readPay(body, line, environment) {
820
+ function readPay(body, line, environment2) {
821
821
  if (typeof body !== "string" || body === "" || body.length > PAY_BODY_LIMIT)
822
822
  return null;
823
823
  let value;
@@ -849,11 +849,11 @@ function readPay(body, line, environment) {
849
849
  return null;
850
850
  for (const name of CARD_KEYS3) {
851
851
  const blob = tokenex[name];
852
- if (environment === void 0) {
852
+ if (environment2 === void 0) {
853
853
  if (typeof blob !== "string" || !BASE642.test(blob) || blob.length < 4 || blob.length > 4096)
854
854
  return null;
855
855
  }
856
- else if (!isPaddleTokenexCiphertext(blob, environment))
856
+ else if (!isPaddleTokenexCiphertext(blob, environment2))
857
857
  return null;
858
858
  }
859
859
  if (tokenex.encrypted_card_number === tokenex.encrypted_cvv)
@@ -1257,8 +1257,8 @@ var TEXT_LIMIT = 256;
1257
1257
  var CONTROL4 = /[\u0000-\u001f\u007f]/;
1258
1258
  var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1259
1259
  var sameKeys3 = (value, keys) => {
1260
- const own2 = Object.keys(value);
1261
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
1260
+ const own3 = Object.keys(value);
1261
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
1262
1262
  };
1263
1263
  var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
1264
1264
  var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
@@ -1460,8 +1460,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
1460
1460
  var CARD_PAYMENT = "PAYMENT_CARD";
1461
1461
  var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1462
1462
  var sameKeys4 = (value, keys) => {
1463
- const own2 = Object.keys(value);
1464
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
1463
+ const own3 = Object.keys(value);
1464
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
1465
1465
  };
1466
1466
  var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
1467
1467
  var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -1490,8 +1490,8 @@ function gopayCardFormUrl(url) {
1490
1490
  }
1491
1491
  if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
1492
1492
  return null;
1493
- const environment = Object.prototype.hasOwnProperty.call(GOPAY_CARD_FORM_HOSTS, parsed.hostname) ? GOPAY_CARD_FORM_HOSTS[parsed.hostname] : null;
1494
- if (environment === null || !parsed.pathname.startsWith(GOPAY_CARD_FORM_PATH))
1493
+ const environment2 = Object.prototype.hasOwnProperty.call(GOPAY_CARD_FORM_HOSTS, parsed.hostname) ? GOPAY_CARD_FORM_HOSTS[parsed.hostname] : null;
1494
+ if (environment2 === null || !parsed.pathname.startsWith(GOPAY_CARD_FORM_PATH))
1495
1495
  return null;
1496
1496
  if (!TOKEN2.test(parsed.pathname.slice(GOPAY_CARD_FORM_PATH.length)))
1497
1497
  return null;
@@ -1503,7 +1503,7 @@ function gopayCardFormUrl(url) {
1503
1503
  const version = parsed.searchParams.get("ver");
1504
1504
  if (signature === null || !SIGNATURE.test(signature) || language !== null && !LANGUAGE.test(language) || version !== null && !VERSION.test(version))
1505
1505
  return null;
1506
- return Object.freeze({ host: parsed.hostname, environment, signature });
1506
+ return Object.freeze({ host: parsed.hostname, environment: environment2, signature });
1507
1507
  }
1508
1508
  function readBody4(body) {
1509
1509
  if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT7)
@@ -1685,8 +1685,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
1685
1685
  var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
1686
1686
  var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1687
1687
  var sameKeys5 = (value, keys) => {
1688
- const own2 = Object.keys(value);
1689
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
1688
+ const own3 = Object.keys(value);
1689
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
1690
1690
  };
1691
1691
  var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
1692
1692
  var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -1843,14 +1843,14 @@ function paygentBodyVerdict(body) {
1843
1843
  return code === null ? CARD13 : refuse14(code);
1844
1844
  }
1845
1845
  function paygentRequestVerdict(url, body) {
1846
- const environment = paygentEnvironment(url);
1847
- if (environment === null)
1846
+ const environment2 = paygentEnvironment(url);
1847
+ if (environment2 === null)
1848
1848
  return refuse14("paygent_url_refused");
1849
1849
  const { code, pairs } = judgeBody3(body);
1850
1850
  if (code !== null)
1851
1851
  return refuse14(code);
1852
1852
  const key = pairs[1][1];
1853
- return (environment === "production" ? LIVE_KEY : SANDBOX_KEY).test(key) ? CARD13 : refuse14("paygent_key_environment");
1853
+ return (environment2 === "production" ? LIVE_KEY : SANDBOX_KEY).test(key) ? CARD13 : refuse14("paygent_key_environment");
1854
1854
  }
1855
1855
  // src/multipart-form.js
1856
1856
  var BODY_LIMIT11 = 65536;
@@ -1994,6 +1994,462 @@ function payNlBodyVerdict(body, contentType) {
1994
1994
  }
1995
1995
  var ERROR_KEYS = /* @__PURE__ */ Object.freeze(["errorId", "errorTag", "errorMessage", "errorFieldName"]);
1996
1996
  var REQUEST_KEYS = /* @__PURE__ */ Object.freeze(["result", ...ERROR_KEYS]);
1997
+ // src/revolut.js
1998
+ var REVOLUT_PSP = "revolut";
1999
+ var REVOLUT_HOSTS = /* @__PURE__ */ Object.freeze(["merchant.revolut.com", "sandbox-merchant.revolut.com"]);
2000
+ var REVOLUT_BODY_KEYS = /* @__PURE__ */ Object.freeze(["payment_method", "customer", "amount", "channel"]);
2001
+ var REVOLUT_CARD_FIELD_KEYS = /* @__PURE__ */ Object.freeze([
2002
+ "type",
2003
+ "number",
2004
+ "expiry_month",
2005
+ "expiry_year",
2006
+ "cvv",
2007
+ "kount_session_id",
2008
+ "billing_address",
2009
+ "cardholder_name",
2010
+ "shipping_address",
2011
+ "save_for",
2012
+ "environment"
2013
+ ]);
2014
+ var REVOLUT_CARD_POPUP_KEYS = /* @__PURE__ */ Object.freeze([
2015
+ "type",
2016
+ "number",
2017
+ "expiry_month",
2018
+ "expiry_year",
2019
+ "cvv",
2020
+ "kount_session_id",
2021
+ "cardholder_name",
2022
+ "billing_address",
2023
+ "shipping_address",
2024
+ "save_for",
2025
+ "environment"
2026
+ ]);
2027
+ var REVOLUT_CHANNELS = /* @__PURE__ */ Object.freeze(["WEB_SDK", "REV_CHECKOUT", "HOSTED_PAYMENT_PAGE"]);
2028
+ var BODY_LIMIT12 = 16384;
2029
+ var URL_LIMIT6 = 128;
2030
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
2031
+ var PAYMENTS_PATH = /^\/api\/public\/orders\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/payments$/;
2032
+ var CARD_NUMBER8 = /^[0-9]{12,19}$/;
2033
+ var SECURITY_CODE11 = /^[0-9]{3,4}$/;
2034
+ var KOUNT_SESSION = /^[0-9a-f]{32}$/;
2035
+ var AMOUNT_LIMIT = 1e11;
2036
+ var ADDRESS_KEYS = /* @__PURE__ */ Object.freeze(["country", "region", "city", "postcode", "street_line_1", "street_line_2"]);
2037
+ var ENVIRONMENT_KEYS = /* @__PURE__ */ Object.freeze([
2038
+ "type",
2039
+ "color_depth",
2040
+ "screen_width",
2041
+ "screen_height",
2042
+ "java_enabled",
2043
+ "time_zone_utc_offset",
2044
+ "challenge_window_width",
2045
+ "browser_url",
2046
+ "referrer_url"
2047
+ ]);
2048
+ var NEW_CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["type", "email", "name", "phone"]);
2049
+ var COUNTRY = /^[A-Z]{2}$/;
2050
+ var PHONE = /^\+?[0-9 \u00a0\/().-]{6,32}$/;
2051
+ var EMAIL3 = /^[^\s@]{1,64}@[^\s@]{1,255}$/;
2052
+ var TEXT_LIMIT2 = 256;
2053
+ var CONTROL5 = /[\u0000-\u001f\u007f]/;
2054
+ var CARD_MEMBER2 = /^(?:number|card_?number|cardnumber|cardnum|card_num|pan|cvv|cvc|cvv2)$/i;
2055
+ var record10 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2056
+ var own2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
2057
+ var inOrder = (value, keys) => {
2058
+ let at = 0;
2059
+ for (const name of Object.keys(value)) {
2060
+ while (at < keys.length && keys[at] !== name)
2061
+ at += 1;
2062
+ if (at === keys.length)
2063
+ return false;
2064
+ at += 1;
2065
+ }
2066
+ return true;
2067
+ };
2068
+ var wellFormed = (value) => {
2069
+ try {
2070
+ encodeURIComponent(value);
2071
+ return true;
2072
+ }
2073
+ catch {
2074
+ return false;
2075
+ }
2076
+ };
2077
+ var plainText2 = (value) => typeof value === "string" && value.length >= 1 && value.length <= TEXT_LIMIT2 && !CONTROL5.test(value) && (value.match(/[0-9]/g) ?? []).length < 12 && wellFormed(value);
2078
+ var between = (value, min, max) => Number.isSafeInteger(value) && value >= min && value <= max;
2079
+ var NETWORK = /^(?:4[0-9]{15}|4[0-9]{12}|5[1-5][0-9]{14}|2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9]{2}|7(?:[01][0-9]|20))[0-9]{12}|3[47][0-9]{13})$/;
2080
+ var luhn2 = (digits) => {
2081
+ let sum = 0;
2082
+ for (let at = 0; at < digits.length; at += 1) {
2083
+ let d = digits.charCodeAt(digits.length - 1 - at) - 48;
2084
+ if (at % 2 === 1) {
2085
+ d *= 2;
2086
+ if (d > 9)
2087
+ d -= 9;
2088
+ }
2089
+ sum += d;
2090
+ }
2091
+ return sum % 10 === 0;
2092
+ };
2093
+ var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
2094
+ var holdsCardShape = (text2, shape = NETWORK) => (text2.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
2095
+ var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
2096
+ var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
2097
+ var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
2098
+ var CONTINUE7 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
2099
+ function revolutPaymentsTarget(url) {
2100
+ if (typeof url !== "string" || url.length > URL_LIMIT6 || url.includes("?") || url.includes("#"))
2101
+ return null;
2102
+ let parsed;
2103
+ try {
2104
+ parsed = new URL(url);
2105
+ }
2106
+ catch {
2107
+ return null;
2108
+ }
2109
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !REVOLUT_HOSTS.includes(parsed.hostname))
2110
+ return null;
2111
+ const match = PAYMENTS_PATH.exec(parsed.pathname);
2112
+ return match ? Object.freeze({ host: parsed.hostname, order: match[1] }) : null;
2113
+ }
2114
+ function isRevolutPaymentsUrl(url) {
2115
+ return revolutPaymentsTarget(url) !== null;
2116
+ }
2117
+ function readBody7(body) {
2118
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT12)
2119
+ return null;
2120
+ let value;
2121
+ try {
2122
+ value = JSON.parse(body);
2123
+ if (!record10(value) || JSON.stringify(value) !== body)
2124
+ return null;
2125
+ }
2126
+ catch {
2127
+ return null;
2128
+ }
2129
+ return value;
2130
+ }
2131
+ function address(value) {
2132
+ if (!record10(value) || !inOrder(value, ADDRESS_KEYS))
2133
+ return false;
2134
+ const names = Object.keys(value);
2135
+ if (!names.some((key) => typeof value[key] === "string" && value[key].trim() !== ""))
2136
+ return false;
2137
+ return names.every((key) => value[key] === "" || (key === "country" ? typeof value[key] === "string" && COUNTRY.test(value[key]) : plainText2(value[key])));
2138
+ }
2139
+ function pageUrl(value) {
2140
+ if (typeof value !== "string" || value.length > 2048 || CONTROL5.test(value) || holdsCardShape(value, ANY_NETWORK) || !wellFormed(value))
2141
+ return false;
2142
+ let parsed;
2143
+ try {
2144
+ parsed = new URL(value);
2145
+ }
2146
+ catch {
2147
+ return false;
2148
+ }
2149
+ return parsed.protocol === "https:" || parsed.protocol === "http:";
2150
+ }
2151
+ function referrerOrigin(value) {
2152
+ if (value === "" || value === "null")
2153
+ return true;
2154
+ if (typeof value !== "string" || value.length > 512 || holdsCardShape(value, ANY_NETWORK))
2155
+ return false;
2156
+ let parsed;
2157
+ try {
2158
+ parsed = new URL(value);
2159
+ }
2160
+ catch {
2161
+ return false;
2162
+ }
2163
+ return (parsed.protocol === "https:" || parsed.protocol === "http:") && parsed.origin === value;
2164
+ }
2165
+ function environment(value) {
2166
+ if (!record10(value) || !inOrder(value, ENVIRONMENT_KEYS))
2167
+ return false;
2168
+ return value.type === "browser" && between(value.color_depth, 0, 256) && between(value.screen_width, 0, 1e5) && between(value.screen_height, 0, 1e5) && typeof value.java_enabled === "boolean" && between(value.time_zone_utc_offset, -1440, 1440) && between(value.challenge_window_width, 1, 1e4) && (!own2(value, "browser_url") || pageUrl(value.browser_url)) && (!own2(value, "referrer_url") || referrerOrigin(value.referrer_url));
2169
+ }
2170
+ function customer(value) {
2171
+ if (!record10(value))
2172
+ return false;
2173
+ if (value.type === "existing") {
2174
+ const names = Object.keys(value);
2175
+ return names.length === 2 && names[0] === "type" && names[1] === "id" && typeof value.id === "string" && UUID.test(value.id);
2176
+ }
2177
+ if (value.type !== "new" || !inOrder(value, NEW_CUSTOMER_KEYS) || !own2(value, "email"))
2178
+ return false;
2179
+ if (typeof value.email !== "string" || !EMAIL3.test(value.email) || !plainText2(value.email))
2180
+ return false;
2181
+ if (own2(value, "name") && !plainText2(value.name))
2182
+ return false;
2183
+ return !own2(value, "phone") || phone(value.phone);
2184
+ }
2185
+ function cardMethod(value) {
2186
+ if (!record10(value) || value.type !== "card")
2187
+ return "revolut_body_unsupported";
2188
+ if (!inOrder(value, REVOLUT_CARD_FIELD_KEYS) && !inOrder(value, REVOLUT_CARD_POPUP_KEYS))
2189
+ return "revolut_body_unsupported";
2190
+ if (typeof value.number !== "string" || !CARD_NUMBER8.test(value.number) || !between(value.expiry_month, 1, 12) || !between(value.expiry_year, 2e3, 2099) || typeof value.cvv !== "string" || !SECURITY_CODE11.test(value.cvv))
2191
+ return "revolut_body_unsupported";
2192
+ if (!own2(value, "environment") || !environment(value.environment))
2193
+ return "revolut_body_unsupported";
2194
+ if (own2(value, "kount_session_id") && (typeof value.kount_session_id !== "string" || !KOUNT_SESSION.test(value.kount_session_id))) {
2195
+ return "revolut_body_unsupported";
2196
+ }
2197
+ for (const key of ["billing_address", "shipping_address"]) {
2198
+ if (own2(value, key) && !address(value[key]))
2199
+ return "revolut_body_unsupported";
2200
+ }
2201
+ if (own2(value, "cardholder_name") && !plainText2(value.cardholder_name))
2202
+ return "revolut_body_unsupported";
2203
+ if (own2(value, "save_for")) {
2204
+ if (value.save_for === "CUSTOMER" || value.save_for === "MERCHANT")
2205
+ return "revolut_card_on_file";
2206
+ if (value.save_for !== "NONE")
2207
+ return "revolut_body_unsupported";
2208
+ }
2209
+ return null;
2210
+ }
2211
+ function namesCardValue2(parsed) {
2212
+ const pending = record10(parsed) || Array.isArray(parsed) ? [parsed] : [];
2213
+ while (pending.length > 0) {
2214
+ const node = pending.pop();
2215
+ for (const key of Object.keys(node)) {
2216
+ if (!Array.isArray(node) && CARD_MEMBER2.test(key))
2217
+ return true;
2218
+ const value = node[key];
2219
+ if (value !== null && typeof value === "object")
2220
+ pending.push(value);
2221
+ }
2222
+ }
2223
+ return false;
2224
+ }
2225
+ function revolutBodyVerdict(body) {
2226
+ const value = readBody7(body);
2227
+ if (value === null) {
2228
+ return body === void 0 || body === null || body === "" ? CONTINUE7 : refuse16("revolut_body_unsupported");
2229
+ }
2230
+ const method = record10(value.payment_method) ? value.payment_method.type : void 0;
2231
+ if (method !== "card")
2232
+ return namesCardValue2(value) ? refuse16("revolut_body_unsupported") : CONTINUE7;
2233
+ if (!inOrder(value, REVOLUT_BODY_KEYS) || Object.keys(value).length !== REVOLUT_BODY_KEYS.length)
2234
+ return refuse16("revolut_body_unsupported");
2235
+ const code = cardMethod(value.payment_method);
2236
+ if (code !== null)
2237
+ return refuse16(code);
2238
+ if (!customer(value.customer) || !between(value.amount, 1, AMOUNT_LIMIT) || !REVOLUT_CHANNELS.includes(value.channel)) {
2239
+ return refuse16("revolut_body_unsupported");
2240
+ }
2241
+ return CARD15;
2242
+ }
2243
+ // src/sumup.js
2244
+ var SUMUP_PSP = "sumup";
2245
+ var SUMUP_API_HOST = "api.sumup.com";
2246
+ var SUMUP_CHECKOUT_PATH = "/v0.2/checkouts/";
2247
+ var BODY_LIMIT13 = 16384;
2248
+ var CHECKOUT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2249
+ var ROOT_KEYS5 = /* @__PURE__ */ Object.freeze([
2250
+ "payment_type",
2251
+ "device_information",
2252
+ "method_details",
2253
+ "personal_details",
2254
+ "card",
2255
+ "installments",
2256
+ "mandate",
2257
+ "lxn_session_token",
2258
+ "customer_details",
2259
+ "sca_experience"
2260
+ ]);
2261
+ var CARD_KEYS7 = /* @__PURE__ */ Object.freeze(["zip_code", "name", "number", "expiry_month", "expiry_year", "cvv"]);
2262
+ var PERSONAL_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "address", "birth_date", "phone"]);
2263
+ var ADDRESS_KEYS2 = /* @__PURE__ */ Object.freeze(["country", "city", "line1", "line2", "postal_code", "state"]);
2264
+ var CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "note_for_merchant"]);
2265
+ var CARD_NUMBER9 = /^[0-9]{12,19}$/;
2266
+ var MONTH7 = /^(?:0[1-9]|1[0-2])$/;
2267
+ var YEAR7 = /^(?:[0-9]{2}|[0-9]{4})$/;
2268
+ var CODE2 = /^[0-9]{3,4}$/;
2269
+ var BASE643 = /^[A-Za-z0-9+/]{4,4096}={0,2}$/;
2270
+ var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2271
+ var DEVICE_KEYS2 = /* @__PURE__ */ Object.freeze([
2272
+ "user_agent",
2273
+ "language",
2274
+ "timezone_offset",
2275
+ "screen_width",
2276
+ "screen_height",
2277
+ "color_depth",
2278
+ "modal_width",
2279
+ "modal_height",
2280
+ "adblock",
2281
+ "realIp",
2282
+ "route"
2283
+ ]);
2284
+ var RISK_TOKEN = /^[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]*$/;
2285
+ var RISK_TOKEN_LIMIT = 4096;
2286
+ var PAN_LIKE4 = /(?:[0-9][ _.:-]*){12,}/;
2287
+ var DATE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
2288
+ var COUNTRY2 = /^[A-Z]{2}$/;
2289
+ var PHONE2 = /^[ #0-9_+\/().-]{1,32}$/;
2290
+ var CARD_PAYMENT2 = "card";
2291
+ var SCA_EXPERIENCE = "iframe";
2292
+ var record11 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2293
+ var refuse17 = (code) => Object.freeze({ verdict: "refuse", code });
2294
+ var CARD16 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
2295
+ function orderedSubset(value, keys) {
2296
+ let at = -1;
2297
+ for (const key of Object.keys(value)) {
2298
+ const next = keys.indexOf(key);
2299
+ if (next <= at)
2300
+ return false;
2301
+ at = next;
2302
+ }
2303
+ return true;
2304
+ }
2305
+ function luhn3(digits) {
2306
+ let sum = 0;
2307
+ for (let at = 0; at < digits.length; at += 1) {
2308
+ let digit = Number(digits[digits.length - 1 - at]);
2309
+ if (at % 2 === 1) {
2310
+ digit *= 2;
2311
+ if (digit > 9)
2312
+ digit -= 9;
2313
+ }
2314
+ sum += digit;
2315
+ }
2316
+ return sum % 10 === 0 && sum > 0;
2317
+ }
2318
+ var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch.charCodeAt(0) !== 127);
2319
+ function typed(value, limit = 256) {
2320
+ return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
2321
+ }
2322
+ function decodeBase64(text2) {
2323
+ if (typeof text2 !== "string" || !BASE643.test(text2) || text2.length % 4 !== 0)
2324
+ return null;
2325
+ let bits = 0;
2326
+ let value = 0;
2327
+ let out = "";
2328
+ for (const ch of text2.replace(/=+$/, "")) {
2329
+ value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
2330
+ bits += 6;
2331
+ if (bits >= 8) {
2332
+ bits -= 8;
2333
+ out += String.fromCharCode(value >> bits & 255);
2334
+ }
2335
+ }
2336
+ return out;
2337
+ }
2338
+ function soundDevice(text2) {
2339
+ const json = decodeBase64(text2);
2340
+ if (json === null)
2341
+ return false;
2342
+ let value;
2343
+ try {
2344
+ value = JSON.parse(json);
2345
+ if (JSON.stringify(value) !== json)
2346
+ return false;
2347
+ }
2348
+ catch {
2349
+ return false;
2350
+ }
2351
+ if (!record11(value) || Object.keys(value).join() !== "deviceId,components" || typeof value.deviceId !== "string" || value.deviceId.length > 256 || PAN_LIKE4.test(value.deviceId) || !printable(value.deviceId) || !Array.isArray(value.components) || value.components.length !== DEVICE_KEYS2.length) {
2352
+ return false;
2353
+ }
2354
+ return value.components.every((component, at) => record11(component) && Object.keys(component).join() === "key,value" && component.key === DEVICE_KEYS2[at] && typeof component.value === "string" && component.value.length <= 1024 && !PAN_LIKE4.test(component.value) && printable(component.value));
2355
+ }
2356
+ var soundRiskToken = (token) => typeof token === "string" && token.length <= RISK_TOKEN_LIMIT && RISK_TOKEN.test(token) && !PAN_LIKE4.test(token);
2357
+ function sumupCheckoutUrl(url) {
2358
+ if (typeof url !== "string" || url.length > 256 || url.includes("#") || url.includes("?"))
2359
+ return null;
2360
+ let parsed;
2361
+ try {
2362
+ parsed = new URL(url);
2363
+ }
2364
+ catch {
2365
+ return null;
2366
+ }
2367
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
2368
+ return null;
2369
+ if (parsed.hostname !== SUMUP_API_HOST || !parsed.pathname.startsWith(SUMUP_CHECKOUT_PATH))
2370
+ return null;
2371
+ const checkoutId = parsed.pathname.slice(SUMUP_CHECKOUT_PATH.length);
2372
+ return CHECKOUT_ID.test(checkoutId) ? Object.freeze({ checkoutId }) : null;
2373
+ }
2374
+ function readBody8(body) {
2375
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT13)
2376
+ return null;
2377
+ let value;
2378
+ try {
2379
+ value = JSON.parse(body);
2380
+ if (!record11(value) || JSON.stringify(value) !== body)
2381
+ return null;
2382
+ }
2383
+ catch {
2384
+ return null;
2385
+ }
2386
+ return value;
2387
+ }
2388
+ function soundCard(card) {
2389
+ if (!record11(card) || !orderedSubset(card, CARD_KEYS7))
2390
+ return false;
2391
+ if (typeof card.number !== "string" || !CARD_NUMBER9.test(card.number) || !luhn3(card.number))
2392
+ return false;
2393
+ if (typeof card.expiry_month !== "string" || !MONTH7.test(card.expiry_month))
2394
+ return false;
2395
+ if (typeof card.expiry_year !== "string" || !YEAR7.test(card.expiry_year))
2396
+ return false;
2397
+ if (typeof card.cvv !== "string" || !CODE2.test(card.cvv))
2398
+ return false;
2399
+ if (card.name !== void 0 && (!typed(card.name, 129) || /[0-9]/.test(card.name)))
2400
+ return false;
2401
+ if (card.zip_code !== void 0 && !typed(card.zip_code, 10))
2402
+ return false;
2403
+ return true;
2404
+ }
2405
+ function soundPersonal(details) {
2406
+ if (!record11(details) || !orderedSubset(details, PERSONAL_KEYS) || Object.keys(details).length === 0)
2407
+ return false;
2408
+ for (const key of ["first_name", "last_name", "email"]) {
2409
+ if (details[key] !== void 0 && !typed(details[key]))
2410
+ return false;
2411
+ }
2412
+ if (details.birth_date !== void 0 && (typeof details.birth_date !== "string" || !DATE.test(details.birth_date)))
2413
+ return false;
2414
+ if (details.phone !== void 0 && (typeof details.phone !== "string" || !PHONE2.test(details.phone) || (details.phone.match(/[0-9]/g) ?? []).length > 15))
2415
+ return false;
2416
+ if (details.address === void 0)
2417
+ return true;
2418
+ const address2 = details.address;
2419
+ if (!record11(address2) || !orderedSubset(address2, ADDRESS_KEYS2) || Object.keys(address2).length === 0)
2420
+ return false;
2421
+ if (address2.country !== void 0 && (typeof address2.country !== "string" || !COUNTRY2.test(address2.country)))
2422
+ return false;
2423
+ return ["city", "line1", "line2", "postal_code", "state"].every((key) => address2[key] === void 0 || typed(address2[key]));
2424
+ }
2425
+ function soundCustomer(details) {
2426
+ if (!record11(details) || !orderedSubset(details, CUSTOMER_KEYS) || Object.keys(details).length === 0)
2427
+ return false;
2428
+ return CUSTOMER_KEYS.every((key) => details[key] === void 0 || typed(details[key], key === "note_for_merchant" ? 1024 : 256));
2429
+ }
2430
+ function sumupBodyVerdict(body, url) {
2431
+ if (url !== void 0 && sumupCheckoutUrl(url) === null)
2432
+ return refuse17("sumup_url_refused");
2433
+ const value = readBody8(body);
2434
+ if (value === null || !orderedSubset(value, ROOT_KEYS5))
2435
+ return refuse17("sumup_body_unsupported");
2436
+ if (value.payment_type !== CARD_PAYMENT2 || !soundDevice(value.device_information) || !soundCard(value.card) || value.installments !== 1) {
2437
+ return refuse17("sumup_body_unsupported");
2438
+ }
2439
+ if (value.method_details !== void 0 && !(record11(value.method_details) && orderedSubset(value.method_details, ["zip_code"]) && typed(value.method_details.zip_code, 10)))
2440
+ return refuse17("sumup_body_unsupported");
2441
+ if (value.personal_details !== void 0 && !soundPersonal(value.personal_details))
2442
+ return refuse17("sumup_body_unsupported");
2443
+ if (value.customer_details !== void 0 && !soundCustomer(value.customer_details))
2444
+ return refuse17("sumup_body_unsupported");
2445
+ if (value.lxn_session_token !== void 0 && !soundRiskToken(value.lxn_session_token))
2446
+ return refuse17("sumup_body_unsupported");
2447
+ if (value.sca_experience !== void 0 && value.sca_experience !== SCA_EXPERIENCE)
2448
+ return refuse17("sumup_body_unsupported");
2449
+ if (value.mandate !== void 0)
2450
+ return refuse17("sumup_card_saving_refused");
2451
+ return CARD16;
2452
+ }
1997
2453
  // src/card-fields.js
1998
2454
  function processorGate(recognizer, url, body) {
1999
2455
  if (recognizer && recognizer.psp === LYRA_PSP)
@@ -2040,6 +2496,13 @@ function processorGate(recognizer, url, body) {
2040
2496
  }
2041
2497
  if (recognizer && recognizer.psp === GOPAY_PSP)
2042
2498
  return gopayBodyVerdict(body, url);
2499
+ if (recognizer && recognizer.psp === REVOLUT_PSP) {
2500
+ if (url !== void 0 && !isRevolutPaymentsUrl(url))
2501
+ return { verdict: "refuse", code: "revolut_url_refused" };
2502
+ return revolutBodyVerdict(body);
2503
+ }
2504
+ if (recognizer && recognizer.psp === SUMUP_PSP)
2505
+ return sumupBodyVerdict(body, url);
2043
2506
  if (recognizer && recognizer.psp === GRAVY_PSP)
2044
2507
  return gravyBodyVerdict(body);
2045
2508
  if (recognizer && recognizer.psp === MONERIS_PSP) {
@@ -2157,7 +2620,7 @@ function splitCardLeg(recognizer, body) {
2157
2620
  const absorb = list(split.absorb);
2158
2621
  const pass = list(split.pass);
2159
2622
  const sibling = list(split.siblingKeys);
2160
- const own2 = [];
2623
+ const own3 = [];
2161
2624
  const seen = /* @__PURE__ */ new Set();
2162
2625
  for (const chunk of body.split("&")) {
2163
2626
  const eq = chunk.indexOf("=");
@@ -2174,13 +2637,13 @@ function splitCardLeg(recognizer, body) {
2174
2637
  return null;
2175
2638
  seen.add(key);
2176
2639
  if (!sibling.includes(key))
2177
- own2.push(key);
2640
+ own3.push(key);
2178
2641
  }
2179
- if (own2.length === 0)
2642
+ if (own3.length === 0)
2180
2643
  return null;
2181
- if (own2.every((key) => absorb.includes(key)))
2644
+ if (own3.every((key) => absorb.includes(key)))
2182
2645
  return "absorb";
2183
- if (own2.every((key) => pass.includes(key)))
2646
+ if (own3.every((key) => pass.includes(key)))
2184
2647
  return "pass";
2185
2648
  return null;
2186
2649
  }