@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/LICENSE +21 -0
- package/README.md +735 -0
- package/dist/chunk-LKIXYEBZ.mjs +103 -0
- package/dist/helpers-T6ONVODW.mjs +30 -0
- package/dist/index.d.mts +1363 -0
- package/dist/index.d.ts +1363 -0
- package/dist/index.js +1227 -0
- package/dist/index.mjs +1067 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
# @hypay/typescript-sdk
|
|
2
|
+
|
|
3
|
+
A fully typed, production-ready TypeScript SDK for the [Hyp Pay](https://pay.hyp.co.il/) payment gateway API (Israel).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Pay Protocol** — Generate signed payment page URLs with tamper-proof signatures
|
|
8
|
+
- **Signature Verification** — Verify transactions from success/failure redirect pages
|
|
9
|
+
- **Soft Protocol** — Server-side transactions with tokens, Apple Pay, and Google Pay
|
|
10
|
+
- **Token Management** — Obtain and reuse tokens for recurring charges (auto-parses Tokef)
|
|
11
|
+
- **J5 Transactions** — Reserve and later charge credit lines
|
|
12
|
+
- **Postpone Transactions** — Create delayed charges and commit them within 72 hours
|
|
13
|
+
- **Cancel & Refund** — Cancel same-day transactions or refund by transaction ID / token
|
|
14
|
+
- **Subscriptions (HK)** — Create standing orders with initial payments, terminate/activate
|
|
15
|
+
- **EzCount Invoices** — Generate signed invoice URLs, build item strings with validation
|
|
16
|
+
- **Offline Invoices** — Cash, Check, and Multi-check invoice creation
|
|
17
|
+
- **Error Handling** — Typed errors with full Hypay + Shva EMV error code mappings
|
|
18
|
+
- **Production Ready** — Timeouts, custom fetch, lifecycle hooks, Israeli ID validation
|
|
19
|
+
- **Tree-shakable** — ESM + CJS dual output, zero runtime dependencies
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @hypay/typescript-sdk
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Requirements:** Node.js >= 18 (uses native `fetch`)
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { HypayClient, Coin, PageLang } from "@hypay/typescript-sdk";
|
|
33
|
+
|
|
34
|
+
const client = new HypayClient({
|
|
35
|
+
masof: "0010131918", // Terminal number (10 digits)
|
|
36
|
+
apiKey: "your-api-key", // API key from Settings > Terminal Settings
|
|
37
|
+
passP: "your-password", // PassP from terminal settings
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Pay Protocol — Payment Page
|
|
44
|
+
|
|
45
|
+
### Step 1 + 2: Create a Signed Payment Page URL
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const url = await client.createPaymentPageUrl({
|
|
49
|
+
Info: "Order #12345",
|
|
50
|
+
Amount: 100,
|
|
51
|
+
UserId: "203269535",
|
|
52
|
+
ClientName: "Israel",
|
|
53
|
+
ClientLName: "Israeli",
|
|
54
|
+
email: "customer@example.com",
|
|
55
|
+
phone: "098610338",
|
|
56
|
+
cell: "0505555555",
|
|
57
|
+
street: "Levanon 3",
|
|
58
|
+
city: "Netanya",
|
|
59
|
+
zip: "42361",
|
|
60
|
+
Tash: 2,
|
|
61
|
+
Coin: Coin.ILS,
|
|
62
|
+
PageLang: PageLang.HEB,
|
|
63
|
+
tmp: 1,
|
|
64
|
+
MoreData: true,
|
|
65
|
+
Sign: true,
|
|
66
|
+
UTF8: true,
|
|
67
|
+
UTF8out: true,
|
|
68
|
+
sendemail: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Redirect the customer to `url`
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Step 1 only: Sign Parameters (for custom URL building)
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const result = await client.sign({
|
|
78
|
+
Info: "Order #123",
|
|
79
|
+
Amount: 100,
|
|
80
|
+
// ...
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
console.log(result.signature); // The signature hash
|
|
84
|
+
console.log(result.raw); // Full signed query string
|
|
85
|
+
|
|
86
|
+
// Build the URL yourself
|
|
87
|
+
const paymentUrl = client.buildPaymentPageUrl(result.raw);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Step 3: Handle Success Redirect
|
|
91
|
+
|
|
92
|
+
When the customer completes payment, they're redirected to your success page with transaction parameters in the URL.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { parsePaymentPageResponse } from "@hypay/typescript-sdk";
|
|
96
|
+
|
|
97
|
+
// In your success page handler:
|
|
98
|
+
const response = parsePaymentPageResponse(req.url);
|
|
99
|
+
console.log(response.Id); // Transaction ID
|
|
100
|
+
console.log(response.CCode); // "0" = success
|
|
101
|
+
console.log(response.Amount); // Amount charged
|
|
102
|
+
console.log(response.ACode); // Confirmation code
|
|
103
|
+
console.log(response.L4digit); // Last 4 digits (when MoreData=True)
|
|
104
|
+
console.log(response.Bank); // Acquirer (when MoreData=True)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Step 4: Verify Transaction Signature
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// Option A: Verify from parsed parameters
|
|
111
|
+
import { parseRedirectUrl } from "@hypay/typescript-sdk";
|
|
112
|
+
|
|
113
|
+
const params = parseRedirectUrl(req.url);
|
|
114
|
+
const result = await client.verify(params);
|
|
115
|
+
|
|
116
|
+
if (result.verified) {
|
|
117
|
+
// Transaction is legitimate — process the order
|
|
118
|
+
} else {
|
|
119
|
+
// CCode=902 — verification failed, do NOT process
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Option B: Verify directly from URL
|
|
123
|
+
const result = await client.verifyRedirectUrl(req.url);
|
|
124
|
+
if (result.verified) { /* OK */ }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Soft Protocol — Server-Side Transactions
|
|
130
|
+
|
|
131
|
+
### Token-Based Transaction
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
const result = await client.soft({
|
|
135
|
+
CC: "1315872608557940000", // Token (19 digits)
|
|
136
|
+
Tmonth: "04",
|
|
137
|
+
Tyear: "2025",
|
|
138
|
+
Amount: 50,
|
|
139
|
+
Info: "Subscription renewal",
|
|
140
|
+
UserId: "203269535",
|
|
141
|
+
ClientName: "Israel",
|
|
142
|
+
ClientLName: "Israeli",
|
|
143
|
+
email: "customer@example.com",
|
|
144
|
+
Coin: Coin.ILS,
|
|
145
|
+
Token: true,
|
|
146
|
+
MoreData: true,
|
|
147
|
+
UTF8: true,
|
|
148
|
+
UTF8out: true,
|
|
149
|
+
sendemail: true,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
console.log(result.Id); // Transaction ID
|
|
153
|
+
console.log(result.ACode); // Confirmation code
|
|
154
|
+
console.log(result.UID); // UID for J5 charge
|
|
155
|
+
// Access MoreData fields via result.params:
|
|
156
|
+
console.log(result.params.Bank); // Acquirer
|
|
157
|
+
console.log(result.params.Brand); // Card brand
|
|
158
|
+
console.log(result.params.L4digit); // Last 4 digits
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Apple Pay / Google Pay
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const result = await client.soft({
|
|
165
|
+
WalletToken: walletTokenJsonString, // From Apple Pay / Google Pay SDK
|
|
166
|
+
Amount: 100,
|
|
167
|
+
Info: "Purchase",
|
|
168
|
+
UserId: "203269535",
|
|
169
|
+
ClientName: "Israel",
|
|
170
|
+
Coin: Coin.ILS,
|
|
171
|
+
MoreData: true,
|
|
172
|
+
UTF8: true,
|
|
173
|
+
UTF8out: true,
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Token Management
|
|
180
|
+
|
|
181
|
+
### Get a Token
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const token = await client.getToken({
|
|
185
|
+
TransId: "12788261",
|
|
186
|
+
Fild1: "customer-123", // Your reference (not saved in Hypay)
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
console.log(token.Token); // "1315872608557940000" (19 digits)
|
|
190
|
+
console.log(token.Tokef); // "2504" (YYMM format)
|
|
191
|
+
console.log(token.Tmonth); // "04" (auto-parsed)
|
|
192
|
+
console.log(token.Tyear); // "2025" (auto-parsed)
|
|
193
|
+
|
|
194
|
+
// Save token.Token, token.Tmonth, token.Tyear, and customer details
|
|
195
|
+
// (Hypay does NOT store user info or card validity with the token)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Use Token in a Soft Transaction
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
await client.soft({
|
|
202
|
+
CC: token.Token,
|
|
203
|
+
Tmonth: token.Tmonth,
|
|
204
|
+
Tyear: token.Tyear,
|
|
205
|
+
Token: true,
|
|
206
|
+
Amount: 50,
|
|
207
|
+
Info: "Monthly charge",
|
|
208
|
+
UserId: savedUserId,
|
|
209
|
+
ClientName: savedName,
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Cross-Terminal Token Usage
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
await client.soft({
|
|
217
|
+
CC: token.Token,
|
|
218
|
+
Tmonth: token.Tmonth,
|
|
219
|
+
Tyear: token.Tyear,
|
|
220
|
+
Token: true,
|
|
221
|
+
tOwner: "0010020610", // Terminal that owns the token
|
|
222
|
+
Amount: 50,
|
|
223
|
+
Info: "Cross-terminal charge",
|
|
224
|
+
UserId: "203269535",
|
|
225
|
+
ClientName: "Israel",
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Manual Tokef Parsing
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { parseTokef } from "@hypay/typescript-sdk";
|
|
233
|
+
|
|
234
|
+
const { Tmonth, Tyear } = parseTokef("2504");
|
|
235
|
+
// Tmonth = "04", Tyear = "2025"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## J5 Transaction — Credit Line Reservation
|
|
241
|
+
|
|
242
|
+
### Reserve a Credit Line
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
const reservation = await client.soft({
|
|
246
|
+
CC: token.Token,
|
|
247
|
+
Tmonth: token.Tmonth,
|
|
248
|
+
Tyear: token.Tyear,
|
|
249
|
+
Token: true,
|
|
250
|
+
J5: true, // Reserve credit line
|
|
251
|
+
MoreData: true, // Required to get UID
|
|
252
|
+
Amount: 100,
|
|
253
|
+
Info: "Hotel reservation",
|
|
254
|
+
UserId: "203269535",
|
|
255
|
+
ClientName: "Israel",
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Save reservation.UID and reservation.ACode
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Charge the Reservation (amount <= original)
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
const charge = await client.chargeJ5(
|
|
265
|
+
{
|
|
266
|
+
CC: token.Token,
|
|
267
|
+
Tmonth: token.Tmonth,
|
|
268
|
+
Tyear: token.Tyear,
|
|
269
|
+
Token: true,
|
|
270
|
+
Amount: 80,
|
|
271
|
+
Info: "Hotel checkout",
|
|
272
|
+
UserId: "203269535",
|
|
273
|
+
ClientName: "Israel",
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"inputObj.originalUid": reservation.UID!,
|
|
277
|
+
"inputObj.originalAmount": 8000, // 80 ILS in agorot
|
|
278
|
+
AuthNum: reservation.ACode,
|
|
279
|
+
"inputObj.authorizationCodeManpik": 7,
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Postpone Transaction
|
|
287
|
+
|
|
288
|
+
### Create a Postponed Transaction
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
const postponed = await client.soft({
|
|
292
|
+
CC: token.Token,
|
|
293
|
+
Tmonth: token.Tmonth,
|
|
294
|
+
Tyear: token.Tyear,
|
|
295
|
+
Token: true,
|
|
296
|
+
Postpone: true,
|
|
297
|
+
Amount: 100,
|
|
298
|
+
Info: "Pending order verification",
|
|
299
|
+
UserId: "203269535",
|
|
300
|
+
ClientName: "Israel",
|
|
301
|
+
MoreData: true,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// postponed.CCode === "800" (valid postpone)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Commit Within 72 Hours
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
const result = await client.commitTransaction({
|
|
311
|
+
TransId: postponed.Id,
|
|
312
|
+
SendHesh: true,
|
|
313
|
+
heshDesc: "Payment for order 1234",
|
|
314
|
+
UTF8: true,
|
|
315
|
+
UTF8out: true,
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
console.log(result.HeshASM); // Invoice number created
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Cancel & Refund
|
|
324
|
+
|
|
325
|
+
### Cancel (Same Day, Before 23:20)
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
const result = await client.cancelTransaction({
|
|
329
|
+
TransId: "5890796",
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Refund by Transaction ID
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
const result = await client.refund({
|
|
337
|
+
TransId: "12290620",
|
|
338
|
+
Amount: 10,
|
|
339
|
+
Tash: 1,
|
|
340
|
+
SendHesh: true,
|
|
341
|
+
UTF8: true,
|
|
342
|
+
UTF8out: true,
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
console.log(result.Id); // New refund transaction ID
|
|
346
|
+
console.log(result.HeshASM); // Credit invoice number
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Refund by Token (PAYout)
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
const result = await client.refundByToken({
|
|
353
|
+
CC: "6907500685494032346",
|
|
354
|
+
Tmonth: "04",
|
|
355
|
+
Tyear: "2023",
|
|
356
|
+
Amount: 2,
|
|
357
|
+
Info: "Refund for order 123",
|
|
358
|
+
zPass: "1234", // Secret refund password (sent to terminal owner's phone)
|
|
359
|
+
Token: true,
|
|
360
|
+
UserId: "000000000",
|
|
361
|
+
ClientName: "Israel",
|
|
362
|
+
SendHesh: true,
|
|
363
|
+
sendemail: true,
|
|
364
|
+
UTF8: true,
|
|
365
|
+
UTF8out: true,
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Subscriptions (HK Module)
|
|
372
|
+
|
|
373
|
+
### Create a Subscription
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
const url = await client.createSubscriptionUrl({
|
|
377
|
+
Info: "Monthly subscription",
|
|
378
|
+
Amount: 120,
|
|
379
|
+
HK: true,
|
|
380
|
+
Tash: 999, // Unlimited payments
|
|
381
|
+
freq: 1, // Monthly
|
|
382
|
+
FirstDate: "2025-06-01",
|
|
383
|
+
OnlyOnApprove: true,
|
|
384
|
+
UserId: "203269535",
|
|
385
|
+
ClientName: "Israel",
|
|
386
|
+
email: "customer@example.com",
|
|
387
|
+
Coin: Coin.ILS,
|
|
388
|
+
UTF8: true,
|
|
389
|
+
UTF8out: true,
|
|
390
|
+
Sign: true,
|
|
391
|
+
MoreData: true,
|
|
392
|
+
sendemail: true,
|
|
393
|
+
SendHesh: true,
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// The success redirect URL will include HKId (agreement number)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Subscription with Initial Payment
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
const url = await client.createSubscriptionWithInitialPayment({
|
|
403
|
+
Info: "Plan with setup fee",
|
|
404
|
+
Amount: 120, // Monthly recurring amount
|
|
405
|
+
HK: true,
|
|
406
|
+
Tash: 999,
|
|
407
|
+
freq: 1,
|
|
408
|
+
TashFirstPayment: 50, // Setup fee amount
|
|
409
|
+
FirstPaymentTash: 3, // Charge setup fee for 3 months
|
|
410
|
+
FixTash: true,
|
|
411
|
+
OnlyOnApprove: true,
|
|
412
|
+
UserId: "203269535",
|
|
413
|
+
ClientName: "Israel",
|
|
414
|
+
Coin: Coin.ILS,
|
|
415
|
+
UTF8: true,
|
|
416
|
+
UTF8out: true,
|
|
417
|
+
Sign: true,
|
|
418
|
+
MoreData: true,
|
|
419
|
+
});
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Terminate / Activate an Agreement
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { HKNewStatus } from "@hypay/typescript-sdk";
|
|
426
|
+
|
|
427
|
+
// Terminate
|
|
428
|
+
await client.terminateSubscription("64239");
|
|
429
|
+
// or: await client.updateHKStatus({ HKId: "64239", NewStat: HKNewStatus.Terminate });
|
|
430
|
+
|
|
431
|
+
// Reactivate
|
|
432
|
+
await client.activateSubscription("64239");
|
|
433
|
+
// or: await client.updateHKStatus({ HKId: "64239", NewStat: HKNewStatus.Activate });
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## EzCount Invoices
|
|
439
|
+
|
|
440
|
+
### Build Invoice Items
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
import { buildItemsString, calculateItemsTotal } from "@hypay/typescript-sdk";
|
|
444
|
+
|
|
445
|
+
const items = [
|
|
446
|
+
{ code: "001", description: "Widget A", quantity: 2, price: 50 },
|
|
447
|
+
{ code: "002", description: "Widget B", quantity: 1, price: 100 },
|
|
448
|
+
];
|
|
449
|
+
|
|
450
|
+
const heshDesc = buildItemsString(items);
|
|
451
|
+
// "[001~Widget A~2~50][002~Widget B~1~100]"
|
|
452
|
+
|
|
453
|
+
const total = calculateItemsTotal(items);
|
|
454
|
+
// 200 (must match Amount parameter)
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Get a Signed Invoice URL
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
const invoiceUrl = await client.getInvoiceUrl({
|
|
461
|
+
TransId: "55373520",
|
|
462
|
+
type: "EZCOUNT",
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
// Or for old system:
|
|
466
|
+
const pdfUrl = await client.getInvoiceUrl({
|
|
467
|
+
TransId: "55373520",
|
|
468
|
+
type: "PDF",
|
|
469
|
+
HeshORCopy: true, // Authentic copy
|
|
470
|
+
});
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## Offline Invoices
|
|
476
|
+
|
|
477
|
+
### Cash Invoice
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
const result = await client.createOfflineInvoice({
|
|
481
|
+
TransType: "Cash",
|
|
482
|
+
Info: "Cash payment",
|
|
483
|
+
Amount: 200,
|
|
484
|
+
UserId: "203269535",
|
|
485
|
+
ClientName: "Israel",
|
|
486
|
+
email: "customer@example.com",
|
|
487
|
+
Pritim: true,
|
|
488
|
+
heshDesc: buildItemsString([
|
|
489
|
+
{ code: "001", description: "Product A", quantity: 2, price: 50 },
|
|
490
|
+
{ code: "002", description: "Product B", quantity: 1, price: 100 },
|
|
491
|
+
]),
|
|
492
|
+
SendHesh: true,
|
|
493
|
+
UTF8: true,
|
|
494
|
+
UTF8out: true,
|
|
495
|
+
});
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Check Invoice
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
const result = await client.createOfflineInvoice({
|
|
502
|
+
TransType: "Check",
|
|
503
|
+
Info: "Check payment",
|
|
504
|
+
Amount: 200,
|
|
505
|
+
Bank: "10",
|
|
506
|
+
Snif: "912",
|
|
507
|
+
PAN: "1234456",
|
|
508
|
+
CheckNum: "11111111",
|
|
509
|
+
Date: "20250211",
|
|
510
|
+
UserId: "203269535",
|
|
511
|
+
ClientName: "Israel",
|
|
512
|
+
SendHesh: true,
|
|
513
|
+
UTF8: true,
|
|
514
|
+
UTF8out: true,
|
|
515
|
+
});
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Multi-Check Invoice
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
const result = await client.createOfflineInvoice({
|
|
522
|
+
TransType: "Multi",
|
|
523
|
+
Info: "Multi-check payment",
|
|
524
|
+
Amount: 200, // Total
|
|
525
|
+
Bank: "10,12,11",
|
|
526
|
+
Snif: "912,826,921",
|
|
527
|
+
PAN: "1234456,1111111,222222",
|
|
528
|
+
CheckNum: "11111111,112223,3554568",
|
|
529
|
+
Date: "20250211,20250911,20251012",
|
|
530
|
+
UserId: "203269535",
|
|
531
|
+
ClientName: "Israel",
|
|
532
|
+
SendHesh: true,
|
|
533
|
+
UTF8: true,
|
|
534
|
+
UTF8out: true,
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Error Handling
|
|
541
|
+
|
|
542
|
+
### Typed Errors
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
import { HypayError, HypayNetworkError, HypayTimeoutError } from "@hypay/typescript-sdk";
|
|
546
|
+
|
|
547
|
+
try {
|
|
548
|
+
await client.soft({ /* ... */ });
|
|
549
|
+
} catch (error) {
|
|
550
|
+
if (error instanceof HypayError) {
|
|
551
|
+
console.error(`CCode: ${error.code}`); // e.g., "902"
|
|
552
|
+
console.error(`Message: ${error.message}`); // "Authentication error..."
|
|
553
|
+
console.error(`Raw: ${error.raw}`); // Full response string
|
|
554
|
+
console.error(`Params:`, error.params); // Parsed response
|
|
555
|
+
} else if (error instanceof HypayTimeoutError) {
|
|
556
|
+
console.error(`Timeout after ${error.timeoutMs}ms`);
|
|
557
|
+
} else if (error instanceof HypayNetworkError) {
|
|
558
|
+
console.error(`Network error: ${error.message}`);
|
|
559
|
+
console.error(`Cause:`, error.cause);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Error Code Utilities
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
import {
|
|
568
|
+
isSuccessCode,
|
|
569
|
+
isShvaError,
|
|
570
|
+
isHypayError,
|
|
571
|
+
getErrorMessage,
|
|
572
|
+
ALL_ERROR_CODES,
|
|
573
|
+
} from "@hypay/typescript-sdk";
|
|
574
|
+
|
|
575
|
+
isSuccessCode("0"); // true — Approved
|
|
576
|
+
isSuccessCode("800"); // true — Postponed (valid)
|
|
577
|
+
isSuccessCode("902"); // false — Authentication error
|
|
578
|
+
|
|
579
|
+
isShvaError("6"); // true — Incorrect CVV (Shva)
|
|
580
|
+
isHypayError("902"); // true — Authentication error (Hypay)
|
|
581
|
+
|
|
582
|
+
getErrorMessage("902"); // "Authentication error — reference differs from configured method"
|
|
583
|
+
getErrorMessage("6"); // "Incorrect ID or CVV"
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## Validation Helpers
|
|
589
|
+
|
|
590
|
+
```typescript
|
|
591
|
+
import {
|
|
592
|
+
isValidMasof,
|
|
593
|
+
isTestMasof,
|
|
594
|
+
isValidToken,
|
|
595
|
+
isValidEmail,
|
|
596
|
+
isValidIsraeliId,
|
|
597
|
+
} from "@hypay/typescript-sdk";
|
|
598
|
+
|
|
599
|
+
isValidMasof("0010131918"); // true (10 digits)
|
|
600
|
+
isTestMasof("0010131918"); // true (starts with 00100)
|
|
601
|
+
isTestMasof("1234567890"); // false
|
|
602
|
+
|
|
603
|
+
isValidToken("1315872608557940000"); // true (19 digits)
|
|
604
|
+
isValidEmail("test@example.com"); // true
|
|
605
|
+
|
|
606
|
+
isValidIsraeliId("203269535"); // true (valid Teudat Zehut)
|
|
607
|
+
isValidIsraeliId("000000000"); // true (special test value)
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
## Advanced Configuration
|
|
613
|
+
|
|
614
|
+
### Custom Timeout
|
|
615
|
+
|
|
616
|
+
```typescript
|
|
617
|
+
const client = new HypayClient({
|
|
618
|
+
masof: "0010131918",
|
|
619
|
+
apiKey: "your-key",
|
|
620
|
+
timeout: 60_000, // 60 seconds
|
|
621
|
+
});
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Custom Fetch (Node.js < 18 or test mocks)
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
import nodeFetch from "node-fetch";
|
|
628
|
+
|
|
629
|
+
const client = new HypayClient({
|
|
630
|
+
masof: "0010131918",
|
|
631
|
+
apiKey: "your-key",
|
|
632
|
+
fetch: nodeFetch as unknown as typeof fetch,
|
|
633
|
+
});
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
### Lifecycle Hooks (Logging, Metrics)
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
const client = new HypayClient({
|
|
640
|
+
masof: "0010131918",
|
|
641
|
+
apiKey: "your-key",
|
|
642
|
+
hooks: {
|
|
643
|
+
onRequest: (ctx) => {
|
|
644
|
+
console.log(`[Hypay] ${ctx.method} ${ctx.action}`, ctx.params);
|
|
645
|
+
},
|
|
646
|
+
onResponse: (ctx) => {
|
|
647
|
+
console.log(`[Hypay] ${ctx.action} responded in ${ctx.durationMs}ms`, {
|
|
648
|
+
status: ctx.statusCode,
|
|
649
|
+
CCode: ctx.parsedParams.CCode,
|
|
650
|
+
});
|
|
651
|
+
},
|
|
652
|
+
onError: (error, ctx) => {
|
|
653
|
+
console.error(`[Hypay] ${ctx.action} failed: ${error.code} — ${error.message}`);
|
|
654
|
+
// Send to your error tracking (Sentry, Datadog, etc.)
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
## Testing
|
|
663
|
+
|
|
664
|
+
Use a test terminal (Masof starting with `00100`) for development:
|
|
665
|
+
|
|
666
|
+
| Parameter | Test Value |
|
|
667
|
+
|-----------|-----------|
|
|
668
|
+
| Masof | `0010131918` |
|
|
669
|
+
| PassP | `yaad` |
|
|
670
|
+
| API Key | `7110eda4d09e062aa5e4a390b0a572ac0d2c0220` |
|
|
671
|
+
|
|
672
|
+
**Test Credit Card:**
|
|
673
|
+
|
|
674
|
+
| Field | Value |
|
|
675
|
+
|-------|-------|
|
|
676
|
+
| Number | `5326107300020772` |
|
|
677
|
+
| Expiry | `05/31` |
|
|
678
|
+
| CVV | `033` |
|
|
679
|
+
| ID | `890108558` or `000000000` |
|
|
680
|
+
|
|
681
|
+
Use low amounts (5-10 ILS) for testing. To simulate failures, use a real credit card on a test terminal.
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
685
|
+
## API Reference
|
|
686
|
+
|
|
687
|
+
### Client Methods
|
|
688
|
+
|
|
689
|
+
| Method | Description |
|
|
690
|
+
|--------|-------------|
|
|
691
|
+
| `sign(params)` | Sign payment page parameters (APISign) |
|
|
692
|
+
| `buildPaymentPageUrl(qs)` | Build payment page URL from signed query string |
|
|
693
|
+
| `createPaymentPageUrl(params)` | Sign + build URL in one call |
|
|
694
|
+
| `verify(params)` | Verify transaction from success page params |
|
|
695
|
+
| `verifyRedirectUrl(url)` | Parse URL + verify in one call |
|
|
696
|
+
| `soft(params)` | Server-side transaction (token, wallet, card) |
|
|
697
|
+
| `getToken(params)` | Get reusable token from a transaction |
|
|
698
|
+
| `chargeJ5(tokenParams, j5Params)` | Charge a J5 credit line reservation |
|
|
699
|
+
| `commitTransaction(params)` | Commit a postponed (800) transaction |
|
|
700
|
+
| `cancelTransaction(params)` | Cancel a same-day transaction |
|
|
701
|
+
| `refund(params)` | Refund by transaction ID (zikoyAPI) |
|
|
702
|
+
| `refundByToken(params)` | Refund via token + zPass (PAYout) |
|
|
703
|
+
| `createSubscriptionUrl(params)` | Create HK subscription payment page |
|
|
704
|
+
| `createSubscriptionWithInitialPayment(params)` | Subscription with setup fee |
|
|
705
|
+
| `updateHKStatus(params)` | Change standing order status |
|
|
706
|
+
| `terminateSubscription(hkId)` | Terminate a standing order |
|
|
707
|
+
| `activateSubscription(hkId)` | Activate a standing order |
|
|
708
|
+
| `getInvoiceUrl(params)` | Get signed EzCount invoice URL |
|
|
709
|
+
| `createOfflineInvoice(params)` | Create Cash/Check/Multi invoice |
|
|
710
|
+
|
|
711
|
+
### Helper Functions
|
|
712
|
+
|
|
713
|
+
| Function | Description |
|
|
714
|
+
|----------|-------------|
|
|
715
|
+
| `parseQueryString(qs)` | Parse URL query string to Record |
|
|
716
|
+
| `parseRedirectUrl(url)` | Parse success/failure redirect URL |
|
|
717
|
+
| `parsePaymentPageResponse(url)` | Parse redirect URL to typed response |
|
|
718
|
+
| `parseTokef(tokef)` | Parse YYMM token expiry to Tmonth/Tyear |
|
|
719
|
+
| `buildItemsString(items)` | Build heshDesc invoice items string |
|
|
720
|
+
| `calculateItemsTotal(items)` | Calculate total from invoice items |
|
|
721
|
+
| `isValidMasof(masof)` | Validate terminal number format |
|
|
722
|
+
| `isTestMasof(masof)` | Check if terminal is a test terminal |
|
|
723
|
+
| `isValidToken(token)` | Validate 19-digit token format |
|
|
724
|
+
| `isValidEmail(email)` | Basic email validation |
|
|
725
|
+
| `isValidIsraeliId(id)` | Validate Israeli ID (Teudat Zehut) |
|
|
726
|
+
| `isSuccessCode(ccode)` | Check if CCode is success (0/600/700/800) |
|
|
727
|
+
| `isShvaError(ccode)` | Check if CCode is Shva error (1-200) |
|
|
728
|
+
| `isHypayError(ccode)` | Check if CCode is Hypay error (201-999) |
|
|
729
|
+
| `getErrorMessage(ccode)` | Get human-readable error description |
|
|
730
|
+
|
|
731
|
+
---
|
|
732
|
+
|
|
733
|
+
## License
|
|
734
|
+
|
|
735
|
+
MIT
|