@hypay/typescript-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1227 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+
23
+ // src/helpers.ts
24
+ var helpers_exports = {};
25
+ __export(helpers_exports, {
26
+ buildItemsString: () => buildItemsString,
27
+ calculateItemsTotal: () => calculateItemsTotal,
28
+ isTestMasof: () => isTestMasof,
29
+ isValidEmail: () => isValidEmail,
30
+ isValidIsraeliId: () => isValidIsraeliId,
31
+ isValidMasof: () => isValidMasof,
32
+ isValidToken: () => isValidToken,
33
+ parsePaymentPageResponse: () => parsePaymentPageResponse,
34
+ parseQueryString: () => parseQueryString,
35
+ parseRedirectUrl: () => parseRedirectUrl,
36
+ parseTokef: () => parseTokef,
37
+ serializeParams: () => serializeParams,
38
+ toQueryString: () => toQueryString
39
+ });
40
+ function parseQueryString(qs) {
41
+ const result = {};
42
+ const trimmed = qs.trim();
43
+ if (!trimmed) return result;
44
+ for (const pair of trimmed.split("&")) {
45
+ const eqIndex = pair.indexOf("=");
46
+ if (eqIndex === -1) {
47
+ const key = decodeURIComponent(pair);
48
+ if (key) result[key] = "";
49
+ } else {
50
+ const key = decodeURIComponent(pair.slice(0, eqIndex));
51
+ const value = decodeURIComponent(pair.slice(eqIndex + 1));
52
+ if (key) result[key] = value;
53
+ }
54
+ }
55
+ return result;
56
+ }
57
+ function toQueryString(params) {
58
+ const parts = [];
59
+ for (const [key, value] of Object.entries(params)) {
60
+ if (value === void 0) continue;
61
+ parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
62
+ }
63
+ return parts.join("&");
64
+ }
65
+ function serializeParams(params) {
66
+ const result = {};
67
+ for (const [key, value] of Object.entries(params)) {
68
+ if (value === void 0) continue;
69
+ if (typeof value === "boolean") {
70
+ result[key] = value ? "True" : "False";
71
+ } else {
72
+ result[key] = value;
73
+ }
74
+ }
75
+ return result;
76
+ }
77
+ function parseRedirectUrl(url) {
78
+ const qsIndex = url.indexOf("?");
79
+ if (qsIndex === -1) return {};
80
+ return parseQueryString(url.slice(qsIndex + 1));
81
+ }
82
+ function parsePaymentPageResponse(url) {
83
+ const params = parseRedirectUrl(url);
84
+ return params;
85
+ }
86
+ function parseTokef(tokef) {
87
+ if (!tokef || tokef.length !== 4) {
88
+ throw new Error(`Invalid Tokef format: "${tokef}". Expected 4-digit YYMM string.`);
89
+ }
90
+ const yy = tokef.slice(0, 2);
91
+ const mm = tokef.slice(2, 4);
92
+ return {
93
+ Tmonth: mm,
94
+ Tyear: `20${yy}`
95
+ };
96
+ }
97
+ function buildItemsString(items) {
98
+ return items.map((item) => `[${item.code}~${item.description}~${item.quantity}~${item.price}]`).join("");
99
+ }
100
+ function calculateItemsTotal(items) {
101
+ return items.reduce((sum, item) => sum + item.quantity * item.price, 0);
102
+ }
103
+ function isValidMasof(masof) {
104
+ return /^\d{10}$/.test(masof);
105
+ }
106
+ function isTestMasof(masof) {
107
+ return isValidMasof(masof) && masof.startsWith("00100");
108
+ }
109
+ function isValidToken(token) {
110
+ return /^\d{19}$/.test(token);
111
+ }
112
+ function isValidEmail(email) {
113
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
114
+ }
115
+ function isValidIsraeliId(id) {
116
+ if (!/^\d{9}$/.test(id)) return false;
117
+ if (id === "000000000") return true;
118
+ let sum = 0;
119
+ for (let i = 0; i < 9; i++) {
120
+ let digit = parseInt(id[i], 10) * (i % 2 + 1);
121
+ if (digit > 9) digit -= 9;
122
+ sum += digit;
123
+ }
124
+ return sum % 10 === 0;
125
+ }
126
+ var init_helpers = __esm({
127
+ "src/helpers.ts"() {
128
+ "use strict";
129
+ }
130
+ });
131
+
132
+ // src/index.ts
133
+ var index_exports = {};
134
+ __export(index_exports, {
135
+ ALL_ERROR_CODES: () => ALL_ERROR_CODES,
136
+ Bank: () => Bank,
137
+ Brand: () => Brand,
138
+ Coin: () => Coin,
139
+ HKNewStatus: () => HKNewStatus,
140
+ HYPAY_ERROR_CODES: () => HYPAY_ERROR_CODES,
141
+ HypayClient: () => HypayClient,
142
+ HypayError: () => HypayError,
143
+ HypayNetworkError: () => HypayNetworkError,
144
+ HypayTimeoutError: () => HypayTimeoutError,
145
+ Issuer: () => Issuer,
146
+ PageLang: () => PageLang,
147
+ SHVA_ERROR_CODES: () => SHVA_ERROR_CODES,
148
+ SpecialCardType: () => SpecialCardType,
149
+ TashType: () => TashType,
150
+ buildItemsString: () => buildItemsString,
151
+ calculateItemsTotal: () => calculateItemsTotal,
152
+ getErrorMessage: () => getErrorMessage,
153
+ isHypayError: () => isHypayError,
154
+ isShvaError: () => isShvaError,
155
+ isSuccessCode: () => isSuccessCode,
156
+ isTestMasof: () => isTestMasof,
157
+ isValidEmail: () => isValidEmail,
158
+ isValidIsraeliId: () => isValidIsraeliId,
159
+ isValidMasof: () => isValidMasof,
160
+ isValidToken: () => isValidToken,
161
+ parsePaymentPageResponse: () => parsePaymentPageResponse,
162
+ parseQueryString: () => parseQueryString,
163
+ parseRedirectUrl: () => parseRedirectUrl,
164
+ parseTokef: () => parseTokef,
165
+ serializeParams: () => serializeParams,
166
+ toQueryString: () => toQueryString
167
+ });
168
+ module.exports = __toCommonJS(index_exports);
169
+
170
+ // src/types.ts
171
+ var Coin = /* @__PURE__ */ ((Coin2) => {
172
+ Coin2[Coin2["ILS"] = 1] = "ILS";
173
+ Coin2[Coin2["USD"] = 2] = "USD";
174
+ Coin2[Coin2["EUR"] = 3] = "EUR";
175
+ Coin2[Coin2["GBP"] = 4] = "GBP";
176
+ return Coin2;
177
+ })(Coin || {});
178
+ var PageLang = /* @__PURE__ */ ((PageLang2) => {
179
+ PageLang2["HEB"] = "HEB";
180
+ PageLang2["ENG"] = "ENG";
181
+ return PageLang2;
182
+ })(PageLang || {});
183
+ var TashType = /* @__PURE__ */ ((TashType2) => {
184
+ TashType2[TashType2["Regular"] = 1] = "Regular";
185
+ TashType2[TashType2["Credit"] = 6] = "Credit";
186
+ return TashType2;
187
+ })(TashType || {});
188
+ var Bank = /* @__PURE__ */ ((Bank2) => {
189
+ Bank2[Bank2["Isracard"] = 1] = "Isracard";
190
+ Bank2[Bank2["VisaCal"] = 2] = "VisaCal";
191
+ Bank2[Bank2["Diners"] = 3] = "Diners";
192
+ Bank2[Bank2["Amex"] = 4] = "Amex";
193
+ Bank2[Bank2["MAX"] = 6] = "MAX";
194
+ Bank2[Bank2["BIT"] = 99] = "BIT";
195
+ return Bank2;
196
+ })(Bank || {});
197
+ var Brand = /* @__PURE__ */ ((Brand2) => {
198
+ Brand2[Brand2["PL"] = 0] = "PL";
199
+ Brand2[Brand2["MasterCard"] = 1] = "MasterCard";
200
+ Brand2[Brand2["Visa"] = 2] = "Visa";
201
+ Brand2[Brand2["Diners"] = 3] = "Diners";
202
+ Brand2[Brand2["Amex"] = 4] = "Amex";
203
+ Brand2[Brand2["Isracard"] = 5] = "Isracard";
204
+ return Brand2;
205
+ })(Brand || {});
206
+ var Issuer = /* @__PURE__ */ ((Issuer2) => {
207
+ Issuer2[Issuer2["Foreign"] = 0] = "Foreign";
208
+ Issuer2[Issuer2["Isracard"] = 1] = "Isracard";
209
+ Issuer2[Issuer2["VisaCal"] = 2] = "VisaCal";
210
+ Issuer2[Issuer2["JCB"] = 5] = "JCB";
211
+ Issuer2[Issuer2["MAX"] = 6] = "MAX";
212
+ return Issuer2;
213
+ })(Issuer || {});
214
+ var HKNewStatus = /* @__PURE__ */ ((HKNewStatus2) => {
215
+ HKNewStatus2[HKNewStatus2["Terminate"] = 1] = "Terminate";
216
+ HKNewStatus2[HKNewStatus2["Activate"] = 2] = "Activate";
217
+ return HKNewStatus2;
218
+ })(HKNewStatus || {});
219
+ var SpecialCardType = /* @__PURE__ */ ((SpecialCardType2) => {
220
+ SpecialCardType2["Default"] = "00";
221
+ SpecialCardType2["Immediate"] = "01";
222
+ SpecialCardType2["Club"] = "70";
223
+ SpecialCardType2["PetrolCard"] = "03";
224
+ SpecialCardType2["DualCard"] = "04";
225
+ SpecialCardType2["DualClub"] = "74";
226
+ SpecialCardType2["PetrolClub"] = "75";
227
+ SpecialCardType2["Chargeable"] = "06";
228
+ SpecialCardType2["Petrol"] = "08";
229
+ SpecialCardType2["Tourist"] = "99";
230
+ return SpecialCardType2;
231
+ })(SpecialCardType || {});
232
+ var HypayError = class extends Error {
233
+ constructor(message, code, raw, params) {
234
+ super(message);
235
+ this.name = "HypayError";
236
+ this.code = code;
237
+ this.raw = raw;
238
+ this.params = params;
239
+ }
240
+ };
241
+ var HypayNetworkError = class extends Error {
242
+ constructor(message, cause) {
243
+ super(message);
244
+ this.name = "HypayNetworkError";
245
+ this.cause = cause;
246
+ }
247
+ };
248
+ var HypayTimeoutError = class extends Error {
249
+ constructor(timeoutMs) {
250
+ super(`Request timed out after ${timeoutMs}ms`);
251
+ this.name = "HypayTimeoutError";
252
+ this.timeoutMs = timeoutMs;
253
+ }
254
+ };
255
+
256
+ // src/client.ts
257
+ init_helpers();
258
+
259
+ // src/errors.ts
260
+ var HYPAY_ERROR_CODES = {
261
+ "33": "Refund amount is greater than the original transaction amount",
262
+ "250": "Deal does not exist or already committed",
263
+ "400": "Sum of items differs from transaction amount",
264
+ "401": "First or last name is required",
265
+ "402": "Transaction information (Info) is required",
266
+ "600": "Checking card number (J2)",
267
+ "700": "Approved without charge (J5 credit line reservation)",
268
+ "800": "Postpone transaction (delayed charge)",
269
+ "901": "Terminal is not permitted to work in this method",
270
+ "902": "Authentication error \u2014 reference differs from configured method",
271
+ "903": "Number of payments exceeds terminal configuration",
272
+ "905": "Wrong parameter value",
273
+ "906": "Agreement does not exist",
274
+ "910": "Token request from invalid transaction \u2014 add allowFalse=True",
275
+ "920": "Deal does not exist or already committed/cancelled",
276
+ "990": "Card details not fully readable",
277
+ "996": "Terminal is not permitted to use token",
278
+ "997": "Token is not valid",
279
+ "998": "Deal cancelled",
280
+ "999": "Communication error"
281
+ };
282
+ var SHVA_ERROR_CODES = {
283
+ "0": "Approved",
284
+ "000": "Approved",
285
+ "1": "Card blocked \u2014 confiscate card",
286
+ "001": "Card blocked",
287
+ "2": "Stolen card \u2014 confiscate card",
288
+ "002": "Stolen card \u2014 confiscate card",
289
+ "3": "Call credit card company",
290
+ "003": "Call credit card company",
291
+ "4": "Transaction not approved",
292
+ "004": "Transaction not approved",
293
+ "5": "Forged card \u2014 confiscate card",
294
+ "005": "Forged card \u2014 confiscate card",
295
+ "6": "Incorrect ID or CVV",
296
+ "006": "Rejected: incorrect CVV2",
297
+ "7": "Must call credit card company",
298
+ "007": "Rejected: incorrect CAVV/UCAF",
299
+ "8": "Error building encryption key for blocked file",
300
+ "008": "Rejected: incorrect AVS",
301
+ "9": "Could not connect \u2014 call credit card company",
302
+ "009": "Rejection \u2014 communication disconnect",
303
+ "010": "Partial approval",
304
+ "011": "Rejected: insufficient points/stars/miles/benefit",
305
+ "012": "Card not authorized at this terminal",
306
+ "013": "Rejected: incorrect balance code",
307
+ "014": "Rejected: card not associated with network",
308
+ "015": "Rejected: card not valid (expired)",
309
+ "016": "Rejected: currency not authorized",
310
+ "017": "Rejected: credit type not authorized for transaction",
311
+ "026": "Rejected: incorrect ID",
312
+ "033": "Invalid card",
313
+ "036": "Expired card",
314
+ "041": "Must query due to ceiling only for J2 transaction",
315
+ "042": "Must query (not ceiling-only) for J2 transaction",
316
+ "173": "Duplicate transaction"
317
+ };
318
+ var ALL_ERROR_CODES = {
319
+ ...SHVA_ERROR_CODES,
320
+ ...HYPAY_ERROR_CODES
321
+ };
322
+ function getErrorMessage(ccode) {
323
+ return ALL_ERROR_CODES[ccode] ?? `Unknown error (CCode=${ccode})`;
324
+ }
325
+ function isSuccessCode(ccode) {
326
+ return ccode === "0" || ccode === "600" || ccode === "700" || ccode === "800";
327
+ }
328
+ function isShvaError(ccode) {
329
+ const num = parseInt(ccode, 10);
330
+ return !isNaN(num) && num >= 1 && num <= 200;
331
+ }
332
+ function isHypayError(ccode) {
333
+ const num = parseInt(ccode, 10);
334
+ if (isNaN(num)) return false;
335
+ if (num === 600 || num === 700 || num === 800) return false;
336
+ return num >= 201 && num <= 999;
337
+ }
338
+
339
+ // src/client.ts
340
+ var DEFAULT_BASE_URL = "https://pay.hyp.co.il/p/";
341
+ var DEFAULT_TIMEOUT = 3e4;
342
+ var HypayClient = class {
343
+ constructor(config) {
344
+ this.masof = config.masof;
345
+ this.apiKey = config.apiKey;
346
+ this.passP = config.passP;
347
+ this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/?$/, "/");
348
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
349
+ this.fetchFn = config.fetch ?? globalThis.fetch;
350
+ this.hooks = config.hooks ?? {};
351
+ }
352
+ // ─── Low-level HTTP ──────────────────────────────────────────────────────
353
+ /**
354
+ * Make a GET request to the Hypay API.
355
+ * All API calls use GET by default, which is the most common method for Hypay.
356
+ */
357
+ async requestGet(action, params) {
358
+ const serialized = serializeParams(params);
359
+ const qs = toQueryString(serialized);
360
+ const url = `${this.baseUrl}?${qs}`;
361
+ const context = {
362
+ action,
363
+ method: "GET",
364
+ url,
365
+ params: Object.fromEntries(
366
+ Object.entries(serialized).filter(([, v]) => v !== void 0).map(([k, v]) => [k, String(v)])
367
+ )
368
+ };
369
+ await this.hooks.onRequest?.(context);
370
+ const start = Date.now();
371
+ let response;
372
+ try {
373
+ const controller = new AbortController();
374
+ const timer = setTimeout(() => controller.abort(), this.timeout);
375
+ try {
376
+ response = await this.fetchFn(url, { signal: controller.signal });
377
+ } finally {
378
+ clearTimeout(timer);
379
+ }
380
+ } catch (err) {
381
+ if (err instanceof DOMException && err.name === "AbortError") {
382
+ throw new HypayTimeoutError(this.timeout);
383
+ }
384
+ throw new HypayNetworkError(
385
+ `Network error while calling Hypay API: ${err instanceof Error ? err.message : String(err)}`,
386
+ err
387
+ );
388
+ }
389
+ const text = await response.text();
390
+ const parsed = parseQueryString(text);
391
+ const durationMs = Date.now() - start;
392
+ await this.hooks.onResponse?.({
393
+ ...context,
394
+ statusCode: response.status,
395
+ raw: text,
396
+ parsedParams: parsed,
397
+ durationMs
398
+ });
399
+ return { raw: text, params: parsed };
400
+ }
401
+ /**
402
+ * Make a POST request to the Hypay API.
403
+ * Use for actions that send large payloads (e.g., WalletToken with Apple Pay).
404
+ */
405
+ async requestPost(action, params) {
406
+ const serialized = serializeParams(params);
407
+ const body = toQueryString(serialized);
408
+ const context = {
409
+ action,
410
+ method: "POST",
411
+ url: this.baseUrl,
412
+ params: Object.fromEntries(
413
+ Object.entries(serialized).filter(([, v]) => v !== void 0).map(([k, v]) => [k, String(v)])
414
+ )
415
+ };
416
+ await this.hooks.onRequest?.(context);
417
+ const start = Date.now();
418
+ let response;
419
+ try {
420
+ const controller = new AbortController();
421
+ const timer = setTimeout(() => controller.abort(), this.timeout);
422
+ try {
423
+ response = await this.fetchFn(this.baseUrl, {
424
+ method: "POST",
425
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
426
+ body,
427
+ signal: controller.signal
428
+ });
429
+ } finally {
430
+ clearTimeout(timer);
431
+ }
432
+ } catch (err) {
433
+ if (err instanceof DOMException && err.name === "AbortError") {
434
+ throw new HypayTimeoutError(this.timeout);
435
+ }
436
+ throw new HypayNetworkError(
437
+ `Network error while calling Hypay API: ${err instanceof Error ? err.message : String(err)}`,
438
+ err
439
+ );
440
+ }
441
+ const text = await response.text();
442
+ const parsed = parseQueryString(text);
443
+ const durationMs = Date.now() - start;
444
+ await this.hooks.onResponse?.({
445
+ ...context,
446
+ statusCode: response.status,
447
+ raw: text,
448
+ parsedParams: parsed,
449
+ durationMs
450
+ });
451
+ return { raw: text, params: parsed };
452
+ }
453
+ /**
454
+ * Unified request method. Defaults to GET, uses POST for wallet/large payloads.
455
+ */
456
+ async request(action, params, method = "GET") {
457
+ return method === "POST" ? this.requestPost(action, params) : this.requestGet(action, params);
458
+ }
459
+ authParams() {
460
+ return {
461
+ Masof: this.masof,
462
+ PassP: this.passP
463
+ };
464
+ }
465
+ throwIfError(parsed, raw, context) {
466
+ if (parsed.CCode && !isSuccessCode(parsed.CCode)) {
467
+ const error = new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
468
+ if (context) {
469
+ this.hooks.onError?.(error, context);
470
+ }
471
+ throw error;
472
+ }
473
+ }
474
+ // ═══════════════════════════════════════════════════════════════════════════
475
+ // PAY PROTOCOL — Payment Page
476
+ // ═══════════════════════════════════════════════════════════════════════════
477
+ /**
478
+ * **Step 1** — Sign payment page parameters (APISign + What=SIGN).
479
+ *
480
+ * This generates a `signature` that must be appended to the payment page URL.
481
+ * The signature prevents parameter tampering on the client side.
482
+ *
483
+ * Requires "Verify by signature in the payment page" enabled in terminal settings.
484
+ *
485
+ * @example
486
+ * ```ts
487
+ * const result = await client.sign({
488
+ * Info: "Order #123",
489
+ * Amount: 100,
490
+ * UserId: "203269535",
491
+ * ClientName: "Israel",
492
+ * Coin: Coin.ILS,
493
+ * Sign: true,
494
+ * UTF8: true,
495
+ * UTF8out: true,
496
+ * MoreData: true,
497
+ * });
498
+ * console.log(result.signature);
499
+ * ```
500
+ */
501
+ async sign(params) {
502
+ const allParams = {
503
+ action: "APISign",
504
+ What: "SIGN",
505
+ KEY: this.apiKey,
506
+ ...this.authParams(),
507
+ ...params
508
+ };
509
+ const { raw, params: parsed } = await this.request("APISign", allParams);
510
+ return {
511
+ raw,
512
+ signature: parsed.signature ?? "",
513
+ params: parsed
514
+ };
515
+ }
516
+ /**
517
+ * **Step 2** — Build the full payment page URL from a signed query string.
518
+ *
519
+ * @param signedQueryString - The raw result from `sign()`.
520
+ */
521
+ buildPaymentPageUrl(signedQueryString) {
522
+ return `${this.baseUrl}?${signedQueryString}`;
523
+ }
524
+ /**
525
+ * **Steps 1 + 2 combined** — Sign parameters and return the full payment page URL.
526
+ *
527
+ * @example
528
+ * ```ts
529
+ * const url = await client.createPaymentPageUrl({
530
+ * Info: "Order #123",
531
+ * Amount: 100,
532
+ * UserId: "203269535",
533
+ * ClientName: "Israel",
534
+ * Coin: Coin.ILS,
535
+ * Sign: true,
536
+ * UTF8: true,
537
+ * UTF8out: true,
538
+ * });
539
+ * // Redirect the customer to `url`
540
+ * ```
541
+ */
542
+ async createPaymentPageUrl(params) {
543
+ const signResult = await this.sign(params);
544
+ return this.buildPaymentPageUrl(signResult.raw);
545
+ }
546
+ // ═══════════════════════════════════════════════════════════════════════════
547
+ // VERIFICATION — Verify transaction signature
548
+ // ═══════════════════════════════════════════════════════════════════════════
549
+ /**
550
+ * **Step 4** — Verify a transaction using parameters from the success page.
551
+ *
552
+ * Takes the query parameters from the success/failure redirect URL and verifies
553
+ * them against the Hypay server. Returns `verified: true` when `CCode === "0"`,
554
+ * `CCode === "902"` means verification failed.
555
+ *
556
+ * Requires "Verify by signature in the payment page" enabled in terminal settings.
557
+ *
558
+ * @example
559
+ * ```ts
560
+ * import { parseRedirectUrl } from "@hypay/typescript-sdk";
561
+ *
562
+ * const successParams = parseRedirectUrl(req.url);
563
+ * const result = await client.verify(successParams);
564
+ *
565
+ * if (result.verified) {
566
+ * // Transaction is legitimate — process the order
567
+ * } else {
568
+ * // Verification failed — do not process
569
+ * }
570
+ * ```
571
+ */
572
+ async verify(params) {
573
+ const allParams = {
574
+ action: "APISign",
575
+ What: "VERIFY",
576
+ KEY: this.apiKey,
577
+ ...this.authParams(),
578
+ ...params
579
+ };
580
+ const { raw, params: parsed } = await this.request("APISign-VERIFY", allParams);
581
+ return {
582
+ verified: parsed.CCode === "0",
583
+ CCode: parsed.CCode ?? "",
584
+ raw,
585
+ params: parsed
586
+ };
587
+ }
588
+ /**
589
+ * Convenience method: parse a success page URL and verify it in one call.
590
+ *
591
+ * @example
592
+ * ```ts
593
+ * const result = await client.verifyRedirectUrl(
594
+ * "https://yoursite.com/success?Id=123&CCode=0&Amount=10&..."
595
+ * );
596
+ * if (result.verified) { /* OK *\/ }
597
+ * ```
598
+ */
599
+ async verifyRedirectUrl(redirectUrl) {
600
+ const { parseRedirectUrl: parseRedirectUrl2 } = await Promise.resolve().then(() => (init_helpers(), helpers_exports));
601
+ const params = parseRedirectUrl2(redirectUrl);
602
+ return this.verify(params);
603
+ }
604
+ // ═══════════════════════════════════════════════════════════════════════════
605
+ // SOFT PROTOCOL — Server-side transactions
606
+ // ═══════════════════════════════════════════════════════════════════════════
607
+ /**
608
+ * Execute a server-side transaction using the Soft protocol.
609
+ *
610
+ * Used for:
611
+ * - Token-based charges (after obtaining a token via `getToken()`)
612
+ * - Apple Pay / Google Pay via WalletToken
613
+ * - Direct credit card charges (PCI-compliant environments)
614
+ *
615
+ * Automatically uses POST for WalletToken requests (large payload).
616
+ *
617
+ * @throws {HypayError} When CCode indicates an error
618
+ *
619
+ * @example
620
+ * ```ts
621
+ * // Token-based transaction
622
+ * const result = await client.soft({
623
+ * CC: "1315872608557940000",
624
+ * Tmonth: "04",
625
+ * Tyear: "2025",
626
+ * Amount: 50,
627
+ * Info: "Subscription renewal",
628
+ * UserId: "203269535",
629
+ * ClientName: "Israel",
630
+ * Token: true,
631
+ * MoreData: true,
632
+ * UTF8: true,
633
+ * UTF8out: true,
634
+ * });
635
+ * ```
636
+ *
637
+ * @example
638
+ * ```ts
639
+ * // Apple Pay / Google Pay
640
+ * const result = await client.soft({
641
+ * WalletToken: walletTokenJson,
642
+ * Amount: 100,
643
+ * Info: "Purchase",
644
+ * UserId: "203269535",
645
+ * ClientName: "Israel",
646
+ * });
647
+ * ```
648
+ */
649
+ async soft(params) {
650
+ const allParams = {
651
+ action: "soft",
652
+ ...this.authParams(),
653
+ ...params
654
+ };
655
+ const method = "WalletToken" in params && params.WalletToken ? "POST" : "GET";
656
+ const { raw, params: parsed } = await this.request("soft", allParams, method);
657
+ if (parsed.CCode && !isSuccessCode(parsed.CCode)) {
658
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
659
+ }
660
+ return {
661
+ Id: parsed.Id ?? "",
662
+ CCode: parsed.CCode ?? "",
663
+ Amount: parsed.Amount ?? "",
664
+ ACode: parsed.ACode ?? "",
665
+ Fild1: parsed.Fild1,
666
+ Fild2: parsed.Fild2,
667
+ Fild3: parsed.Fild3,
668
+ Hesh: parsed.Hesh,
669
+ UID: parsed.UID,
670
+ errMsg: parsed.errMsg,
671
+ raw,
672
+ params: parsed
673
+ };
674
+ }
675
+ // ═══════════════════════════════════════════════════════════════════════════
676
+ // TOKENS — Get and manage tokens
677
+ // ═══════════════════════════════════════════════════════════════════════════
678
+ /**
679
+ * Obtain a token for a previously completed transaction.
680
+ *
681
+ * The token (19 digits) replaces credit card information for future Soft transactions.
682
+ * The transaction must be in one of these statuses: Approved (0), 600, 700, 800, 998.
683
+ *
684
+ * **Important:** Save the Tokef (card validity) and customer details (UserId, etc.)
685
+ * as they are NOT stored in Hypay servers.
686
+ *
687
+ * The response includes convenience fields `Tmonth` and `Tyear` parsed from `Tokef`.
688
+ *
689
+ * @throws {HypayError} When CCode indicates an error (901, 902, 910, 990)
690
+ *
691
+ * @example
692
+ * ```ts
693
+ * const token = await client.getToken({ TransId: "12788261" });
694
+ *
695
+ * // Save for future charges:
696
+ * // token.Token = "1315872608557940000"
697
+ * // token.Tmonth = "04"
698
+ * // token.Tyear = "2025"
699
+ *
700
+ * // Use in a soft transaction:
701
+ * await client.soft({
702
+ * CC: token.Token,
703
+ * Tmonth: token.Tmonth,
704
+ * Tyear: token.Tyear,
705
+ * Token: true,
706
+ * Amount: 50,
707
+ * Info: "Charge via token",
708
+ * UserId: "203269535",
709
+ * ClientName: "Israel",
710
+ * });
711
+ * ```
712
+ */
713
+ async getToken(params) {
714
+ const allParams = {
715
+ action: "getToken",
716
+ ...this.authParams(),
717
+ TransId: params.TransId,
718
+ Fild1: params.Fild1,
719
+ Fild2: params.Fild2,
720
+ Fild3: params.Fild3,
721
+ allowFalse: params.allowFalse
722
+ };
723
+ const { raw, params: parsed } = await this.request("getToken", allParams);
724
+ if (parsed.CCode && parsed.CCode !== "0") {
725
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
726
+ }
727
+ let Tmonth = "";
728
+ let Tyear = "";
729
+ if (parsed.Tokef && parsed.Tokef.length === 4) {
730
+ const parsed_tokef = parseTokef(parsed.Tokef);
731
+ Tmonth = parsed_tokef.Tmonth;
732
+ Tyear = parsed_tokef.Tyear;
733
+ }
734
+ return {
735
+ Id: parsed.Id ?? "",
736
+ CCode: parsed.CCode ?? "",
737
+ Token: parsed.Token ?? "",
738
+ Tokef: parsed.Tokef ?? "",
739
+ Tmonth,
740
+ Tyear,
741
+ Fild1: parsed.Fild1,
742
+ Fild2: parsed.Fild2,
743
+ Fild3: parsed.Fild3,
744
+ raw,
745
+ params: parsed
746
+ };
747
+ }
748
+ // ═══════════════════════════════════════════════════════════════════════════
749
+ // TRANSACTION J5 — Charge a J5 reservation
750
+ // ═══════════════════════════════════════════════════════════════════════════
751
+ /**
752
+ * Charge a J5 (credit line reservation) transaction.
753
+ *
754
+ * When a Pay/Soft request was made with `J5=True` and `MoreData=True`,
755
+ * you can later charge the reserved amount using the UID and ACode from the response.
756
+ *
757
+ * **If charge amount <= original J5 amount:** use this method (soft + additional params).
758
+ * **If charge amount > original J5 amount:** use the regular token flow instead.
759
+ *
760
+ * @param tokenParams - Standard Soft token parameters (CC, Tmonth, Tyear, etc.)
761
+ * @param j5Params - J5-specific parameters (originalUid, originalAmount, AuthNum)
762
+ *
763
+ * @throws {HypayError} When CCode indicates an error
764
+ *
765
+ * @example
766
+ * ```ts
767
+ * const result = await client.chargeJ5(
768
+ * {
769
+ * CC: token.Token,
770
+ * Tmonth: token.Tmonth,
771
+ * Tyear: token.Tyear,
772
+ * Token: true,
773
+ * Amount: 50,
774
+ * Info: "J5 charge",
775
+ * UserId: "203269535",
776
+ * ClientName: "Israel",
777
+ * },
778
+ * {
779
+ * "inputObj.originalUid": originalResponse.UID,
780
+ * "inputObj.originalAmount": 5000, // 50 ILS in agorot
781
+ * AuthNum: originalResponse.ACode,
782
+ * "inputObj.authorizationCodeManpik": 7,
783
+ * }
784
+ * );
785
+ * ```
786
+ */
787
+ async chargeJ5(tokenParams, j5Params) {
788
+ const allParams = {
789
+ action: "soft",
790
+ ...this.authParams(),
791
+ ...tokenParams,
792
+ ...j5Params
793
+ };
794
+ const { raw, params: parsed } = await this.request("soft-J5", allParams);
795
+ if (parsed.CCode && !isSuccessCode(parsed.CCode)) {
796
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
797
+ }
798
+ return {
799
+ Id: parsed.Id ?? "",
800
+ CCode: parsed.CCode ?? "",
801
+ Amount: parsed.Amount ?? "",
802
+ ACode: parsed.ACode ?? "",
803
+ Fild1: parsed.Fild1,
804
+ Fild2: parsed.Fild2,
805
+ Fild3: parsed.Fild3,
806
+ Hesh: parsed.Hesh,
807
+ UID: parsed.UID,
808
+ errMsg: parsed.errMsg,
809
+ raw,
810
+ params: parsed
811
+ };
812
+ }
813
+ // ═══════════════════════════════════════════════════════════════════════════
814
+ // POSTPONE — Commit delayed transactions
815
+ // ═══════════════════════════════════════════════════════════════════════════
816
+ /**
817
+ * Commit a postponed transaction (CCode 800).
818
+ *
819
+ * Postponed transactions should be committed within 72 hours.
820
+ * If not committed, leave at status 800 (do not cancel).
821
+ *
822
+ * @throws {HypayError} When CCode indicates an error (250 = doesn't exist / already committed)
823
+ *
824
+ * @example
825
+ * ```ts
826
+ * const result = await client.commitTransaction({
827
+ * TransId: "5343635",
828
+ * SendHesh: true,
829
+ * heshDesc: "Payment for order 1234",
830
+ * UTF8: true,
831
+ * UTF8out: true,
832
+ * });
833
+ * console.log(result.HeshASM); // Invoice number
834
+ * ```
835
+ */
836
+ async commitTransaction(params) {
837
+ const allParams = {
838
+ action: "commitTrans",
839
+ ...this.authParams(),
840
+ ...params
841
+ };
842
+ const { raw, params: parsed } = await this.request("commitTrans", allParams);
843
+ if (parsed.CCode && parsed.CCode !== "0") {
844
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
845
+ }
846
+ return {
847
+ Id: parsed.Id ?? "",
848
+ CCode: parsed.CCode ?? "",
849
+ HeshASM: parsed.HeshASM,
850
+ Fild1: parsed.Fild1,
851
+ Fild2: parsed.Fild2,
852
+ Fild3: parsed.Fild3,
853
+ raw,
854
+ params: parsed
855
+ };
856
+ }
857
+ // ═══════════════════════════════════════════════════════════════════════════
858
+ // CANCEL — Cancel a transaction
859
+ // ═══════════════════════════════════════════════════════════════════════════
860
+ /**
861
+ * Cancel a transaction.
862
+ *
863
+ * **Rules:**
864
+ * - Only on the same day, before 23:20 (before SHVA deposit)
865
+ * - Cancelled transactions CANNOT be restored
866
+ * - No cost to the business (transaction won't be presented to credit card companies)
867
+ * - If invoice module is active, a credit memo will be issued
868
+ *
869
+ * @throws {HypayError} When CCode indicates an error (920 = doesn't exist / already committed)
870
+ *
871
+ * @example
872
+ * ```ts
873
+ * const result = await client.cancelTransaction({ TransId: "5890796" });
874
+ * console.log(result.CCode); // "0" = success
875
+ * ```
876
+ */
877
+ async cancelTransaction(params) {
878
+ const allParams = {
879
+ action: "CancelTrans",
880
+ ...this.authParams(),
881
+ TransId: params.TransId
882
+ };
883
+ const { raw, params: parsed } = await this.request("CancelTrans", allParams);
884
+ if (parsed.CCode && parsed.CCode !== "0") {
885
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
886
+ }
887
+ return {
888
+ TransId: parsed.TransId ?? "",
889
+ CCode: parsed.CCode ?? "",
890
+ Hesh: parsed.Hesh,
891
+ raw,
892
+ params: parsed
893
+ };
894
+ }
895
+ // ═══════════════════════════════════════════════════════════════════════════
896
+ // REFUND — Refund transactions
897
+ // ═══════════════════════════════════════════════════════════════════════════
898
+ /**
899
+ * Refund a transaction by its original transaction ID (zikoyAPI).
900
+ *
901
+ * **Rules:**
902
+ * - Refund amount must not exceed the original transaction amount
903
+ * - Can be done at any stage, even after 23:00
904
+ * - A credit refund is like a new deal for the credit card company
905
+ * - Does NOT require a token or the secret refund password
906
+ *
907
+ * @throws {HypayError} When CCode indicates an error (33 = amount exceeds original)
908
+ *
909
+ * @example
910
+ * ```ts
911
+ * const result = await client.refund({
912
+ * TransId: "12290620",
913
+ * Amount: 10,
914
+ * Tash: 1,
915
+ * SendHesh: true,
916
+ * UTF8: true,
917
+ * UTF8out: true,
918
+ * });
919
+ * console.log(`Refund ID: ${result.Id}`);
920
+ * ```
921
+ */
922
+ async refund(params) {
923
+ const allParams = {
924
+ action: "zikoyAPI",
925
+ ...this.authParams(),
926
+ ...params
927
+ };
928
+ const { raw, params: parsed } = await this.request("zikoyAPI", allParams);
929
+ if (parsed.CCode && parsed.CCode !== "0") {
930
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
931
+ }
932
+ return {
933
+ Id: parsed.Id ?? "",
934
+ CCode: parsed.CCode ?? "",
935
+ ACode: parsed.ACode,
936
+ HeshASM: parsed.HeshASM,
937
+ raw,
938
+ params: parsed
939
+ };
940
+ }
941
+ /**
942
+ * Refund a transaction using a token and the secret refund password (PAYout).
943
+ *
944
+ * This uses the Soft protocol with the `zPass` parameter.
945
+ * The refund password is sent to the terminal owner's cell phone and is non-interchangeable.
946
+ *
947
+ * @throws {HypayError} When CCode indicates an error
948
+ *
949
+ * @example
950
+ * ```ts
951
+ * const result = await client.refundByToken({
952
+ * CC: "6907500685494032346",
953
+ * Tmonth: "04",
954
+ * Tyear: "2023",
955
+ * Amount: 2,
956
+ * Info: "Refund for order 123",
957
+ * zPass: "1234",
958
+ * Token: true,
959
+ * UserId: "000000000",
960
+ * ClientName: "Israel",
961
+ * SendHesh: true,
962
+ * sendemail: true,
963
+ * });
964
+ * ```
965
+ */
966
+ async refundByToken(params) {
967
+ return this.soft(params);
968
+ }
969
+ // ═══════════════════════════════════════════════════════════════════════════
970
+ // HK MODULE — Standing Orders / Subscriptions
971
+ // ═══════════════════════════════════════════════════════════════════════════
972
+ /**
973
+ * Create a subscription (HK / standing order) payment page URL.
974
+ *
975
+ * This is a convenience wrapper around `createPaymentPageUrl` with HK-specific params.
976
+ *
977
+ * @example
978
+ * ```ts
979
+ * const url = await client.createSubscriptionUrl({
980
+ * Info: "Monthly subscription",
981
+ * Amount: 120,
982
+ * HK: true,
983
+ * Tash: 999, // Unlimited payments
984
+ * freq: 1, // Monthly
985
+ * FirstDate: "2025-06-01",
986
+ * OnlyOnApprove: true,
987
+ * UserId: "203269535",
988
+ * ClientName: "Israel",
989
+ * email: "customer@example.com",
990
+ * Coin: Coin.ILS,
991
+ * UTF8: true,
992
+ * UTF8out: true,
993
+ * Sign: true,
994
+ * MoreData: true,
995
+ * });
996
+ * ```
997
+ */
998
+ async createSubscriptionUrl(params) {
999
+ return this.createPaymentPageUrl(params);
1000
+ }
1001
+ /**
1002
+ * Create a subscription with an initial transaction of a different amount.
1003
+ *
1004
+ * @example
1005
+ * ```ts
1006
+ * const url = await client.createSubscriptionWithInitialPayment({
1007
+ * Info: "Plan with setup fee",
1008
+ * Amount: 120, // Monthly amount
1009
+ * HK: true,
1010
+ * Tash: 999,
1011
+ * freq: 1,
1012
+ * TashFirstPayment: 50, // Setup fee
1013
+ * FirstPaymentTash: 3, // Charge setup fee for 3 months
1014
+ * FixTash: true,
1015
+ * OnlyOnApprove: true,
1016
+ * UserId: "203269535",
1017
+ * ClientName: "Israel",
1018
+ * Coin: Coin.ILS,
1019
+ * UTF8: true,
1020
+ * UTF8out: true,
1021
+ * Sign: true,
1022
+ * MoreData: true,
1023
+ * });
1024
+ * ```
1025
+ */
1026
+ async createSubscriptionWithInitialPayment(params) {
1027
+ return this.createPaymentPageUrl(params);
1028
+ }
1029
+ /**
1030
+ * Change the status of a standing order (HK) agreement.
1031
+ *
1032
+ * @throws {HypayError} When CCode indicates an error (905 = wrong param, 906 = not found)
1033
+ *
1034
+ * @example
1035
+ * ```ts
1036
+ * // Terminate
1037
+ * await client.updateHKStatus({
1038
+ * HKId: "64239",
1039
+ * NewStat: HKNewStatus.Terminate,
1040
+ * });
1041
+ *
1042
+ * // Reactivate
1043
+ * await client.updateHKStatus({
1044
+ * HKId: "64239",
1045
+ * NewStat: HKNewStatus.Activate,
1046
+ * });
1047
+ * ```
1048
+ */
1049
+ async updateHKStatus(params) {
1050
+ const allParams = {
1051
+ action: "HKStatus",
1052
+ ...this.authParams(),
1053
+ HKId: params.HKId,
1054
+ NewStat: params.NewStat
1055
+ };
1056
+ const { raw, params: parsed } = await this.request("HKStatus", allParams);
1057
+ if (parsed.CCode && parsed.CCode !== "0") {
1058
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
1059
+ }
1060
+ return {
1061
+ HKId: parsed.HKId ?? "",
1062
+ CCode: parsed.CCode ?? "",
1063
+ raw,
1064
+ params: parsed
1065
+ };
1066
+ }
1067
+ /**
1068
+ * Terminate a standing order agreement. Shorthand for `updateHKStatus`.
1069
+ */
1070
+ async terminateSubscription(hkId) {
1071
+ return this.updateHKStatus({ HKId: hkId, NewStat: 1 });
1072
+ }
1073
+ /**
1074
+ * Activate a standing order agreement. Shorthand for `updateHKStatus`.
1075
+ */
1076
+ async activateSubscription(hkId) {
1077
+ return this.updateHKStatus({ HKId: hkId, NewStat: 2 });
1078
+ }
1079
+ // ═══════════════════════════════════════════════════════════════════════════
1080
+ // EZCOUNT INVOICES — Print and manage invoices
1081
+ // ═══════════════════════════════════════════════════════════════════════════
1082
+ /**
1083
+ * Generate a signed URL for printing/viewing an EzCount invoice.
1084
+ *
1085
+ * Uses a two-step process:
1086
+ * 1. Sign the request with APISign (What=SIGN, ACTION=PrintHesh)
1087
+ * 2. Build the final URL from the signed response
1088
+ *
1089
+ * **Note:** `ACTION=PrintHesh` is uppercase, `action=APISign` is lowercase.
1090
+ *
1091
+ * @example
1092
+ * ```ts
1093
+ * const url = await client.getInvoiceUrl({
1094
+ * TransId: "55373520",
1095
+ * type: "EZCOUNT",
1096
+ * });
1097
+ * // Redirect user or fetch the invoice PDF
1098
+ * ```
1099
+ */
1100
+ async getInvoiceUrl(params) {
1101
+ const signParams = {
1102
+ action: "APISign",
1103
+ What: "SIGN",
1104
+ Masof: this.masof,
1105
+ KEY: this.apiKey,
1106
+ PassP: this.passP,
1107
+ ACTION: "PrintHesh",
1108
+ type: params.type
1109
+ };
1110
+ if (params.TransId) signParams.TransId = params.TransId;
1111
+ if (params.asm) signParams.asm = params.asm;
1112
+ if (params.HeshORCopy !== void 0) signParams.HeshORCopy = params.HeshORCopy;
1113
+ const { raw } = await this.request("PrintHesh-SIGN", signParams);
1114
+ return `${this.baseUrl}?${raw}`;
1115
+ }
1116
+ // ═══════════════════════════════════════════════════════════════════════════
1117
+ // OFFLINE INVOICES — Cash, Check, Multi
1118
+ // ═══════════════════════════════════════════════════════════════════════════
1119
+ /**
1120
+ * Create an invoice for an offline transaction (Cash, Check, or Multi-check).
1121
+ *
1122
+ * Uses the Soft protocol with the `TransType` parameter.
1123
+ *
1124
+ * @throws {HypayError} When CCode indicates an error
1125
+ *
1126
+ * @example
1127
+ * ```ts
1128
+ * // Cash invoice
1129
+ * const result = await client.createOfflineInvoice({
1130
+ * TransType: "Cash",
1131
+ * Info: "Cash payment",
1132
+ * Amount: 200,
1133
+ * UserId: "203269535",
1134
+ * ClientName: "Israel",
1135
+ * email: "customer@example.com",
1136
+ * Pritim: true,
1137
+ * heshDesc: "[001~Product A~2~50][002~Product B~1~100]",
1138
+ * SendHesh: true,
1139
+ * UTF8: true,
1140
+ * UTF8out: true,
1141
+ * });
1142
+ * ```
1143
+ *
1144
+ * @example
1145
+ * ```ts
1146
+ * // Check invoice
1147
+ * const result = await client.createOfflineInvoice({
1148
+ * TransType: "Check",
1149
+ * Info: "Check payment",
1150
+ * Amount: 200,
1151
+ * Bank: "10",
1152
+ * Snif: "912",
1153
+ * PAN: "1234456",
1154
+ * CheckNum: "11111111",
1155
+ * Date: "20250211",
1156
+ * UserId: "203269535",
1157
+ * ClientName: "Israel",
1158
+ * SendHesh: true,
1159
+ * UTF8: true,
1160
+ * UTF8out: true,
1161
+ * });
1162
+ * ```
1163
+ */
1164
+ async createOfflineInvoice(params) {
1165
+ const allParams = {
1166
+ action: "soft",
1167
+ ...this.authParams(),
1168
+ ...params
1169
+ };
1170
+ const { raw, params: parsed } = await this.request("soft-offline", allParams);
1171
+ if (parsed.CCode && !isSuccessCode(parsed.CCode)) {
1172
+ throw new HypayError(getErrorMessage(parsed.CCode), parsed.CCode, raw, parsed);
1173
+ }
1174
+ return {
1175
+ Id: parsed.Id ?? "",
1176
+ CCode: parsed.CCode ?? "",
1177
+ Amount: parsed.Amount ?? "",
1178
+ ACode: parsed.ACode ?? "",
1179
+ Fild1: parsed.Fild1,
1180
+ Fild2: parsed.Fild2,
1181
+ Fild3: parsed.Fild3,
1182
+ Hesh: parsed.Hesh,
1183
+ UID: parsed.UID,
1184
+ errMsg: parsed.errMsg,
1185
+ raw,
1186
+ params: parsed
1187
+ };
1188
+ }
1189
+ };
1190
+
1191
+ // src/index.ts
1192
+ init_helpers();
1193
+ // Annotate the CommonJS export names for ESM import in node:
1194
+ 0 && (module.exports = {
1195
+ ALL_ERROR_CODES,
1196
+ Bank,
1197
+ Brand,
1198
+ Coin,
1199
+ HKNewStatus,
1200
+ HYPAY_ERROR_CODES,
1201
+ HypayClient,
1202
+ HypayError,
1203
+ HypayNetworkError,
1204
+ HypayTimeoutError,
1205
+ Issuer,
1206
+ PageLang,
1207
+ SHVA_ERROR_CODES,
1208
+ SpecialCardType,
1209
+ TashType,
1210
+ buildItemsString,
1211
+ calculateItemsTotal,
1212
+ getErrorMessage,
1213
+ isHypayError,
1214
+ isShvaError,
1215
+ isSuccessCode,
1216
+ isTestMasof,
1217
+ isValidEmail,
1218
+ isValidIsraeliId,
1219
+ isValidMasof,
1220
+ isValidToken,
1221
+ parsePaymentPageResponse,
1222
+ parseQueryString,
1223
+ parseRedirectUrl,
1224
+ parseTokef,
1225
+ serializeParams,
1226
+ toQueryString
1227
+ });