eps-gateway-nodejs 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 +620 -0
- package/dist/EPS.d.ts +17 -0
- package/dist/EPS.js +210 -0
- package/dist/EPS.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +117 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.js +68 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/validator.d.ts +3 -0
- package/dist/utils/validator.js +86 -0
- package/dist/utils/validator.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 EPS Gateway Node.js Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
# EPS Gateway Node.js SDK
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/eps-gateway-nodejs)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
A well-maintained, unofficial Node.js package for integrating EPS (Easy Payment System) payments. Provides reliable support for initiating and handling transactions with minimal setup.
|
|
8
|
+
|
|
9
|
+
**Official EPS Website:** [https://www.eps.com.bd](https://www.eps.com.bd)
|
|
10
|
+
|
|
11
|
+
> **Note:** This is an unofficial SDK created by the developer community. EPS does not provide an official Node.js SDK.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
✅ **TypeScript Support** - Full TypeScript definitions included
|
|
16
|
+
✅ **Promise-based API** - Modern async/await syntax
|
|
17
|
+
✅ **Automatic Token Management** - Handles JWT token caching and renewal
|
|
18
|
+
✅ **HMACSHA512 Hash Generation** - Built-in secure hash utility
|
|
19
|
+
✅ **Sandbox & Production** - Easy environment switching
|
|
20
|
+
✅ **Input Validation** - Validates all parameters before API calls
|
|
21
|
+
✅ **Error Handling** - Comprehensive error messages
|
|
22
|
+
✅ **Product List Support** - Multiple products in single transaction
|
|
23
|
+
✅ **Zero Dependencies** - Only uses axios for HTTP requests
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install eps-gateway-nodejs
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
or
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
yarn add eps-gateway-nodejs
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
const { EPS, generateTransactionId } = require('eps-gateway-nodejs');
|
|
41
|
+
|
|
42
|
+
// Initialize EPS
|
|
43
|
+
const eps = new EPS({
|
|
44
|
+
username: 'your_username@example.com',
|
|
45
|
+
password: 'your_password',
|
|
46
|
+
hashKey: 'your_hash_key',
|
|
47
|
+
merchantId: 'your-merchant-id',
|
|
48
|
+
storeId: 'your-store-id',
|
|
49
|
+
sandbox: true // Use sandbox for testing
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Initialize payment
|
|
53
|
+
const payment = await eps.initializePayment({
|
|
54
|
+
customerOrderId: 'ORD123',
|
|
55
|
+
merchantTransactionId: generateTransactionId(),
|
|
56
|
+
totalAmount: 1000,
|
|
57
|
+
|
|
58
|
+
successUrl: 'https://yoursite.com/payment/success',
|
|
59
|
+
failUrl: 'https://yoursite.com/payment/fail',
|
|
60
|
+
cancelUrl: 'https://yoursite.com/payment/cancel',
|
|
61
|
+
|
|
62
|
+
customerName: 'John Doe',
|
|
63
|
+
customerEmail: 'john@example.com',
|
|
64
|
+
customerPhone: '01712345678',
|
|
65
|
+
customerAddress: 'Dhaka',
|
|
66
|
+
customerCity: 'Dhaka',
|
|
67
|
+
customerState: 'Dhaka',
|
|
68
|
+
customerPostcode: '1200',
|
|
69
|
+
|
|
70
|
+
productName: 'Test Product'
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Redirect user to payment page
|
|
74
|
+
console.log('Redirect to:', payment.RedirectURL);
|
|
75
|
+
|
|
76
|
+
// Verify payment (after callback)
|
|
77
|
+
const verification = await eps.verifyPayment({
|
|
78
|
+
merchantTransactionId: 'your_transaction_id'
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (verification.Status === 'Success') {
|
|
82
|
+
console.log('Payment successful!');
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
### Required Parameters
|
|
89
|
+
|
|
90
|
+
| Parameter | Type | Description |
|
|
91
|
+
|-----------|------|-------------|
|
|
92
|
+
| `username` | string | EPS merchant username (usually email) |
|
|
93
|
+
| `password` | string | EPS merchant password |
|
|
94
|
+
| `hashKey` | string | Hash key provided by EPS (base64 encoded) |
|
|
95
|
+
| `merchantId` | string | Merchant ID (UUID format) |
|
|
96
|
+
| `storeId` | string | Store ID (UUID format) |
|
|
97
|
+
|
|
98
|
+
### Optional Parameters
|
|
99
|
+
|
|
100
|
+
| Parameter | Type | Default | Description |
|
|
101
|
+
|-----------|------|---------|-------------|
|
|
102
|
+
| `sandbox` | boolean | `false` | Use sandbox environment for testing |
|
|
103
|
+
| `timeout` | number | `30000` | Request timeout in milliseconds |
|
|
104
|
+
|
|
105
|
+
### Environment Variables Example
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
EPS_USERNAME=merchant@example.com
|
|
109
|
+
EPS_PASSWORD=your_password
|
|
110
|
+
EPS_HASH_KEY=your_hash_key_base64
|
|
111
|
+
EPS_MERCHANT_ID=094980ee-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
112
|
+
EPS_STORE_ID=35b518f6-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
113
|
+
EPS_SANDBOX=true
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
const eps = new EPS({
|
|
118
|
+
username: process.env.EPS_USERNAME,
|
|
119
|
+
password: process.env.EPS_PASSWORD,
|
|
120
|
+
hashKey: process.env.EPS_HASH_KEY,
|
|
121
|
+
merchantId: process.env.EPS_MERCHANT_ID,
|
|
122
|
+
storeId: process.env.EPS_STORE_ID,
|
|
123
|
+
sandbox: process.env.EPS_SANDBOX === 'true'
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## API Reference
|
|
128
|
+
|
|
129
|
+
### Initialize Payment
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
const payment = await eps.initializePayment(params);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Required Parameters
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
{
|
|
139
|
+
// Order Information
|
|
140
|
+
customerOrderId: 'ORD123', // Your unique order ID
|
|
141
|
+
merchantTransactionId: '20240117001', // Unique transaction ID (min 10 digits)
|
|
142
|
+
totalAmount: 1000, // Amount in BDT
|
|
143
|
+
|
|
144
|
+
// Callback URLs
|
|
145
|
+
successUrl: 'https://yoursite.com/success',
|
|
146
|
+
failUrl: 'https://yoursite.com/fail',
|
|
147
|
+
cancelUrl: 'https://yoursite.com/cancel',
|
|
148
|
+
|
|
149
|
+
// Customer Information
|
|
150
|
+
customerName: 'John Doe',
|
|
151
|
+
customerEmail: 'john@example.com',
|
|
152
|
+
customerPhone: '01712345678', // Bangladesh format: 01XXXXXXXXX
|
|
153
|
+
customerAddress: 'House 123, Road 456',
|
|
154
|
+
customerCity: 'Dhaka',
|
|
155
|
+
customerState: 'Dhaka',
|
|
156
|
+
customerPostcode: '1200',
|
|
157
|
+
|
|
158
|
+
// Product Information
|
|
159
|
+
productName: 'Test Product'
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Optional Parameters
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
{
|
|
167
|
+
// Transaction Type
|
|
168
|
+
transactionTypeId: TransactionType.WEB, // WEB=1, ANDROID=2, IOS=3
|
|
169
|
+
|
|
170
|
+
// Additional Customer Info
|
|
171
|
+
customerAddress2: 'Sector 7, Uttara',
|
|
172
|
+
customerCountry: 'BD',
|
|
173
|
+
|
|
174
|
+
// Shipping Information
|
|
175
|
+
shipmentName: 'John Doe',
|
|
176
|
+
shipmentAddress: 'House 123',
|
|
177
|
+
shipmentCity: 'Dhaka',
|
|
178
|
+
shipmentState: 'Dhaka',
|
|
179
|
+
shipmentPostcode: '1200',
|
|
180
|
+
shipmentCountry: 'BD',
|
|
181
|
+
|
|
182
|
+
// Product Details
|
|
183
|
+
productProfile: 'general',
|
|
184
|
+
productCategory: 'Electronics',
|
|
185
|
+
noOfItem: 1,
|
|
186
|
+
|
|
187
|
+
// Multiple Products
|
|
188
|
+
productList: [
|
|
189
|
+
{
|
|
190
|
+
ProductName: 'Product 1',
|
|
191
|
+
NoOfItem: 2,
|
|
192
|
+
ProductPrice: 500,
|
|
193
|
+
ProductProfile: 'Description',
|
|
194
|
+
ProductCategory: 'Category'
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
|
|
198
|
+
// Custom Values (for your reference)
|
|
199
|
+
valueA: 'custom_data_1',
|
|
200
|
+
valueB: 'custom_data_2',
|
|
201
|
+
valueC: 'custom_data_3',
|
|
202
|
+
valueD: 'custom_data_4',
|
|
203
|
+
|
|
204
|
+
// Other
|
|
205
|
+
shippingMethod: 'NO',
|
|
206
|
+
ipAddress: '103.45.67.89'
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### Response
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
{
|
|
214
|
+
TransactionId: '23e02880-f378-4594-86f8-30ecb5998094',
|
|
215
|
+
RedirectURL: 'https://pg.eps.com.bd/PG?data=...',
|
|
216
|
+
ErrorMessage: '',
|
|
217
|
+
ErrorCode: null
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Verify Payment
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
// Method 1: Verify by merchant transaction ID
|
|
225
|
+
const result = await eps.verifyPayment({
|
|
226
|
+
merchantTransactionId: '20240117001'
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Method 2: Verify by EPS transaction ID
|
|
230
|
+
const result = await eps.verifyPayment({
|
|
231
|
+
epsTransactionId: 'C2549190401'
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Method 3: Quick status check
|
|
235
|
+
const isSuccessful = await eps.isPaymentSuccessful('20240117001');
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### Response
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
{
|
|
242
|
+
MerchantTransactionId: '20240117001',
|
|
243
|
+
EpsTransactionId: 'C2549190401',
|
|
244
|
+
Status: 'Success', // Success, Failed, Pending
|
|
245
|
+
TotalAmount: '1000.00',
|
|
246
|
+
TransactionDate: '17 Jan 2024 06:30:15 PM',
|
|
247
|
+
TransactionType: 'Purchase',
|
|
248
|
+
FinancialEntity: 'OKWallet', // Payment method used
|
|
249
|
+
|
|
250
|
+
// Customer details
|
|
251
|
+
CustomerName: 'John Doe',
|
|
252
|
+
CustomerEmail: 'john@example.com',
|
|
253
|
+
CustomerPhone: '01712345678',
|
|
254
|
+
|
|
255
|
+
// Error info (if any)
|
|
256
|
+
ErrorCode: '',
|
|
257
|
+
ErrorMessage: ''
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Payment Flow
|
|
262
|
+
|
|
263
|
+
### 1. Initialize Payment
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
const payment = await eps.initializePayment({...});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### 2. Redirect User
|
|
270
|
+
|
|
271
|
+
```javascript
|
|
272
|
+
// Redirect user to EPS payment page
|
|
273
|
+
res.redirect(payment.RedirectURL);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 3. Handle Callbacks
|
|
277
|
+
|
|
278
|
+
EPS will redirect users back to your URLs with transaction details:
|
|
279
|
+
|
|
280
|
+
#### Success URL
|
|
281
|
+
```
|
|
282
|
+
https://yoursite.com/payment/success?merchantTransactionId=xxx&status=success
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Fail URL
|
|
286
|
+
```
|
|
287
|
+
https://yoursite.com/payment/fail?merchantTransactionId=xxx&status=failed
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### Cancel URL
|
|
291
|
+
```
|
|
292
|
+
https://yoursite.com/payment/cancel?merchantTransactionId=xxx&status=cancelled
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 4. Verify Payment
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
router.get('/payment/success', async (req, res) => {
|
|
299
|
+
const { merchantTransactionId } = req.query;
|
|
300
|
+
|
|
301
|
+
// ALWAYS verify with EPS
|
|
302
|
+
const verification = await eps.verifyPayment({ merchantTransactionId });
|
|
303
|
+
|
|
304
|
+
if (verification.Status === 'Success') {
|
|
305
|
+
// Payment confirmed - Update your database
|
|
306
|
+
await updateOrderStatus(merchantTransactionId, 'PAID');
|
|
307
|
+
res.render('success', { transaction: verification });
|
|
308
|
+
} else {
|
|
309
|
+
res.redirect('/payment/fail');
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Express.js Integration
|
|
315
|
+
|
|
316
|
+
```javascript
|
|
317
|
+
const express = require('express');
|
|
318
|
+
const { EPS, generateTransactionId } = require('eps-gateway-nodejs');
|
|
319
|
+
|
|
320
|
+
const app = express();
|
|
321
|
+
const eps = new EPS({...});
|
|
322
|
+
|
|
323
|
+
// Initiate payment
|
|
324
|
+
app.post('/payment/initiate', async (req, res) => {
|
|
325
|
+
try {
|
|
326
|
+
const payment = await eps.initializePayment({
|
|
327
|
+
customerOrderId: req.body.orderId,
|
|
328
|
+
merchantTransactionId: generateTransactionId(),
|
|
329
|
+
totalAmount: req.body.amount,
|
|
330
|
+
successUrl: `${req.protocol}://${req.get('host')}/payment/success`,
|
|
331
|
+
failUrl: `${req.protocol}://${req.get('host')}/payment/fail`,
|
|
332
|
+
cancelUrl: `${req.protocol}://${req.get('host')}/payment/cancel`,
|
|
333
|
+
...req.body.customer,
|
|
334
|
+
productName: req.body.productName
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
res.redirect(payment.RedirectURL);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
res.status(500).json({ error: error.message });
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// Success callback
|
|
344
|
+
app.get('/payment/success', async (req, res) => {
|
|
345
|
+
const verification = await eps.verifyPayment({
|
|
346
|
+
merchantTransactionId: req.query.merchantTransactionId
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
if (verification.Status === 'Success') {
|
|
350
|
+
// Update database, send email, etc.
|
|
351
|
+
res.render('payment-success', { data: verification });
|
|
352
|
+
} else {
|
|
353
|
+
res.redirect('/payment/fail');
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Utility Functions
|
|
359
|
+
|
|
360
|
+
### Generate Transaction ID
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
const { generateTransactionId } = require('eps-gateway-nodejs');
|
|
364
|
+
|
|
365
|
+
const txnId = generateTransactionId();
|
|
366
|
+
// Returns: 20240117123456789 (17 digits, timestamp-based)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Generate Hash (Advanced)
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
const { generateHash } = require('eps-gateway-nodejs');
|
|
373
|
+
|
|
374
|
+
const hash = generateHash('value_to_hash', 'your_hash_key');
|
|
375
|
+
// Returns: Base64 HMACSHA512 hash
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Error Handling
|
|
379
|
+
|
|
380
|
+
```javascript
|
|
381
|
+
const { EPSError } = require('eps-gateway-nodejs');
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const payment = await eps.initializePayment({...});
|
|
385
|
+
} catch (error) {
|
|
386
|
+
if (error instanceof EPSError) {
|
|
387
|
+
console.error('EPS Error:', error.message);
|
|
388
|
+
console.error('Error Code:', error.code);
|
|
389
|
+
console.error('Response:', error.response);
|
|
390
|
+
} else {
|
|
391
|
+
console.error('Unknown error:', error);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Common Error Codes
|
|
397
|
+
|
|
398
|
+
| Code | Description |
|
|
399
|
+
|------|-------------|
|
|
400
|
+
| `INVALID_CONFIG` | Invalid configuration parameters |
|
|
401
|
+
| `INVALID_PARAMS` | Invalid payment parameters |
|
|
402
|
+
| `AUTH_ERROR` | Authentication failed |
|
|
403
|
+
| `INIT_ERROR` | Payment initialization failed |
|
|
404
|
+
| `VERIFY_ERROR` | Transaction verification failed |
|
|
405
|
+
| `NETWORK_ERROR` | Network/connection error |
|
|
406
|
+
|
|
407
|
+
## TypeScript Usage
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { EPS, InitializePaymentParams, VerifyPaymentResponse, TransactionType } from 'eps-gateway-nodejs';
|
|
411
|
+
|
|
412
|
+
const eps = new EPS({
|
|
413
|
+
username: 'merchant@example.com',
|
|
414
|
+
password: 'password',
|
|
415
|
+
hashKey: 'hash_key',
|
|
416
|
+
merchantId: 'merchant-id',
|
|
417
|
+
storeId: 'store-id',
|
|
418
|
+
sandbox: true
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const params: InitializePaymentParams = {
|
|
422
|
+
customerOrderId: 'ORD123',
|
|
423
|
+
merchantTransactionId: '20240117001',
|
|
424
|
+
totalAmount: 1000,
|
|
425
|
+
transactionTypeId: TransactionType.WEB,
|
|
426
|
+
// ... other params
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const payment = await eps.initializePayment(params);
|
|
430
|
+
const verification: VerifyPaymentResponse = await eps.verifyPayment({
|
|
431
|
+
merchantTransactionId: '20240117001'
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## Testing
|
|
436
|
+
|
|
437
|
+
### Sandbox Mode
|
|
438
|
+
|
|
439
|
+
```javascript
|
|
440
|
+
const eps = new EPS({
|
|
441
|
+
username: 'sandbox_username',
|
|
442
|
+
password: 'sandbox_password',
|
|
443
|
+
hashKey: 'sandbox_hash_key',
|
|
444
|
+
merchantId: 'sandbox-merchant-id',
|
|
445
|
+
storeId: 'sandbox-store-id',
|
|
446
|
+
sandbox: true // Important!
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Test Credentials
|
|
451
|
+
|
|
452
|
+
Contact EPS support to get sandbox credentials for testing.
|
|
453
|
+
|
|
454
|
+
## Examples
|
|
455
|
+
|
|
456
|
+
Check the `/examples` directory for complete working examples:
|
|
457
|
+
|
|
458
|
+
- `initialize-payment.js` - Basic payment initialization
|
|
459
|
+
- `verify-payment.js` - Payment verification
|
|
460
|
+
- `complete-flow.js` - Complete payment flow with Express.js integration
|
|
461
|
+
|
|
462
|
+
Run examples:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
npm run build
|
|
466
|
+
node examples/initialize-payment.js
|
|
467
|
+
node examples/verify-payment.js
|
|
468
|
+
node examples/complete-flow.js
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
## Best Practices
|
|
472
|
+
|
|
473
|
+
### 1. Always Verify Payments
|
|
474
|
+
|
|
475
|
+
Never trust callback URLs alone. Always verify payment status with EPS:
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
// ❌ BAD - Don't trust the callback alone
|
|
479
|
+
app.get('/payment/success', async (req, res) => {
|
|
480
|
+
// Directly mark as paid - INSECURE!
|
|
481
|
+
await markOrderAsPaid(req.query.orderId);
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// ✅ GOOD - Always verify with EPS
|
|
485
|
+
app.get('/payment/success', async (req, res) => {
|
|
486
|
+
const verification = await eps.verifyPayment({
|
|
487
|
+
merchantTransactionId: req.query.merchantTransactionId
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
if (verification.Status === 'Success') {
|
|
491
|
+
await markOrderAsPaid(req.query.orderId);
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### 2. Store Transaction IDs
|
|
497
|
+
|
|
498
|
+
```javascript
|
|
499
|
+
// Save transaction details before redirecting
|
|
500
|
+
await Payment.create({
|
|
501
|
+
orderId: 'ORD123',
|
|
502
|
+
merchantTransactionId: txnId,
|
|
503
|
+
epsTransactionId: payment.TransactionId,
|
|
504
|
+
amount: 1000,
|
|
505
|
+
status: 'INITIATED'
|
|
506
|
+
});
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### 3. Use Environment Variables
|
|
510
|
+
|
|
511
|
+
```javascript
|
|
512
|
+
// Never hardcode credentials
|
|
513
|
+
const eps = new EPS({
|
|
514
|
+
username: process.env.EPS_USERNAME,
|
|
515
|
+
password: process.env.EPS_PASSWORD,
|
|
516
|
+
hashKey: process.env.EPS_HASH_KEY,
|
|
517
|
+
merchantId: process.env.EPS_MERCHANT_ID,
|
|
518
|
+
storeId: process.env.EPS_STORE_ID,
|
|
519
|
+
sandbox: process.env.NODE_ENV !== 'production'
|
|
520
|
+
});
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### 4. Handle Errors Gracefully
|
|
524
|
+
|
|
525
|
+
```javascript
|
|
526
|
+
try {
|
|
527
|
+
const payment = await eps.initializePayment(params);
|
|
528
|
+
res.redirect(payment.RedirectURL);
|
|
529
|
+
} catch (error) {
|
|
530
|
+
logger.error('Payment initiation failed:', error);
|
|
531
|
+
res.render('payment-error', {
|
|
532
|
+
message: 'Unable to process payment. Please try again.'
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 5. Use Unique Transaction IDs
|
|
538
|
+
|
|
539
|
+
```javascript
|
|
540
|
+
const { generateTransactionId } = require('eps-gateway-nodejs');
|
|
541
|
+
|
|
542
|
+
// Always generate unique transaction IDs
|
|
543
|
+
const txnId = generateTransactionId(); // Timestamp-based, 17 digits
|
|
544
|
+
|
|
545
|
+
// Or use your own format (minimum 10 digits)
|
|
546
|
+
const customTxnId = `${Date.now()}${Math.random().toString().slice(2, 6)}`;
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
## FAQ
|
|
550
|
+
|
|
551
|
+
### Q: Is this an official SDK?
|
|
552
|
+
**A:** No, this is an unofficial SDK created by the developer community. EPS does not provide an official Node.js SDK.
|
|
553
|
+
|
|
554
|
+
### Q: How do I get EPS credentials?
|
|
555
|
+
**A:** Contact EPS (Easy Payment System) support at info@eps.com.bd or visit www.eps.com.bd
|
|
556
|
+
|
|
557
|
+
### Q: What's the difference between sandbox and production?
|
|
558
|
+
**A:** Sandbox is for testing with test credentials. Production is for real transactions with real money.
|
|
559
|
+
|
|
560
|
+
### Q: Can I use this in production?
|
|
561
|
+
**A:** Yes, but thoroughly test in sandbox mode first. This library is used in production by several projects.
|
|
562
|
+
|
|
563
|
+
### Q: What payment methods does EPS support?
|
|
564
|
+
**A:** EPS supports various methods including bKash, Nagad, Rocket, Bank cards, OKWallet, and more. The actual methods available depend on your EPS merchant account configuration.
|
|
565
|
+
|
|
566
|
+
### Q: How do I handle webhooks/IPN?
|
|
567
|
+
**A:** EPS uses callback URLs (successUrl, failUrl, cancelUrl). Always verify payment status when handling these callbacks.
|
|
568
|
+
|
|
569
|
+
## Contributing
|
|
570
|
+
|
|
571
|
+
Suggestions, improvements, and pull requests are always welcome!
|
|
572
|
+
|
|
573
|
+
1. Fork the repository
|
|
574
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
575
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
576
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
577
|
+
5. Open a Pull Request
|
|
578
|
+
|
|
579
|
+
### Development Setup
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
git clone https://github.com/imtiaznajim/eps-gateway-nodejs.git
|
|
583
|
+
cd eps-gateway-nodejs
|
|
584
|
+
npm install
|
|
585
|
+
npm run build
|
|
586
|
+
npm test
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## License
|
|
590
|
+
|
|
591
|
+
MIT License - see the [LICENSE](LICENSE) file for details
|
|
592
|
+
|
|
593
|
+
## Disclaimer
|
|
594
|
+
|
|
595
|
+
This is an unofficial SDK. The author is not affiliated with EPS (Easy Payment System). Use at your own risk.
|
|
596
|
+
|
|
597
|
+
## Author
|
|
598
|
+
|
|
599
|
+
**Imtiaz Najim**
|
|
600
|
+
- GitHub: [@imtiaznajim](https://github.com/imtiaznajim)
|
|
601
|
+
- Email: imtiaznajim@gmail.com
|
|
602
|
+
|
|
603
|
+
## Support
|
|
604
|
+
|
|
605
|
+
- 🐛 **Issues:** [GitHub Issues](https://github.com/imtiaznajim/eps-gateway-nodejs/issues)
|
|
606
|
+
- 💬 **Discussions:** [GitHub Discussions](https://github.com/imtiaznajim/eps-gateway-nodejs/discussions)
|
|
607
|
+
- ⭐ **Star this repo** if you find it helpful!
|
|
608
|
+
|
|
609
|
+
## Acknowledgments
|
|
610
|
+
|
|
611
|
+
- Thanks to [EPS (Easy Payment System)](https://www.eps.com.bd) for providing the payment gateway service
|
|
612
|
+
- Built with ❤️ for the Bangladesh developer community
|
|
613
|
+
|
|
614
|
+
## Related Projects
|
|
615
|
+
|
|
616
|
+
- [bkash-payment](https://www.npmjs.com/package/bkash-payment) - bKash Payment Gateway SDK
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
Made with ❤️ for the Bangladesh developer community
|
package/dist/EPS.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EPSConfig, InitializePaymentParams, InitializePaymentResponse, VerifyPaymentParams, VerifyPaymentResponse } from './types';
|
|
2
|
+
export declare class EPS {
|
|
3
|
+
private config;
|
|
4
|
+
private httpClient;
|
|
5
|
+
private token;
|
|
6
|
+
private tokenExpiry;
|
|
7
|
+
private readonly ENDPOINTS;
|
|
8
|
+
constructor(config: EPSConfig);
|
|
9
|
+
private getEndpoints;
|
|
10
|
+
private getToken;
|
|
11
|
+
initializePayment(params: InitializePaymentParams): Promise<InitializePaymentResponse>;
|
|
12
|
+
verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResponse>;
|
|
13
|
+
isPaymentSuccessful(transactionId: string): Promise<boolean>;
|
|
14
|
+
private handleError;
|
|
15
|
+
clearToken(): void;
|
|
16
|
+
getConfig(): Partial<EPSConfig>;
|
|
17
|
+
}
|
package/dist/EPS.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EPS = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
const hash_1 = require("./utils/hash");
|
|
10
|
+
const validator_1 = require("./utils/validator");
|
|
11
|
+
class EPS {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.token = null;
|
|
14
|
+
this.tokenExpiry = null;
|
|
15
|
+
this.ENDPOINTS = {
|
|
16
|
+
SANDBOX: {
|
|
17
|
+
GET_TOKEN: 'https://sandbox-pgapi.eps.com.bd/v1/Auth/GetToken',
|
|
18
|
+
INITIALIZE: 'https://sandbox-pgapi.eps.com.bd/v1/EPSEngine/InitializeEPS',
|
|
19
|
+
VERIFY: 'https://sandbox-pgapi.eps.com.bd/v1/EPSEngine/CheckMerchantTransactionStatus',
|
|
20
|
+
},
|
|
21
|
+
PRODUCTION: {
|
|
22
|
+
GET_TOKEN: 'https://pgapi.eps.com.bd/v1/Auth/GetToken',
|
|
23
|
+
INITIALIZE: 'https://pgapi.eps.com.bd/v1/EPSEngine/InitializeEPS',
|
|
24
|
+
VERIFY: 'https://pgapi.eps.com.bd/v1/EPSEngine/CheckMerchantTransactionStatus',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
(0, validator_1.validateConfig)(config);
|
|
28
|
+
this.config = {
|
|
29
|
+
...config,
|
|
30
|
+
sandbox: config.sandbox ?? false,
|
|
31
|
+
timeout: config.timeout ?? 30000,
|
|
32
|
+
};
|
|
33
|
+
this.httpClient = axios_1.default.create({
|
|
34
|
+
timeout: this.config.timeout,
|
|
35
|
+
headers: {
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
this.httpClient.interceptors.response.use((response) => response, (error) => {
|
|
40
|
+
throw this.handleError(error);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
getEndpoints() {
|
|
44
|
+
return this.config.sandbox ? this.ENDPOINTS.SANDBOX : this.ENDPOINTS.PRODUCTION;
|
|
45
|
+
}
|
|
46
|
+
async getToken() {
|
|
47
|
+
if (this.token && this.tokenExpiry && new Date() < this.tokenExpiry) {
|
|
48
|
+
return this.token;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const hash = (0, hash_1.generateHash)(this.config.username, this.config.hashKey);
|
|
52
|
+
const response = await this.httpClient.post(this.getEndpoints().GET_TOKEN, {
|
|
53
|
+
userName: this.config.username,
|
|
54
|
+
password: this.config.password,
|
|
55
|
+
}, {
|
|
56
|
+
headers: {
|
|
57
|
+
'x-hash': hash,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const data = response.data;
|
|
61
|
+
if (data.errorMessage || data.errorCode) {
|
|
62
|
+
throw new types_1.EPSError(data.errorMessage || 'Failed to get token', data.errorCode || 'TOKEN_ERROR', data);
|
|
63
|
+
}
|
|
64
|
+
this.token = data.token;
|
|
65
|
+
this.tokenExpiry = new Date(data.expireDate);
|
|
66
|
+
return data.token;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof types_1.EPSError) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
throw new types_1.EPSError(`Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'AUTH_ERROR');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async initializePayment(params) {
|
|
76
|
+
(0, validator_1.validatePaymentParams)(params);
|
|
77
|
+
try {
|
|
78
|
+
const token = await this.getToken();
|
|
79
|
+
const hash = (0, hash_1.generateHash)(params.merchantTransactionId, this.config.hashKey);
|
|
80
|
+
const requestBody = {
|
|
81
|
+
merchantId: this.config.merchantId,
|
|
82
|
+
storeId: this.config.storeId,
|
|
83
|
+
CustomerOrderId: params.customerOrderId,
|
|
84
|
+
merchantTransactionId: params.merchantTransactionId,
|
|
85
|
+
transactionTypeId: params.transactionTypeId ?? types_1.TransactionType.WEB,
|
|
86
|
+
financialEntityId: 0,
|
|
87
|
+
transitionStatusId: 0,
|
|
88
|
+
totalAmount: params.totalAmount,
|
|
89
|
+
ipAddress: params.ipAddress || '0.0.0.0',
|
|
90
|
+
version: '1',
|
|
91
|
+
successUrl: params.successUrl,
|
|
92
|
+
failUrl: params.failUrl,
|
|
93
|
+
cancelUrl: params.cancelUrl,
|
|
94
|
+
customerName: params.customerName,
|
|
95
|
+
customerEmail: params.customerEmail,
|
|
96
|
+
CustomerAddress: params.customerAddress,
|
|
97
|
+
CustomerAddress2: params.customerAddress2 || '',
|
|
98
|
+
CustomerCity: params.customerCity,
|
|
99
|
+
CustomerState: params.customerState,
|
|
100
|
+
CustomerPostcode: params.customerPostcode,
|
|
101
|
+
CustomerCountry: params.customerCountry || 'BD',
|
|
102
|
+
CustomerPhone: params.customerPhone,
|
|
103
|
+
ShipmentName: params.shipmentName || '',
|
|
104
|
+
ShipmentAddress: params.shipmentAddress || '',
|
|
105
|
+
ShipmentAddress2: params.shipmentAddress2 || '',
|
|
106
|
+
ShipmentCity: params.shipmentCity || '',
|
|
107
|
+
ShipmentState: params.shipmentState || '',
|
|
108
|
+
ShipmentPostcode: params.shipmentPostcode || '',
|
|
109
|
+
ShipmentCountry: params.shipmentCountry || '',
|
|
110
|
+
ValueA: params.valueA || '',
|
|
111
|
+
ValueB: params.valueB || '',
|
|
112
|
+
ValueC: params.valueC || '',
|
|
113
|
+
ValueD: params.valueD || '',
|
|
114
|
+
ShippingMethod: params.shippingMethod || 'NO',
|
|
115
|
+
NoOfItem: params.noOfItem?.toString() || '1',
|
|
116
|
+
ProductName: params.productName,
|
|
117
|
+
ProductProfile: params.productProfile || 'general',
|
|
118
|
+
ProductCategory: params.productCategory || 'general',
|
|
119
|
+
ProductList: params.productList || [],
|
|
120
|
+
};
|
|
121
|
+
const response = await this.httpClient.post(this.getEndpoints().INITIALIZE, requestBody, {
|
|
122
|
+
headers: {
|
|
123
|
+
'x-hash': hash,
|
|
124
|
+
Authorization: `Bearer ${token}`,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const data = response.data;
|
|
128
|
+
if (data.ErrorMessage || data.ErrorCode) {
|
|
129
|
+
throw new types_1.EPSError(data.ErrorMessage || 'Payment initialization failed', data.ErrorCode || 'INIT_ERROR', data);
|
|
130
|
+
}
|
|
131
|
+
return data;
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (error instanceof types_1.EPSError) {
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
throw new types_1.EPSError(`Payment initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'INIT_ERROR');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async verifyPayment(params) {
|
|
141
|
+
if (!params.merchantTransactionId && !params.epsTransactionId) {
|
|
142
|
+
throw new types_1.EPSError('Either merchantTransactionId or epsTransactionId is required', 'INVALID_PARAMS');
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const token = await this.getToken();
|
|
146
|
+
const hashValue = params.merchantTransactionId || params.epsTransactionId;
|
|
147
|
+
const hash = (0, hash_1.generateHash)(hashValue, this.config.hashKey);
|
|
148
|
+
const queryParams = new URLSearchParams();
|
|
149
|
+
if (params.merchantTransactionId) {
|
|
150
|
+
queryParams.append('merchantTransactionId', params.merchantTransactionId);
|
|
151
|
+
}
|
|
152
|
+
if (params.epsTransactionId) {
|
|
153
|
+
queryParams.append('EPSTransactionId', params.epsTransactionId);
|
|
154
|
+
}
|
|
155
|
+
const url = `${this.getEndpoints().VERIFY}?${queryParams.toString()}`;
|
|
156
|
+
const response = await this.httpClient.get(url, {
|
|
157
|
+
headers: {
|
|
158
|
+
'x-hash': hash,
|
|
159
|
+
Authorization: `Bearer ${token}`,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
const data = response.data;
|
|
163
|
+
if (data.ErrorMessage || data.ErrorCode) {
|
|
164
|
+
throw new types_1.EPSError(data.ErrorMessage || 'Transaction verification failed', data.ErrorCode || 'VERIFY_ERROR', data);
|
|
165
|
+
}
|
|
166
|
+
return data;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
if (error instanceof types_1.EPSError) {
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
throw new types_1.EPSError(`Transaction verification failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'VERIFY_ERROR');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async isPaymentSuccessful(transactionId) {
|
|
176
|
+
try {
|
|
177
|
+
const verification = await this.verifyPayment({
|
|
178
|
+
merchantTransactionId: transactionId,
|
|
179
|
+
});
|
|
180
|
+
return verification.Status.toLowerCase() === 'success';
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
handleError(error) {
|
|
187
|
+
if (error.response) {
|
|
188
|
+
const data = error.response.data;
|
|
189
|
+
return new types_1.EPSError(data?.ErrorMessage || data?.errorMessage || error.message, data?.ErrorCode || data?.errorCode || 'HTTP_ERROR', data);
|
|
190
|
+
}
|
|
191
|
+
if (error.request) {
|
|
192
|
+
return new types_1.EPSError('No response from EPS server', 'NETWORK_ERROR');
|
|
193
|
+
}
|
|
194
|
+
return new types_1.EPSError(error.message, 'UNKNOWN_ERROR');
|
|
195
|
+
}
|
|
196
|
+
clearToken() {
|
|
197
|
+
this.token = null;
|
|
198
|
+
this.tokenExpiry = null;
|
|
199
|
+
}
|
|
200
|
+
getConfig() {
|
|
201
|
+
return {
|
|
202
|
+
username: this.config.username,
|
|
203
|
+
merchantId: this.config.merchantId,
|
|
204
|
+
storeId: this.config.storeId,
|
|
205
|
+
sandbox: this.config.sandbox,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.EPS = EPS;
|
|
210
|
+
//# sourceMappingURL=EPS.js.map
|
package/dist/EPS.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EPS.js","sourceRoot":"","sources":["../src/EPS.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { EPS } from './EPS';
|
|
2
|
+
export { EPSConfig, EPSError, InitializePaymentParams, InitializePaymentResponse, ProductItem, TokenResponse, TransactionType, VerifyPaymentParams, VerifyPaymentResponse, } from './types';
|
|
3
|
+
export { generateHash, generateTransactionId, validateHashKey } from './utils/hash';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateHashKey = exports.generateTransactionId = exports.generateHash = exports.TransactionType = exports.EPSError = exports.EPS = void 0;
|
|
4
|
+
var EPS_1 = require("./EPS");
|
|
5
|
+
Object.defineProperty(exports, "EPS", { enumerable: true, get: function () { return EPS_1.EPS; } });
|
|
6
|
+
var types_1 = require("./types");
|
|
7
|
+
Object.defineProperty(exports, "EPSError", { enumerable: true, get: function () { return types_1.EPSError; } });
|
|
8
|
+
Object.defineProperty(exports, "TransactionType", { enumerable: true, get: function () { return types_1.TransactionType; } });
|
|
9
|
+
var hash_1 = require("./utils/hash");
|
|
10
|
+
Object.defineProperty(exports, "generateHash", { enumerable: true, get: function () { return hash_1.generateHash; } });
|
|
11
|
+
Object.defineProperty(exports, "generateTransactionId", { enumerable: true, get: function () { return hash_1.generateTransactionId; } });
|
|
12
|
+
Object.defineProperty(exports, "validateHashKey", { enumerable: true, get: function () { return hash_1.validateHashKey; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAQA,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,iCAUiB;AARf,iGAAA,QAAQ,OAAA;AAKR,wGAAA,eAAe,OAAA;AAIjB,qCAAoF;AAA3E,oGAAA,YAAY,OAAA;AAAE,6GAAA,qBAAqB,OAAA;AAAE,uGAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export interface EPSConfig {
|
|
2
|
+
username: string;
|
|
3
|
+
password: string;
|
|
4
|
+
hashKey: string;
|
|
5
|
+
merchantId: string;
|
|
6
|
+
storeId: string;
|
|
7
|
+
sandbox?: boolean;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare enum TransactionType {
|
|
11
|
+
WEB = 1,
|
|
12
|
+
ANDROID = 2,
|
|
13
|
+
IOS = 3
|
|
14
|
+
}
|
|
15
|
+
export interface ProductItem {
|
|
16
|
+
ProductName: string;
|
|
17
|
+
NoOfItem: string | number;
|
|
18
|
+
ProductProfile?: string;
|
|
19
|
+
ProductCategory?: string;
|
|
20
|
+
ProductPrice: string | number;
|
|
21
|
+
}
|
|
22
|
+
export interface InitializePaymentParams {
|
|
23
|
+
customerOrderId: string;
|
|
24
|
+
merchantTransactionId: string;
|
|
25
|
+
transactionTypeId?: TransactionType;
|
|
26
|
+
totalAmount: number;
|
|
27
|
+
successUrl: string;
|
|
28
|
+
failUrl: string;
|
|
29
|
+
cancelUrl: string;
|
|
30
|
+
customerName: string;
|
|
31
|
+
customerEmail: string;
|
|
32
|
+
customerAddress: string;
|
|
33
|
+
customerAddress2?: string;
|
|
34
|
+
customerCity: string;
|
|
35
|
+
customerState: string;
|
|
36
|
+
customerPostcode: string;
|
|
37
|
+
customerCountry?: string;
|
|
38
|
+
customerPhone: string;
|
|
39
|
+
shipmentName?: string;
|
|
40
|
+
shipmentAddress?: string;
|
|
41
|
+
shipmentAddress2?: string;
|
|
42
|
+
shipmentCity?: string;
|
|
43
|
+
shipmentState?: string;
|
|
44
|
+
shipmentPostcode?: string;
|
|
45
|
+
shipmentCountry?: string;
|
|
46
|
+
valueA?: string;
|
|
47
|
+
valueB?: string;
|
|
48
|
+
valueC?: string;
|
|
49
|
+
valueD?: string;
|
|
50
|
+
shippingMethod?: string;
|
|
51
|
+
noOfItem?: string | number;
|
|
52
|
+
productName: string;
|
|
53
|
+
productProfile?: string;
|
|
54
|
+
productCategory?: string;
|
|
55
|
+
productList?: ProductItem[];
|
|
56
|
+
ipAddress?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface TokenResponse {
|
|
59
|
+
token: string;
|
|
60
|
+
expireDate: string;
|
|
61
|
+
errorMessage: string | null;
|
|
62
|
+
errorCode: string | null;
|
|
63
|
+
}
|
|
64
|
+
export interface InitializePaymentResponse {
|
|
65
|
+
TransactionId: string;
|
|
66
|
+
RedirectURL: string;
|
|
67
|
+
ErrorMessage: string;
|
|
68
|
+
ErrorCode: string | null;
|
|
69
|
+
FinancialEntityList: any[] | null;
|
|
70
|
+
}
|
|
71
|
+
export interface VerifyPaymentParams {
|
|
72
|
+
merchantTransactionId?: string;
|
|
73
|
+
epsTransactionId?: string;
|
|
74
|
+
}
|
|
75
|
+
export interface VerifyPaymentResponse {
|
|
76
|
+
MerchantTransactionId: string;
|
|
77
|
+
EpsTransactionId: string;
|
|
78
|
+
Status: string;
|
|
79
|
+
TotalAmount: string;
|
|
80
|
+
TransactionDate: string;
|
|
81
|
+
TransactionType: string;
|
|
82
|
+
FinancialEntity: string;
|
|
83
|
+
ErrorCode: string;
|
|
84
|
+
ErrorMessage: string;
|
|
85
|
+
CustomerId: string;
|
|
86
|
+
CustomerName: string;
|
|
87
|
+
CustomerEmail: string;
|
|
88
|
+
CustomerAddress: string;
|
|
89
|
+
CustomerAddress2: string;
|
|
90
|
+
CustomerCity: string;
|
|
91
|
+
CustomerState: string;
|
|
92
|
+
CustomerPostcode: string;
|
|
93
|
+
CustomerCountry: string;
|
|
94
|
+
CustomerPhone: string;
|
|
95
|
+
ShipmentName: string;
|
|
96
|
+
ShipmentAddress: string;
|
|
97
|
+
ShipmentAddress2: string;
|
|
98
|
+
ShipmentCity: string;
|
|
99
|
+
ShipmentState: string;
|
|
100
|
+
ShipmentPostcode: string;
|
|
101
|
+
ShipmentCountry: string;
|
|
102
|
+
ValueA: string;
|
|
103
|
+
ValueB: string;
|
|
104
|
+
ValueC: string;
|
|
105
|
+
ValueD: string;
|
|
106
|
+
ShippingMethod: string;
|
|
107
|
+
NoOfItem: string;
|
|
108
|
+
ProductName: string;
|
|
109
|
+
ProductProfile: string;
|
|
110
|
+
ProductCategory: string;
|
|
111
|
+
PaymentReferance?: string;
|
|
112
|
+
}
|
|
113
|
+
export declare class EPSError extends Error {
|
|
114
|
+
code?: string;
|
|
115
|
+
response?: any;
|
|
116
|
+
constructor(message: string, code?: string, response?: any);
|
|
117
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EPSError = exports.TransactionType = void 0;
|
|
4
|
+
var TransactionType;
|
|
5
|
+
(function (TransactionType) {
|
|
6
|
+
TransactionType[TransactionType["WEB"] = 1] = "WEB";
|
|
7
|
+
TransactionType[TransactionType["ANDROID"] = 2] = "ANDROID";
|
|
8
|
+
TransactionType[TransactionType["IOS"] = 3] = "IOS";
|
|
9
|
+
})(TransactionType || (exports.TransactionType = TransactionType = {}));
|
|
10
|
+
class EPSError extends Error {
|
|
11
|
+
constructor(message, code, response) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'EPSError';
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.response = response;
|
|
16
|
+
Error.captureStackTrace(this, this.constructor);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.EPSError = EPSError;
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;AAuBA,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,mDAAO,CAAA;IACP,2DAAW,CAAA;IACX,mDAAO,CAAA;AACT,CAAC,EAJW,eAAe,+BAAf,eAAe,QAI1B;AAqND,MAAa,QAAS,SAAQ,KAAK;IAIjC,YAAY,OAAe,EAAE,IAAa,EAAE,QAAc;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF;AAXD,4BAWC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.generateHash = generateHash;
|
|
37
|
+
exports.validateHashKey = validateHashKey;
|
|
38
|
+
exports.generateTransactionId = generateTransactionId;
|
|
39
|
+
const crypto = __importStar(require("crypto"));
|
|
40
|
+
function generateHash(value, hashKey) {
|
|
41
|
+
try {
|
|
42
|
+
const hmac = crypto.createHmac('sha512', Buffer.from(hashKey, 'utf8'));
|
|
43
|
+
hmac.update(value, 'utf8');
|
|
44
|
+
return hmac.digest('base64');
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw new Error(`Hash generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function validateHashKey(hashKey) {
|
|
51
|
+
if (!hashKey || typeof hashKey !== 'string') {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const base64Regex = /^[A-Za-z0-9+/=]+$/;
|
|
55
|
+
return base64Regex.test(hashKey) && hashKey.length > 20;
|
|
56
|
+
}
|
|
57
|
+
function generateTransactionId() {
|
|
58
|
+
const now = new Date();
|
|
59
|
+
const year = now.getFullYear();
|
|
60
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
61
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
62
|
+
const hours = String(now.getHours()).padStart(2, '0');
|
|
63
|
+
const minutes = String(now.getMinutes()).padStart(2, '0');
|
|
64
|
+
const seconds = String(now.getSeconds()).padStart(2, '0');
|
|
65
|
+
const milliseconds = String(now.getMilliseconds()).padStart(3, '0');
|
|
66
|
+
return `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}`;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,oCAaC;AAOD,0CAQC;AAOD,sDAWC;AA7DD,+CAAiC;AAejC,SAAgB,YAAY,CAAC,KAAa,EAAE,OAAe;IACzD,IAAI,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAGvE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAG3B,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;IACzG,CAAC;AACH,CAAC;AAOD,SAAgB,eAAe,CAAC,OAAe;IAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,MAAM,WAAW,GAAG,mBAAmB,CAAC;IACxC,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AAC1D,CAAC;AAOD,SAAgB,qBAAqB;IACnC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEpE,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,EAAE,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateConfig = validateConfig;
|
|
4
|
+
exports.validatePaymentParams = validatePaymentParams;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
function validateConfig(config) {
|
|
7
|
+
const required = ['username', 'password', 'hashKey', 'merchantId', 'storeId'];
|
|
8
|
+
for (const field of required) {
|
|
9
|
+
if (!config[field]) {
|
|
10
|
+
throw new types_1.EPSError(`Missing required configuration: ${field}`, 'INVALID_CONFIG');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (config.username && !isValidEmail(config.username)) {
|
|
14
|
+
throw new types_1.EPSError('Invalid username format (expected email)', 'INVALID_CONFIG');
|
|
15
|
+
}
|
|
16
|
+
if (config.merchantId && !isValidUUID(config.merchantId)) {
|
|
17
|
+
throw new types_1.EPSError('Invalid merchantId format (expected UUID)', 'INVALID_CONFIG');
|
|
18
|
+
}
|
|
19
|
+
if (config.storeId && !isValidUUID(config.storeId)) {
|
|
20
|
+
throw new types_1.EPSError('Invalid storeId format (expected UUID)', 'INVALID_CONFIG');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function validatePaymentParams(params) {
|
|
24
|
+
const required = [
|
|
25
|
+
'customerOrderId',
|
|
26
|
+
'merchantTransactionId',
|
|
27
|
+
'totalAmount',
|
|
28
|
+
'successUrl',
|
|
29
|
+
'failUrl',
|
|
30
|
+
'cancelUrl',
|
|
31
|
+
'customerName',
|
|
32
|
+
'customerEmail',
|
|
33
|
+
'customerAddress',
|
|
34
|
+
'customerCity',
|
|
35
|
+
'customerState',
|
|
36
|
+
'customerPostcode',
|
|
37
|
+
'customerPhone',
|
|
38
|
+
'productName',
|
|
39
|
+
];
|
|
40
|
+
for (const field of required) {
|
|
41
|
+
if (!params[field]) {
|
|
42
|
+
throw new types_1.EPSError(`Missing required parameter: ${field}`, 'INVALID_PARAMS');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (params.merchantTransactionId.length < 10) {
|
|
46
|
+
throw new types_1.EPSError('merchantTransactionId must be at least 10 digits', 'INVALID_TRANSACTION_ID');
|
|
47
|
+
}
|
|
48
|
+
if (params.totalAmount <= 0) {
|
|
49
|
+
throw new types_1.EPSError('totalAmount must be greater than 0', 'INVALID_AMOUNT');
|
|
50
|
+
}
|
|
51
|
+
if (!isValidEmail(params.customerEmail)) {
|
|
52
|
+
throw new types_1.EPSError('Invalid customer email format', 'INVALID_EMAIL');
|
|
53
|
+
}
|
|
54
|
+
if (!isValidBDPhone(params.customerPhone)) {
|
|
55
|
+
throw new types_1.EPSError('Invalid phone number format (expected Bangladesh format: 01XXXXXXXXX)', 'INVALID_PHONE');
|
|
56
|
+
}
|
|
57
|
+
const urls = ['successUrl', 'failUrl', 'cancelUrl'];
|
|
58
|
+
for (const urlField of urls) {
|
|
59
|
+
const url = params[urlField];
|
|
60
|
+
if (!isValidURL(url)) {
|
|
61
|
+
throw new types_1.EPSError(`Invalid ${urlField} format`, 'INVALID_URL');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function isValidEmail(email) {
|
|
66
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
67
|
+
return emailRegex.test(email);
|
|
68
|
+
}
|
|
69
|
+
function isValidUUID(uuid) {
|
|
70
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
71
|
+
return uuidRegex.test(uuid);
|
|
72
|
+
}
|
|
73
|
+
function isValidBDPhone(phone) {
|
|
74
|
+
const bdPhoneRegex = /^01[0-9]{9}$/;
|
|
75
|
+
return bdPhoneRegex.test(phone.replace(/[^0-9]/g, ''));
|
|
76
|
+
}
|
|
77
|
+
function isValidURL(url) {
|
|
78
|
+
try {
|
|
79
|
+
new URL(url);
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/utils/validator.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eps-gateway-nodejs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unofficial Node.js SDK for EPS (Easy Payment System) Payment Gateway - Bangladesh",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"test": "jest",
|
|
10
|
+
"prepare": "npm run build",
|
|
11
|
+
"lint": "eslint src/**/*.ts",
|
|
12
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
13
|
+
"dev": "ts-node src/index.ts"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"eps",
|
|
17
|
+
"easy-payment-system",
|
|
18
|
+
"payment-gateway",
|
|
19
|
+
"bangladesh",
|
|
20
|
+
"payment",
|
|
21
|
+
"nodejs",
|
|
22
|
+
"typescript",
|
|
23
|
+
"eps-gateway",
|
|
24
|
+
"online-payment",
|
|
25
|
+
"bd-payment"
|
|
26
|
+
],
|
|
27
|
+
"author": "Imtiaz Najim <imtiaznajim@gmail.com>",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/imtiaznajim/eps-gateway-nodejs.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/imtiaznajim/eps-gateway-nodejs/issues"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/imtiaznajim/eps-gateway-nodejs#readme",
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"axios": "^1.6.5"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^20.11.0",
|
|
47
|
+
"@types/jest": "^29.5.11",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
49
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
50
|
+
"eslint": "^8.56.0",
|
|
51
|
+
"jest": "^29.7.0",
|
|
52
|
+
"prettier": "^3.2.4",
|
|
53
|
+
"ts-jest": "^29.1.1",
|
|
54
|
+
"ts-node": "^10.9.2",
|
|
55
|
+
"typescript": "^5.3.3"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=14.0.0"
|
|
59
|
+
}
|
|
60
|
+
}
|