@agent-cards/sdk 0.23.20 → 0.23.22

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 (64) hide show
  1. package/CHANGELOG.md +55 -2
  2. package/PREFLIGHT.md +6 -0
  3. package/README.md +169 -5
  4. package/dist/amadeus-checkout.generated.d.ts +6 -1
  5. package/dist/amadeus-checkout.generated.js +26 -2
  6. package/dist/card-fields.generated.js +2341 -127
  7. package/dist/cdp.js +199 -28
  8. package/dist/client.d.ts +177 -9
  9. package/dist/client.js +387 -37
  10. package/dist/comgate.d.ts +50 -0
  11. package/dist/comgate.js +80 -0
  12. package/dist/creditguard.generated.js +4 -2
  13. package/dist/cse-body.js +11 -0
  14. package/dist/cybersource-secure-acceptance.generated.d.ts +1 -1
  15. package/dist/ebanx.d.ts +1 -1
  16. package/dist/ebanx.js +1 -1
  17. package/dist/eprotect.generated.d.ts +1 -1
  18. package/dist/eximbay.d.ts +46 -0
  19. package/dist/eximbay.js +69 -0
  20. package/dist/gmo.generated.js +7 -3
  21. package/dist/hipay.generated.d.ts +5 -5
  22. package/dist/hipay.generated.js +5 -2
  23. package/dist/hold.d.ts +1 -1
  24. package/dist/hold.js +10 -4
  25. package/dist/hosted-entry.d.ts +4 -0
  26. package/dist/hosted-entry.js +32 -0
  27. package/dist/index.d.ts +1 -0
  28. package/dist/lifecycle.d.ts +9 -4
  29. package/dist/lifecycle.js +16 -4
  30. package/dist/paddle-tokenex.generated.js +7 -3
  31. package/dist/paygent.generated.d.ts +60 -0
  32. package/dist/paygent.generated.js +425 -0
  33. package/dist/payrails.generated.js +7 -3
  34. package/dist/payrexx.d.ts +91 -0
  35. package/dist/payrexx.generated.d.ts +91 -0
  36. package/dist/payrexx.generated.js +536 -0
  37. package/dist/payrexx.js +141 -0
  38. package/dist/pre-claim.d.ts +30 -1
  39. package/dist/pre-claim.js +257 -39
  40. package/dist/preflight-catalog.json +58 -0
  41. package/dist/preflight-schemas.json +4 -0
  42. package/dist/preflight.generated.js +26 -2
  43. package/dist/prepared-processor.d.ts +7 -2
  44. package/dist/prepared-processor.js +16 -2
  45. package/dist/primer.generated.js +2469 -255
  46. package/dist/przelewy24.d.ts +47 -0
  47. package/dist/przelewy24.js +88 -0
  48. package/dist/registry.d.ts +6 -5
  49. package/dist/registry.js +27 -7
  50. package/dist/shiji-sts.generated.js +7 -3
  51. package/dist/stripe-checkout.generated.js +896 -19
  52. package/dist/toast-seal.generated.d.ts +37 -0
  53. package/dist/toast-seal.generated.js +625 -0
  54. package/dist/toast.generated.d.ts +41 -0
  55. package/dist/toast.generated.js +113 -0
  56. package/dist/tokenex-iframe.d.ts +93 -0
  57. package/dist/tokenex-iframe.generated.d.ts +81 -0
  58. package/dist/tokenex-iframe.generated.js +403 -0
  59. package/dist/tokenex-iframe.js +195 -0
  60. package/dist/transbank.d.ts +45 -0
  61. package/dist/transbank.js +73 -0
  62. package/dist/twoc2p.generated.js +7 -3
  63. package/examples/preflight/kernel-native/inventory.json +1 -1
  64. package/package.json +3 -3
@@ -0,0 +1,37 @@
1
+ declare var TOAST_SCHEME: string;
2
+ declare var ToastError: {
3
+ new (reason: any): {
4
+ name: string;
5
+ message: string;
6
+ stack?: string;
7
+ cause?: unknown;
8
+ };
9
+ };
10
+ declare function toastCardPlaintext(card: any, postalCode: any): string;
11
+ declare function encryptToastCard(card: any, request: any, facilities?: {}): Promise<{
12
+ cardData: string;
13
+ }>;
14
+ declare function isToastCiphertextUnderKey(value: any): boolean;
15
+ declare function toastKeyUsable(authorization: any): boolean;
16
+ declare function toastSubstitutionsRefusal(template: any, substitutions: any): {
17
+ code: string;
18
+ message: any;
19
+ } | null;
20
+ declare function substituteToastCardData(url: any, body: any, fields: any): string;
21
+ declare function toastAnswerOutcome(status: any, text: any): {
22
+ outcome: string;
23
+ reason: string;
24
+ code?: undefined;
25
+ body?: undefined;
26
+ } | {
27
+ outcome: string;
28
+ code: string;
29
+ reason?: undefined;
30
+ body?: undefined;
31
+ } | {
32
+ outcome: string;
33
+ body: string;
34
+ reason?: undefined;
35
+ code?: undefined;
36
+ };
37
+ export { TOAST_SCHEME, ToastError, encryptToastCard, isToastCiphertextUnderKey, substituteToastCardData, toastAnswerOutcome, toastCardPlaintext, toastKeyUsable, toastSubstitutionsRefusal };
@@ -0,0 +1,625 @@
1
+ // @ts-nocheck
2
+ // Generated from @agent-cards/payment-core. Do not edit.
3
+ // artifact-sha256: 76b8b2e66aaea554e1181148894062d1f998d5f7b75dc9ac626d420f22081d7e
4
+ // src/sha256.js
5
+ var K = /* @__PURE__ */ new Uint32Array([
6
+ 1116352408,
7
+ 1899447441,
8
+ 3049323471,
9
+ 3921009573,
10
+ 961987163,
11
+ 1508970993,
12
+ 2453635748,
13
+ 2870763221,
14
+ 3624381080,
15
+ 310598401,
16
+ 607225278,
17
+ 1426881987,
18
+ 1925078388,
19
+ 2162078206,
20
+ 2614888103,
21
+ 3248222580,
22
+ 3835390401,
23
+ 4022224774,
24
+ 264347078,
25
+ 604807628,
26
+ 770255983,
27
+ 1249150122,
28
+ 1555081692,
29
+ 1996064986,
30
+ 2554220882,
31
+ 2821834349,
32
+ 2952996808,
33
+ 3210313671,
34
+ 3336571891,
35
+ 3584528711,
36
+ 113926993,
37
+ 338241895,
38
+ 666307205,
39
+ 773529912,
40
+ 1294757372,
41
+ 1396182291,
42
+ 1695183700,
43
+ 1986661051,
44
+ 2177026350,
45
+ 2456956037,
46
+ 2730485921,
47
+ 2820302411,
48
+ 3259730800,
49
+ 3345764771,
50
+ 3516065817,
51
+ 3600352804,
52
+ 4094571909,
53
+ 275423344,
54
+ 430227734,
55
+ 506948616,
56
+ 659060556,
57
+ 883997877,
58
+ 958139571,
59
+ 1322822218,
60
+ 1537002063,
61
+ 1747873779,
62
+ 1955562222,
63
+ 2024104815,
64
+ 2227730452,
65
+ 2361852424,
66
+ 2428436474,
67
+ 2756734187,
68
+ 3204031479,
69
+ 3329325298
70
+ ]);
71
+ var rotr = (x, n) => x >>> n | x << 32 - n;
72
+ function utf8(text) {
73
+ const out = [];
74
+ for (const char of text) {
75
+ let cp = char.codePointAt(0);
76
+ if (cp >= 55296 && cp <= 57343)
77
+ cp = 65533;
78
+ if (cp < 128)
79
+ out.push(cp);
80
+ else if (cp < 2048)
81
+ out.push(192 | cp >> 6, 128 | cp & 63);
82
+ else if (cp < 65536)
83
+ out.push(224 | cp >> 12, 128 | cp >> 6 & 63, 128 | cp & 63);
84
+ else
85
+ out.push(240 | cp >> 18, 128 | cp >> 12 & 63, 128 | cp >> 6 & 63, 128 | cp & 63);
86
+ }
87
+ return Uint8Array.from(out);
88
+ }
89
+ function sha256Hex(input) {
90
+ const isBytes2 = Object.prototype.toString.call(input) === "[object Uint8Array]";
91
+ if (typeof input !== "string" && !isBytes2)
92
+ throw new TypeError("sha256Hex takes a string or a Uint8Array.");
93
+ const bytes = typeof input === "string" ? utf8(input) : input;
94
+ const length = bytes.length;
95
+ const padded = new Uint8Array((length + 8 >> 6) + 1 << 6);
96
+ padded.set(bytes);
97
+ padded[length] = 128;
98
+ const view = new DataView(padded.buffer);
99
+ view.setUint32(padded.length - 8, Math.floor(length / 536870912));
100
+ view.setUint32(padded.length - 4, length << 3 >>> 0);
101
+ const H = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]);
102
+ const W = new Uint32Array(64);
103
+ for (let offset = 0; offset < padded.length; offset += 64) {
104
+ for (let t = 0; t < 16; t++)
105
+ W[t] = view.getUint32(offset + t * 4);
106
+ for (let t = 16; t < 64; t++) {
107
+ const s0 = rotr(W[t - 15], 7) ^ rotr(W[t - 15], 18) ^ W[t - 15] >>> 3;
108
+ const s1 = rotr(W[t - 2], 17) ^ rotr(W[t - 2], 19) ^ W[t - 2] >>> 10;
109
+ W[t] = W[t - 16] + s0 + W[t - 7] + s1 >>> 0;
110
+ }
111
+ let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
112
+ for (let t = 0; t < 64; t++) {
113
+ const t1 = h + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + (e & f ^ ~e & g) + K[t] + W[t] >>> 0;
114
+ const t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
115
+ h = g;
116
+ g = f;
117
+ f = e;
118
+ e = d + t1 >>> 0;
119
+ d = c;
120
+ c = b;
121
+ b = a;
122
+ a = t1 + t2 >>> 0;
123
+ }
124
+ H[0] += a;
125
+ H[1] += b;
126
+ H[2] += c;
127
+ H[3] += d;
128
+ H[4] += e;
129
+ H[5] += f;
130
+ H[6] += g;
131
+ H[7] += h;
132
+ }
133
+ return Array.from(H, (word) => word.toString(16).padStart(8, "0")).join("");
134
+ }
135
+ // src/merchant-card-endpoint-keys.js
136
+ var MerchantKeyError = class extends Error {
137
+ constructor(reason) {
138
+ super("Refusing to encrypt the card under the merchant's key.");
139
+ this.name = "MerchantKeyError";
140
+ this.code = "merchant_key_refused";
141
+ this.reason = reason;
142
+ }
143
+ };
144
+ var refuse = (reason) => new MerchantKeyError(reason);
145
+ var MERCHANT_KEY_HASHES = /* @__PURE__ */ Object.freeze({ "SHA-1": 20, "SHA-256": 32, "SHA-512": 64 });
146
+ var MERCHANT_KEY_JWE_ENCS = /* @__PURE__ */ Object.freeze({
147
+ "A256CBC-HS512": Object.freeze({ key: 64, iv: 16, tag: 32 }),
148
+ A256GCM: Object.freeze({ key: 32, iv: 12, tag: 16 })
149
+ });
150
+ var MERCHANT_KEY_SIZES = /* @__PURE__ */ Object.freeze([256, 384, 512]);
151
+ var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
152
+ var BASE64URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
153
+ var SHA256_HEX = /^[0-9a-f]{64}$/;
154
+ var RSA_ALGORITHM = [48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0];
155
+ var MAX_ENCRYPTED_LENGTH = 4096;
156
+ var isBytes = (value) => Object.prototype.toString.call(value) === "[object Uint8Array]";
157
+ function encodeBase64(bytes, url = false) {
158
+ const alphabet = url ? BASE64URL_ALPHABET : BASE64_ALPHABET;
159
+ let out = "";
160
+ for (let i = 0; i < bytes.length; i += 3) {
161
+ const a = bytes[i];
162
+ const b = i + 1 < bytes.length ? bytes[i + 1] : 0;
163
+ const c = i + 2 < bytes.length ? bytes[i + 2] : 0;
164
+ const triple = a << 16 | b << 8 | c;
165
+ out += alphabet[triple >> 18 & 63] + alphabet[triple >> 12 & 63];
166
+ if (i + 1 < bytes.length)
167
+ out += alphabet[triple >> 6 & 63];
168
+ else if (!url)
169
+ out += "=";
170
+ if (i + 2 < bytes.length)
171
+ out += alphabet[triple & 63];
172
+ else if (!url)
173
+ out += "=";
174
+ }
175
+ return out;
176
+ }
177
+ function decodeBase64(text, url = false) {
178
+ if (typeof text !== "string" || text.length === 0 || text.length > MAX_ENCRYPTED_LENGTH * 2)
179
+ return null;
180
+ const alphabet = url ? BASE64URL_ALPHABET : BASE64_ALPHABET;
181
+ const body = url ? text : text.replace(/={1,2}$/, "");
182
+ if (!url && text.length % 4 !== 0)
183
+ return null;
184
+ if (body.length % 4 === 1)
185
+ return null;
186
+ const out = new Uint8Array(Math.floor(body.length * 3 / 4));
187
+ let bits = 0;
188
+ let value = 0;
189
+ let at = 0;
190
+ for (let i = 0; i < body.length; i += 1) {
191
+ const digit = alphabet.indexOf(body[i]);
192
+ if (digit === -1)
193
+ return null;
194
+ value = value << 6 | digit;
195
+ bits += 6;
196
+ if (bits >= 8) {
197
+ bits -= 8;
198
+ out[at++] = value >> bits & 255;
199
+ value &= (1 << bits) - 1;
200
+ }
201
+ }
202
+ return encodeBase64(out, url) === text ? out : null;
203
+ }
204
+ function readElement(der, at, tag) {
205
+ if (at + 2 > der.length || der[at] !== tag)
206
+ throw refuse("key");
207
+ let length = der[at + 1];
208
+ let start = at + 2;
209
+ if (length & 128) {
210
+ const count = length & 127;
211
+ if (count === 0 || count > 2 || start + count > der.length || der[start] === 0)
212
+ throw refuse("key");
213
+ length = count === 1 ? der[start] : der[start] * 256 + der[start + 1];
214
+ if (length < 128)
215
+ throw refuse("key");
216
+ start += count;
217
+ }
218
+ if (start + length > der.length)
219
+ throw refuse("key");
220
+ return { start, end: start + length };
221
+ }
222
+ function readPositiveInteger(der, at) {
223
+ const { start, end } = readElement(der, at, 2);
224
+ if (end === start || der[start] & 128)
225
+ throw refuse("key");
226
+ if (der[start] === 0 && (end - start === 1 || !(der[start + 1] & 128)))
227
+ throw refuse("key");
228
+ return { bytes: der.subarray(der[start] === 0 ? start + 1 : start, end), end };
229
+ }
230
+ function toBigInt(bytes) {
231
+ let hex = "";
232
+ for (let i = 0; i < bytes.length; i += 1)
233
+ hex += (bytes[i] < 16 ? "0" : "") + bytes[i].toString(16);
234
+ return BigInt(`0x${hex || "0"}`);
235
+ }
236
+ function toBytes(value, size) {
237
+ const hex = value.toString(16).padStart(size * 2, "0");
238
+ if (hex.length !== size * 2)
239
+ throw refuse("text");
240
+ const out = new Uint8Array(size);
241
+ for (let i = 0; i < size; i += 1)
242
+ out[i] = parseInt(hex.slice(2 * i, 2 * i + 2), 16);
243
+ return out;
244
+ }
245
+ function modPow(base, exponent, modulus) {
246
+ let result = 1n;
247
+ let square = base % modulus;
248
+ for (let rest = exponent; rest > 0n; rest >>= 1n) {
249
+ if (rest & 1n)
250
+ result = result * square % modulus;
251
+ square = square * square % modulus;
252
+ }
253
+ return result;
254
+ }
255
+ function parseMerchantKey(key) {
256
+ const spki = key && typeof key === "object" ? key.spki : void 0;
257
+ const pin = key && typeof key === "object" ? key.sha256 : void 0;
258
+ if (typeof spki !== "string" || spki.length > 1024 || typeof pin !== "string" || !SHA256_HEX.test(pin))
259
+ throw refuse("key");
260
+ const der = decodeBase64(spki);
261
+ if (!der || sha256Hex(der) !== pin)
262
+ throw refuse("key");
263
+ const outer = readElement(der, 0, 48);
264
+ if (outer.end !== der.length || outer.start + RSA_ALGORITHM.length > der.length)
265
+ throw refuse("key");
266
+ if (!RSA_ALGORITHM.every((byte, i) => der[outer.start + i] === byte))
267
+ throw refuse("key");
268
+ const bits = readElement(der, outer.start + RSA_ALGORITHM.length, 3);
269
+ if (bits.end !== outer.end || bits.start === bits.end || der[bits.start] !== 0)
270
+ throw refuse("key");
271
+ const rsa = readElement(der, bits.start + 1, 48);
272
+ if (rsa.end !== bits.end)
273
+ throw refuse("key");
274
+ const modulus = readPositiveInteger(der, rsa.start);
275
+ const exponent = readPositiveInteger(der, modulus.end);
276
+ if (exponent.end !== rsa.end)
277
+ throw refuse("key");
278
+ const n = modulus.bytes;
279
+ if (!MERCHANT_KEY_SIZES.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
280
+ throw refuse("key");
281
+ const e = exponent.bytes;
282
+ if (e.length !== 3 || e[0] !== 1 || e[1] !== 0 || e[2] !== 1)
283
+ throw refuse("key");
284
+ return Object.freeze({ n: toBigInt(n), size: n.length });
285
+ }
286
+ function subtleOf(crypto) {
287
+ if (!crypto || !crypto.subtle || typeof crypto.getRandomValues !== "function")
288
+ throw refuse("crypto");
289
+ return crypto.subtle;
290
+ }
291
+ async function digest(subtle, hash, bytes) {
292
+ try {
293
+ return new Uint8Array(await subtle.digest(hash, bytes));
294
+ }
295
+ catch {
296
+ throw refuse("crypto");
297
+ }
298
+ }
299
+ async function mgf1(subtle, hash, seed, length) {
300
+ const out = new Uint8Array(length);
301
+ const input = new Uint8Array(seed.length + 4);
302
+ input.set(seed);
303
+ try {
304
+ for (let counter = 0, filled = 0; filled < length; counter += 1) {
305
+ input[seed.length] = counter >>> 24 & 255;
306
+ input[seed.length + 1] = counter >>> 16 & 255;
307
+ input[seed.length + 2] = counter >>> 8 & 255;
308
+ input[seed.length + 3] = counter & 255;
309
+ const block = await digest(subtle, hash, input);
310
+ out.set(block.subarray(0, Math.min(block.length, length - filled)), filled);
311
+ filled += block.length;
312
+ block.fill(0);
313
+ }
314
+ return out;
315
+ }
316
+ finally {
317
+ input.fill(0);
318
+ }
319
+ }
320
+ function randomBytes(crypto, length) {
321
+ const out = new Uint8Array(length);
322
+ try {
323
+ crypto.getRandomValues(out);
324
+ }
325
+ catch {
326
+ throw refuse("random");
327
+ }
328
+ return out;
329
+ }
330
+ async function rsaOaepEncrypt(key, message, { hash, mgf1: maskHash }, crypto, seed) {
331
+ const subtle = subtleOf(crypto);
332
+ const { n, size } = parseMerchantKey(key);
333
+ const hLen = MERCHANT_KEY_HASHES[hash];
334
+ if (!hLen || !MERCHANT_KEY_HASHES[maskHash])
335
+ throw refuse("key");
336
+ if (!isBytes(message) || message.length > size - 2 * hLen - 2)
337
+ throw refuse("text");
338
+ const db = new Uint8Array(size - hLen - 1);
339
+ const em = new Uint8Array(size);
340
+ let seedBytes = null;
341
+ let dbMask = null;
342
+ let seedMask = null;
343
+ try {
344
+ db.set(await digest(subtle, hash, new Uint8Array(0)));
345
+ db[db.length - message.length - 1] = 1;
346
+ db.set(message, db.length - message.length);
347
+ if (seed !== void 0) {
348
+ if (!isBytes(seed) || seed.length !== hLen)
349
+ throw refuse("random");
350
+ seedBytes = Uint8Array.from(seed);
351
+ }
352
+ else {
353
+ seedBytes = randomBytes(crypto, hLen);
354
+ }
355
+ dbMask = await mgf1(subtle, maskHash, seedBytes, db.length);
356
+ for (let i = 0; i < db.length; i += 1)
357
+ db[i] ^= dbMask[i];
358
+ seedMask = await mgf1(subtle, maskHash, db, hLen);
359
+ for (let i = 0; i < hLen; i += 1)
360
+ seedBytes[i] ^= seedMask[i];
361
+ em.set(seedBytes, 1);
362
+ em.set(db, 1 + hLen);
363
+ return toBytes(modPow(toBigInt(em), 65537n, n), size);
364
+ }
365
+ finally {
366
+ db.fill(0);
367
+ em.fill(0);
368
+ if (seedBytes)
369
+ seedBytes.fill(0);
370
+ if (dbMask)
371
+ dbMask.fill(0);
372
+ if (seedMask)
373
+ seedMask.fill(0);
374
+ }
375
+ }
376
+ // src/substitution-primitives.js
377
+ var SubstitutionError = class extends Error {
378
+ constructor(message) {
379
+ super(message);
380
+ this.name = "SubstitutionError";
381
+ }
382
+ };
383
+ // src/toast.js
384
+ var TOAST_PSP = "toast";
385
+ var TOAST_PAYMENT_METHODS_URL = "https://payments.toasttab.com/v1/payment-methods";
386
+ var TOAST_KEY_ID = "RSA-OAEP-SHA1::bacb4887-8314-4c23-98fc-d5ef7bc99e94_oo-legacy-browsers";
387
+ var TOAST_KEY = /* @__PURE__ */ Object.freeze({
388
+ spki: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkq50dXdz/fQOwYUswZRXgh5Vghs1tcJZCv2goNsC5BO3dXC/EiejcApaE/fKVMespzDNSLsQHXrWHegpE2piyeBwMzpTbHrCG3v6MnG6Nu+9dBYxPS4T9cNMsf0V/iCPiiaTXib6r8IfOjVZTTas2nKGZEtiDfYJIS3bJ/f30SMP4dAFILvzXGALeqleB/psQ8AFc/qUZf7VZpRnoGtKoo8wD253xTmDdaiKqr09bcJZxhTWsCB9aYouqdbl6y9/5Lu+MtyBkj7LI05g5QqDSfVax0sp/Fe7RY5SYxwlR4GlMonwtbvFTMKsr6dZ1uLuNjHA/6dm+112Uqn/AxrKGwIDAQAB",
389
+ sha256: "5475b78c9577b1258615286307547aba18c52faa6fd7d60ad0cfcb996e21ad0e"
390
+ });
391
+ var TOAST_CIPHERTEXT_BYTES = 256;
392
+ var TOAST_SUBSTITUTION = /* @__PURE__ */ Object.freeze({ at: "card", fields: Object.freeze(["cardData"]) });
393
+ var BODY_LIMIT = 8192;
394
+ var ROOT_KEYS = /* @__PURE__ */ Object.freeze(["type", "card", "sessionSecret", "usage", "setupFutureUsage", "billingDetails"]);
395
+ var CARD_KEYS = /* @__PURE__ */ Object.freeze(["keyId", "cardData"]);
396
+ var WALLETS = /* @__PURE__ */ Object.freeze(["APPLE_PAY", "GOOGLE_PAY"]);
397
+ var SESSION_SECRET = /^[\x21-\x7e]{1,1024}$/;
398
+ var POSTAL_CODE = /^[A-Za-z0-9 -]{0,16}$/;
399
+ var CIPHERTEXT_B64 = /^[A-Za-z0-9+/]{341}[AQgw]==$/;
400
+ var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
401
+ var sameKeys = (value, keys) => {
402
+ const own = Object.keys(value);
403
+ return own.length === keys.length && own.every((key, at) => key === keys[at]);
404
+ };
405
+ var failed = (code) => (
406
+ /** @type {ToastBodyReadJs} */
407
+ Object.freeze({ ok: false, code }));
408
+ function isWalletBody(parsed) {
409
+ const card = parsed.card;
410
+ const rootOk = sameKeys(parsed, ["type", "card", "sessionSecret"]) || sameKeys(parsed, ["type", "card", "sessionSecret", "billingDetails"]) && record(parsed.billingDetails);
411
+ return rootOk && WALLETS.includes(parsed.type) && record(card) && sameKeys(card, ["keyId", "cardData", "wallet"]) && card.keyId === null && typeof card.cardData === "string" && record(card.wallet) && sameKeys(card.wallet, ["type"]) && card.wallet.type === parsed.type && typeof parsed.sessionSecret === "string";
412
+ }
413
+ function isToastPaymentMethodsUrl(url) {
414
+ return url === TOAST_PAYMENT_METHODS_URL;
415
+ }
416
+ function isToastCiphertext(value) {
417
+ return typeof value === "string" && CIPHERTEXT_B64.test(value);
418
+ }
419
+ function readToastBody(body) {
420
+ const malformed = failed("toast_body_malformed");
421
+ if (typeof body !== "string" || body.length > BODY_LIMIT)
422
+ return malformed;
423
+ let parsed;
424
+ try {
425
+ parsed = JSON.parse(body);
426
+ }
427
+ catch {
428
+ return malformed;
429
+ }
430
+ if (!record(parsed) || JSON.stringify(parsed) !== body)
431
+ return malformed;
432
+ if (isWalletBody(parsed))
433
+ return (
434
+ /** @type {ToastBodyReadJs} */
435
+ Object.freeze({ ok: false, wallet: true }));
436
+ const card = parsed.card;
437
+ if (!sameKeys(parsed, ROOT_KEYS) || parsed.type !== "CARD" || !record(card) || !sameKeys(card, CARD_KEYS))
438
+ return malformed;
439
+ if (typeof card.keyId !== "string")
440
+ return malformed;
441
+ if (card.keyId !== TOAST_KEY_ID)
442
+ return failed("toast_foreign_key");
443
+ if (!isToastCiphertext(card.cardData))
444
+ return malformed;
445
+ if (typeof parsed.sessionSecret !== "string" || !SESSION_SECRET.test(parsed.sessionSecret))
446
+ return malformed;
447
+ if (parsed.usage !== null || parsed.setupFutureUsage !== null)
448
+ return failed("toast_keeps_card");
449
+ const billing = parsed.billingDetails;
450
+ if (!record(billing) || !sameKeys(billing, ["postalCode"]) || typeof billing.postalCode !== "string" || !POSTAL_CODE.test(billing.postalCode))
451
+ return malformed;
452
+ const read = { ok: true, sessionSecret: parsed.sessionSecret, postalCode: billing.postalCode, cardData: card.cardData };
453
+ return Object.freeze(read);
454
+ }
455
+ function toastRequestRefusal(request) {
456
+ if (!record(request) || typeof request.method !== "string" || request.method.toUpperCase() !== "POST" || !isToastPaymentMethodsUrl(request.url))
457
+ return "toast_url_refused";
458
+ const read = readToastBody(request.body);
459
+ return read.ok ? null : read.code ?? "toast_body_malformed";
460
+ }
461
+ var REFUSAL_MESSAGES = /* @__PURE__ */ Object.freeze({
462
+ toast_url_refused: "Refusing to pay: this Toast card request does not go to the address Toast's card form sends cards to. Nothing was sent.",
463
+ toast_foreign_key: "Refusing to pay: this Toast card request is encrypted under a key Agentcard has not reviewed. Nothing was sent.",
464
+ toast_keeps_card: "Refusing to pay: this Toast checkout asks to keep the card for later payments, and Agentcard pays only a one-time guest checkout here. Nothing was sent.",
465
+ toast_body_malformed: "Refusing to pay: this is not the card request of Toast's card form. Nothing was sent."
466
+ });
467
+ function toastRefusalMessage(code) {
468
+ return Object.prototype.hasOwnProperty.call(REFUSAL_MESSAGES, code) ? REFUSAL_MESSAGES[code] : REFUSAL_MESSAGES.toast_body_malformed;
469
+ }
470
+ // src/toast-seal.js
471
+ var TOAST_SCHEME = "rsa-oaep-sha1-json";
472
+ var MESSAGES = /* @__PURE__ */ Object.freeze({
473
+ unsupported: "Refusing to pay: this is not the card request of Toast's card form. Nothing was sent.",
474
+ card: "Could not encrypt this card for Toast. Nothing was sent."
475
+ });
476
+ var ToastError = class extends Error {
477
+ constructor(reason) {
478
+ const known = reason === "card" ? "card" : "unsupported";
479
+ super(MESSAGES[known]);
480
+ this.name = "ToastError";
481
+ this.code = "toast_refused";
482
+ this.reason = known;
483
+ }
484
+ };
485
+ var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
486
+ var has = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
487
+ var digitsOf = (value) => typeof value === "string" || typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? String(value) : null;
488
+ var POSTAL_CODE2 = /^[A-Za-z0-9 -]{0,16}$/;
489
+ function toastCardPlaintext(card, postalCode) {
490
+ if (!record2(card) || typeof postalCode !== "string" || !POSTAL_CODE2.test(postalCode))
491
+ throw new ToastError("card");
492
+ const number = digitsOf(card.number)?.replace(/\s/g, "") ?? "";
493
+ const month = digitsOf(card.month) ?? "";
494
+ const year = digitsOf(card.year) ?? "";
495
+ const cvv = digitsOf(card.cvc) ?? "";
496
+ if (!/^\d{12,19}$/.test(number) || !/^\d{1,2}$/.test(month) || !/^(?:\d{2}|\d{4})$/.test(year) || !/^\d{3,4}$/.test(cvv)) {
497
+ throw new ToastError("card");
498
+ }
499
+ if (Number(month) < 1 || Number(month) > 12)
500
+ throw new ToastError("card");
501
+ return JSON.stringify({ cardNumber: number, zipCode: postalCode, cvv, expMonth: month.padStart(2, "0"), expYear: year.slice(-2) });
502
+ }
503
+ async function encryptToastCard(card, request, facilities = {}) {
504
+ if (!record2(request) || toastRequestRefusal({ url: request.url, method: "POST", body: request.body }) !== null) {
505
+ throw new ToastError("unsupported");
506
+ }
507
+ const paused = readToastBody(request.body);
508
+ if (!paused.ok)
509
+ throw new ToastError("unsupported");
510
+ const text = new TextEncoder().encode(toastCardPlaintext(card, paused.postalCode));
511
+ try {
512
+ const sealed = await rsaOaepEncrypt(TOAST_KEY, text, { hash: "SHA-1", mgf1: "SHA-1" }, facilities.crypto ?? globalThis.crypto);
513
+ const cardData = encodeBase64(sealed);
514
+ if (!isToastCiphertext(cardData) || cardData === paused.cardData)
515
+ throw new ToastError("card");
516
+ return { cardData };
517
+ }
518
+ catch (error) {
519
+ if (error instanceof ToastError)
520
+ throw error;
521
+ throw new ToastError("card");
522
+ }
523
+ finally {
524
+ text.fill(0);
525
+ }
526
+ }
527
+ function isToastCiphertextUnderKey(value) {
528
+ if (!isToastCiphertext(value))
529
+ return false;
530
+ const bytes = decodeBase64(value);
531
+ if (!bytes || bytes.length !== TOAST_CIPHERTEXT_BYTES)
532
+ return false;
533
+ let c = 0n;
534
+ for (const byte of bytes)
535
+ c = c << 8n | BigInt(byte);
536
+ try {
537
+ return c > 1n && c < parseMerchantKey(TOAST_KEY).n;
538
+ }
539
+ catch {
540
+ return false;
541
+ }
542
+ }
543
+ function toastKeyUsable(authorization) {
544
+ if (!record2(authorization) || !record2(authorization.cse))
545
+ return false;
546
+ const cse = authorization.cse;
547
+ if (authorization.psp !== TOAST_PSP || cse.psp !== TOAST_PSP || cse.scheme !== TOAST_SCHEME)
548
+ return false;
549
+ if (cse.public_key != null || cse.client_key != null || has(cse, "merchant_hosted") || has(cse, "verifone"))
550
+ return false;
551
+ if (authorization.sandbox !== false || cse.environment !== "live")
552
+ return false;
553
+ if (toastRequestRefusal({ url: authorization.url, method: "POST", body: authorization.postData }) !== null)
554
+ return false;
555
+ try {
556
+ return parseMerchantKey(TOAST_KEY).size === TOAST_CIPHERTEXT_BYTES;
557
+ }
558
+ catch {
559
+ return false;
560
+ }
561
+ }
562
+ function toastSubstitutionsRefusal(template, substitutions) {
563
+ const refuse2 = (message) => ({ code: "invalid_substitutions", message });
564
+ if (!record2(template) || toastRequestRefusal({ url: template.url, method: "POST", body: template.body }) !== null) {
565
+ return refuse2("This authorization is not a Toast card request.");
566
+ }
567
+ const keys = record2(substitutions) ? Object.keys(substitutions) : [];
568
+ if (keys.length !== 1 || keys[0] !== "cardData")
569
+ return refuse2("substitutions must carry exactly cardData.");
570
+ if (!isToastCiphertextUnderKey(substitutions.cardData))
571
+ return refuse2("substitutions.cardData is not a card sealed under the pinned Toast key.");
572
+ const paused = readToastBody(template.body);
573
+ if (!paused.ok || substitutions.cardData === paused.cardData) {
574
+ return refuse2("substitutions.cardData is the paused request's own card, not one the cardholder's device sealed.");
575
+ }
576
+ return null;
577
+ }
578
+ function substituteToastCardData(url, body, fields) {
579
+ const refusal = toastRequestRefusal({ url, method: "POST", body });
580
+ if (refusal !== null)
581
+ throw new SubstitutionError(toastRefusalMessage(refusal));
582
+ const paused = readToastBody(body);
583
+ if (!paused.ok)
584
+ throw new SubstitutionError(toastRefusalMessage("toast_body_malformed"));
585
+ const keys = record2(fields) ? Object.keys(fields) : [];
586
+ if (keys.length !== 1 || keys[0] !== "cardData")
587
+ throw new SubstitutionError("the substitution must carry exactly cardData");
588
+ const sealed = fields.cardData;
589
+ if (!isToastCiphertextUnderKey(sealed))
590
+ throw new SubstitutionError("substitution for cardData is not a card sealed under the pinned Toast key");
591
+ if (sealed === paused.cardData || body.includes(sealed))
592
+ throw new SubstitutionError("the sealed card in this substitution is already in the body");
593
+ const parsed = JSON.parse(body);
594
+ parsed.card.cardData = sealed;
595
+ const out = JSON.stringify(parsed);
596
+ const written = readToastBody(out);
597
+ if (!written.ok || written.cardData !== sealed || written.sessionSecret !== paused.sessionSecret || written.postalCode !== paused.postalCode || out.length !== body.length || out.replace(sealed, paused.cardData) !== body) {
598
+ throw new SubstitutionError("the substitution did not land at card.cardData");
599
+ }
600
+ return out;
601
+ }
602
+ var ANSWER_LIMIT = 65536;
603
+ var METHOD_ID = /^[\x21-\x7e]{1,256}$/;
604
+ function toastAnswerOutcome(status, text) {
605
+ if (!Number.isInteger(status) || status < 100 || status > 599)
606
+ return { outcome: "unknown", reason: "toast_unconfirmed" };
607
+ if (status >= 500)
608
+ return { outcome: "unknown", reason: "server_error" };
609
+ if (status >= 400)
610
+ return { outcome: "refused", code: `http_${status}` };
611
+ if (status < 200 || status >= 300 || typeof text !== "string" || text.length > ANSWER_LIMIT)
612
+ return { outcome: "unknown", reason: "toast_unconfirmed" };
613
+ let answer;
614
+ try {
615
+ answer = JSON.parse(text);
616
+ }
617
+ catch {
618
+ return { outcome: "unknown", reason: "toast_unconfirmed" };
619
+ }
620
+ if (!record2(answer) || typeof answer.id !== "string" || !METHOD_ID.test(answer.id) || !record2(answer.card)) {
621
+ return { outcome: "unknown", reason: "toast_unconfirmed" };
622
+ }
623
+ return { outcome: "approved", body: "{}" };
624
+ }
625
+ export { TOAST_SCHEME, ToastError, encryptToastCard, isToastCiphertextUnderKey, substituteToastCardData, toastAnswerOutcome, toastCardPlaintext, toastKeyUsable, toastSubstitutionsRefusal };