quickpos 1.0.910 → 1.0.912
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/PROVIDERS-DETAILS.md +1544 -0
- package/examples/example-2checkout.js +78 -0
- package/examples/example-bitpay.js +83 -0
- package/examples/example-cardcom.js +80 -0
- package/examples/example-cashfree.js +109 -0
- package/examples/example-checkout.js +85 -0
- package/examples/example-coingate.js +101 -0
- package/examples/example-coinpayments.js +89 -0
- package/examples/example-doku.js +27 -0
- package/examples/example-epay.js +64 -0
- package/examples/example-epoint.js +91 -0
- package/examples/example-freekassa.js +26 -0
- package/examples/example-heleket.js +139 -0
- package/examples/example-konnect.js +227 -0
- package/examples/example-midtrans.js +80 -0
- package/examples/example-noonpayments.js +297 -0
- package/examples/example-nowpayments.js +289 -0
- package/examples/example-omise.js +27 -0
- package/examples/example-paycom.js +82 -0
- package/{example-paydisini.js → examples/example-paydisini.js} +1 -1
- package/examples/example-payid19.js +87 -0
- package/examples/example-paykun.js +29 -0
- package/examples/example-payme.js +202 -0
- package/examples/example-paymentwall.js +201 -0
- package/examples/example-paynet.js +104 -0
- package/examples/example-paynettr.js +18 -0
- package/examples/example-payoneer.js +74 -0
- package/examples/example-payop.js +351 -0
- package/examples/example-paypal.js +200 -0
- package/examples/example-payriff.js +89 -0
- package/examples/example-paysend.js +81 -0
- package/examples/example-payspace.js +103 -0
- package/examples/example-payssion.js +27 -0
- package/examples/example-paytabs.js +28 -0
- package/examples/example-paytm.js +78 -0
- package/examples/example-payuindia.js +108 -0
- package/examples/example-payulatam.js +75 -0
- package/examples/example-phonepe.js +27 -0
- package/examples/example-picpay.js +27 -0
- package/examples/example-plisio.js +84 -0
- package/examples/example-portwallet.js +90 -0
- package/examples/example-primepayments.js +250 -0
- package/examples/example-razorpay.js +30 -0
- package/examples/example-senangpay.js +28 -0
- package/examples/example-shurjopay.js +94 -0
- package/examples/example-toyyibpay.js +80 -0
- package/examples/example-tripay.js +89 -0
- package/examples/example-unitpay.js +26 -0
- package/examples/example-urway.js +28 -0
- package/examples/example-volet.js +80 -0
- package/examples/example-xendit.js +28 -0
- package/examples/example-yallapay.js +253 -0
- package/examples/example-yookassa.js +27 -0
- package/examples/example-youcanpay.js +28 -0
- package/examples/example-zarinpal.js +98 -0
- package/{example.js → examples/example.js} +1 -1
- package/lib/2checkout.js +165 -0
- package/lib/amazonpay.js +161 -0
- package/lib/bitpay.js +122 -0
- package/lib/cardcom.js +193 -0
- package/lib/cashfree.js +184 -0
- package/lib/checkout.js +248 -0
- package/lib/coinbase.js +150 -0
- package/lib/coingate.js +137 -0
- package/lib/coinpayments.js +245 -0
- package/lib/doku.js +173 -0
- package/lib/epay.js +175 -0
- package/lib/epoint.js +162 -0
- package/lib/freekassa.js +128 -0
- package/lib/heleket.js +67 -1
- package/lib/instamojo.js +158 -0
- package/lib/konnect.js +211 -0
- package/lib/midtrans.js +227 -0
- package/lib/noonpayments.js +650 -0
- package/lib/nowpayments.js +311 -0
- package/lib/omise.js +150 -0
- package/lib/paddle.js +180 -0
- package/lib/paycom.js +216 -0
- package/lib/payid19.js +211 -0
- package/lib/paykun.js +144 -0
- package/lib/payme.js +302 -0
- package/lib/paymentwall.js +205 -0
- package/lib/paynet.js +186 -0
- package/lib/paynettr.js +165 -0
- package/lib/payoneer.js +128 -0
- package/lib/payop.js +256 -0
- package/lib/paypal.js +542 -0
- package/lib/payriff.js +148 -0
- package/lib/paysend.js +189 -0
- package/lib/payspace.js +168 -0
- package/lib/payssion.js +177 -0
- package/lib/paytabs.js +145 -0
- package/lib/paytm.js +253 -0
- package/lib/payuindia.js +162 -0
- package/lib/payulatam.js +179 -0
- package/lib/perfectmoney.js +143 -0
- package/lib/phonepe.js +174 -0
- package/lib/picpay.js +119 -0
- package/lib/plisio.js +234 -0
- package/lib/portwallet.js +152 -0
- package/lib/primepayments.js +256 -0
- package/lib/razorpay.js +205 -0
- package/lib/senangpay.js +130 -0
- package/lib/shurjopay.js +159 -0
- package/lib/toyyibpay.js +151 -0
- package/lib/tripay.js +220 -0
- package/lib/unitpay.js +223 -0
- package/lib/urway.js +182 -0
- package/lib/volet.js +147 -0
- package/lib/xendit.js +206 -0
- package/lib/yallapay.js +279 -0
- package/lib/yookassa.js +193 -0
- package/lib/youcanpay.js +124 -0
- package/lib/zarinpal.js +157 -0
- package/package.json +138 -64
- package/readme.md +348 -105
- package/test.js +492 -0
- package/example-heleket.js +0 -83
- package/lib/vallet.js +0 -22
- /package/{example-anypay.js → examples/example-anypay.js} +0 -0
- /package/{example-bufpay.js → examples/example-bufpay.js} +0 -0
- /package/{example-cryptomus.js → examples/example-cryptomus.js} +0 -0
- /package/{example-esnekpos.js → examples/example-esnekpos.js} +0 -0
- /package/{example-fedapay.js → examples/example-fedapay.js} +0 -0
- /package/{example-iyzico.js → examples/example-iyzico.js} +0 -0
- /package/{example-papara.js → examples/example-papara.js} +0 -0
- /package/{example-payeer.js → examples/example-payeer.js} +0 -0
- /package/{example-paymaya.js → examples/example-paymaya.js} +0 -0
- /package/{example-shopier.js → examples/example-shopier.js} +0 -0
- /package/{ipaymu.js → examples/ipaymu.js} +0 -0
- /package/{oderopay.js → examples/oderopay.js} +0 -0
package/lib/paycom.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
class PaycomClient {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
const requiredFields = ['merchantId', 'secretKey'];
|
|
6
|
+
for (let field of requiredFields) {
|
|
7
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
this.merchantId = config.merchantId;
|
|
11
|
+
this.secretKey = config.secretKey;
|
|
12
|
+
this.URL = 'https://checkout.paycom.uz/api';
|
|
13
|
+
|
|
14
|
+
this.client = axios.create({
|
|
15
|
+
baseURL: this.URL,
|
|
16
|
+
headers: {
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
'X-Auth': this.merchantId + ':' + this.secretKey
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
this.client.interceptors.response.use(response => {
|
|
23
|
+
return response;
|
|
24
|
+
}, error => {
|
|
25
|
+
if (error.response) {
|
|
26
|
+
throw new Error(`Paycom API error: ${error.response.data.error?.message || error.message}`);
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Paycom API error: ${error.message}`);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async createPayment(options) {
|
|
33
|
+
try {
|
|
34
|
+
const orderId = options.orderId || `ORDER-${Date.now()}`;
|
|
35
|
+
const amount = Math.round(parseFloat(options.amount) * 100); // Convert to tiyin
|
|
36
|
+
|
|
37
|
+
// Paycom uses a unique link generation system
|
|
38
|
+
const params = {
|
|
39
|
+
m: this.merchantId,
|
|
40
|
+
ac: {
|
|
41
|
+
order_id: orderId
|
|
42
|
+
},
|
|
43
|
+
a: amount,
|
|
44
|
+
c: options.callbackUrl || options.callback_link,
|
|
45
|
+
l: options.lang || 'ru'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Generate payment URL
|
|
49
|
+
const encodedParams = Buffer.from(JSON.stringify(params)).toString('base64');
|
|
50
|
+
const paymentUrl = `https://checkout.paycom.uz/${encodedParams}`;
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
status: 'success',
|
|
54
|
+
data: {
|
|
55
|
+
url: paymentUrl,
|
|
56
|
+
orderId: orderId,
|
|
57
|
+
amount: options.amount,
|
|
58
|
+
params: encodedParams
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw new Error(`Payment creation error: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async handleCallback(callbackData) {
|
|
67
|
+
try {
|
|
68
|
+
// Paycom uses JSON-RPC 2.0 protocol
|
|
69
|
+
const method = callbackData.method;
|
|
70
|
+
const params = callbackData.params;
|
|
71
|
+
const id = callbackData.id;
|
|
72
|
+
|
|
73
|
+
switch (method) {
|
|
74
|
+
case 'CheckPerformTransaction':
|
|
75
|
+
return await this.checkPerformTransaction(params, id);
|
|
76
|
+
|
|
77
|
+
case 'CreateTransaction':
|
|
78
|
+
return await this.createTransaction(params, id);
|
|
79
|
+
|
|
80
|
+
case 'PerformTransaction':
|
|
81
|
+
return await this.performTransaction(params, id);
|
|
82
|
+
|
|
83
|
+
case 'CancelTransaction':
|
|
84
|
+
return await this.cancelTransaction(params, id);
|
|
85
|
+
|
|
86
|
+
case 'CheckTransaction':
|
|
87
|
+
return await this.checkTransaction(params, id);
|
|
88
|
+
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`Unknown method: ${method}`);
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
throw new Error(`Error in Paycom callback handling: ${error.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async checkPerformTransaction(params, id) {
|
|
98
|
+
// Verify that transaction can be performed
|
|
99
|
+
const orderId = params.account.order_id;
|
|
100
|
+
const amount = params.amount;
|
|
101
|
+
|
|
102
|
+
// You should check if order exists and amount is correct
|
|
103
|
+
// Return success response
|
|
104
|
+
return {
|
|
105
|
+
jsonrpc: '2.0',
|
|
106
|
+
id: id,
|
|
107
|
+
result: {
|
|
108
|
+
allow: true
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async createTransaction(params, id) {
|
|
114
|
+
// Create transaction in your database
|
|
115
|
+
const transactionId = params.id;
|
|
116
|
+
const time = params.time;
|
|
117
|
+
const amount = params.amount;
|
|
118
|
+
const orderId = params.account.order_id;
|
|
119
|
+
|
|
120
|
+
// Save transaction with state 1 (created)
|
|
121
|
+
return {
|
|
122
|
+
jsonrpc: '2.0',
|
|
123
|
+
id: id,
|
|
124
|
+
result: {
|
|
125
|
+
create_time: time,
|
|
126
|
+
transaction: transactionId.toString(),
|
|
127
|
+
state: 1
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async performTransaction(params, id) {
|
|
133
|
+
// Perform the transaction (complete payment)
|
|
134
|
+
const transactionId = params.id;
|
|
135
|
+
|
|
136
|
+
// Update transaction state to 2 (completed)
|
|
137
|
+
return {
|
|
138
|
+
jsonrpc: '2.0',
|
|
139
|
+
id: id,
|
|
140
|
+
result: {
|
|
141
|
+
transaction: transactionId.toString(),
|
|
142
|
+
perform_time: Date.now(),
|
|
143
|
+
state: 2
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async cancelTransaction(params, id) {
|
|
149
|
+
// Cancel transaction
|
|
150
|
+
const transactionId = params.id;
|
|
151
|
+
const reason = params.reason;
|
|
152
|
+
|
|
153
|
+
// Update transaction state to -1 (cancelled) or -2 (cancelled after complete)
|
|
154
|
+
return {
|
|
155
|
+
jsonrpc: '2.0',
|
|
156
|
+
id: id,
|
|
157
|
+
result: {
|
|
158
|
+
transaction: transactionId.toString(),
|
|
159
|
+
cancel_time: Date.now(),
|
|
160
|
+
state: -1
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async checkTransaction(params, id) {
|
|
166
|
+
// Check transaction status
|
|
167
|
+
const transactionId = params.id;
|
|
168
|
+
|
|
169
|
+
// Return transaction info from your database
|
|
170
|
+
return {
|
|
171
|
+
jsonrpc: '2.0',
|
|
172
|
+
id: id,
|
|
173
|
+
result: {
|
|
174
|
+
create_time: 0,
|
|
175
|
+
perform_time: 0,
|
|
176
|
+
cancel_time: 0,
|
|
177
|
+
transaction: transactionId.toString(),
|
|
178
|
+
state: 1,
|
|
179
|
+
reason: null
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async verifyCallback(data) {
|
|
185
|
+
try {
|
|
186
|
+
// Verify authorization header
|
|
187
|
+
const authHeader = data.headers?.['x-auth'];
|
|
188
|
+
const expectedAuth = this.merchantId + ':' + this.secretKey;
|
|
189
|
+
|
|
190
|
+
if (authHeader !== expectedAuth) {
|
|
191
|
+
return {
|
|
192
|
+
status: false,
|
|
193
|
+
error: {
|
|
194
|
+
code: -32504,
|
|
195
|
+
message: 'Insufficient privilege to perform this method'
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
status: true,
|
|
202
|
+
data: data
|
|
203
|
+
};
|
|
204
|
+
} catch (error) {
|
|
205
|
+
return {
|
|
206
|
+
status: false,
|
|
207
|
+
error: {
|
|
208
|
+
code: 500,
|
|
209
|
+
message: error.message
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
module.exports = PaycomClient;
|
package/lib/payid19.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
|
|
4
|
+
class PayID19Client {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
const requiredFields = ['apiKey', 'secretKey'];
|
|
7
|
+
for (let field of requiredFields) {
|
|
8
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
this.apiKey = config.apiKey;
|
|
12
|
+
this.secretKey = config.secretKey;
|
|
13
|
+
this.URL = 'https://payid19.com/api/v1';
|
|
14
|
+
|
|
15
|
+
this.client = axios.create({
|
|
16
|
+
baseURL: this.URL,
|
|
17
|
+
headers: {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
'Authorization': `Bearer ${this.apiKey}`
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
this.client.interceptors.response.use(response => {
|
|
24
|
+
return response;
|
|
25
|
+
}, error => {
|
|
26
|
+
if (error.response) {
|
|
27
|
+
throw new Error(`PayID19 API error: ${error.response.data.message || error.message}`);
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`PayID19 API error: ${error.message}`);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
generateSignature(data) {
|
|
34
|
+
const sortedData = Object.keys(data)
|
|
35
|
+
.sort()
|
|
36
|
+
.map(key => `${key}=${data[key]}`)
|
|
37
|
+
.join('&');
|
|
38
|
+
|
|
39
|
+
return crypto
|
|
40
|
+
.createHmac('sha256', this.secretKey)
|
|
41
|
+
.update(sortedData)
|
|
42
|
+
.digest('hex');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async createPayment(options) {
|
|
46
|
+
try {
|
|
47
|
+
const orderId = options.orderId || `ORDER-${Date.now()}`;
|
|
48
|
+
|
|
49
|
+
const requestData = {
|
|
50
|
+
merchant_order_id: orderId,
|
|
51
|
+
amount: parseFloat(options.amount),
|
|
52
|
+
currency: options.currency || 'IDR',
|
|
53
|
+
customer_name: options.customerName || options.name || 'Customer',
|
|
54
|
+
customer_email: options.customerEmail || options.email,
|
|
55
|
+
customer_phone: options.customerPhone || options.phone || '',
|
|
56
|
+
callback_url: options.callbackUrl || options.callback_link,
|
|
57
|
+
return_url: options.returnUrl || options.callback_link,
|
|
58
|
+
description: options.description || options.name || 'Payment',
|
|
59
|
+
payment_method: options.paymentMethod || 'all'
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Generate signature
|
|
63
|
+
const signature = this.generateSignature(requestData);
|
|
64
|
+
requestData.signature = signature;
|
|
65
|
+
|
|
66
|
+
const response = await this.client.post('/payment/create', requestData);
|
|
67
|
+
|
|
68
|
+
if (response.data.status === 'success') {
|
|
69
|
+
return {
|
|
70
|
+
status: 'success',
|
|
71
|
+
data: {
|
|
72
|
+
paymentId: response.data.data.payment_id,
|
|
73
|
+
url: response.data.data.payment_url,
|
|
74
|
+
orderId: orderId,
|
|
75
|
+
qrCode: response.data.data.qr_code,
|
|
76
|
+
expiredAt: response.data.data.expired_at
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
} else {
|
|
80
|
+
throw new Error(response.data.message || 'Payment creation failed');
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
throw new Error(`Payment creation error: ${error.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async getPaymentStatus(paymentId) {
|
|
88
|
+
try {
|
|
89
|
+
const response = await this.client.get(`/payment/status/${paymentId}`);
|
|
90
|
+
|
|
91
|
+
if (response.data.status === 'success') {
|
|
92
|
+
return response.data.data;
|
|
93
|
+
} else {
|
|
94
|
+
throw new Error(response.data.message || 'Failed to get payment status');
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
throw new Error(`Payment status error: ${error.message}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async handleCallback(callbackData) {
|
|
102
|
+
try {
|
|
103
|
+
const verification = await this.verifyCallback(callbackData);
|
|
104
|
+
|
|
105
|
+
if (!verification.status) {
|
|
106
|
+
throw new Error(verification.error.message);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const data = verification.data;
|
|
110
|
+
|
|
111
|
+
// Status mapping
|
|
112
|
+
const statusMapping = {
|
|
113
|
+
'paid': 'success',
|
|
114
|
+
'pending': 'pending',
|
|
115
|
+
'expired': 'expired',
|
|
116
|
+
'failed': 'failed',
|
|
117
|
+
'cancelled': 'cancelled'
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
status: statusMapping[data.payment_status] || 'unknown',
|
|
122
|
+
paymentId: data.payment_id,
|
|
123
|
+
orderId: data.merchant_order_id,
|
|
124
|
+
amount: parseFloat(data.amount),
|
|
125
|
+
currency: data.currency,
|
|
126
|
+
paymentMethod: data.payment_method,
|
|
127
|
+
paymentStatus: data.payment_status,
|
|
128
|
+
paidAt: data.paid_at,
|
|
129
|
+
fee: parseFloat(data.fee || 0),
|
|
130
|
+
netAmount: parseFloat(data.net_amount || data.amount)
|
|
131
|
+
};
|
|
132
|
+
} catch (error) {
|
|
133
|
+
throw new Error(`Error in PayID19 callback handling: ${error.message}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async verifyCallback(data) {
|
|
138
|
+
try {
|
|
139
|
+
const receivedSignature = data.signature;
|
|
140
|
+
delete data.signature;
|
|
141
|
+
|
|
142
|
+
const expectedSignature = this.generateSignature(data);
|
|
143
|
+
|
|
144
|
+
if (receivedSignature !== expectedSignature) {
|
|
145
|
+
return {
|
|
146
|
+
status: false,
|
|
147
|
+
error: {
|
|
148
|
+
code: 401,
|
|
149
|
+
message: 'Invalid signature'
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (data.payment_status === 'failed' || data.payment_status === 'cancelled') {
|
|
155
|
+
return {
|
|
156
|
+
status: false,
|
|
157
|
+
error: {
|
|
158
|
+
code: 400,
|
|
159
|
+
message: `Payment ${data.payment_status}`
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Restore signature for callback response
|
|
165
|
+
data.signature = receivedSignature;
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
status: true,
|
|
169
|
+
data: data
|
|
170
|
+
};
|
|
171
|
+
} catch (error) {
|
|
172
|
+
return {
|
|
173
|
+
status: false,
|
|
174
|
+
error: {
|
|
175
|
+
code: 500,
|
|
176
|
+
message: error.message
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async getBalance() {
|
|
183
|
+
try {
|
|
184
|
+
const response = await this.client.get('/merchant/balance');
|
|
185
|
+
|
|
186
|
+
if (response.data.status === 'success') {
|
|
187
|
+
return response.data.data;
|
|
188
|
+
} else {
|
|
189
|
+
throw new Error(response.data.message || 'Failed to get balance');
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
throw new Error(`Balance error: ${error.message}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async getPaymentMethods() {
|
|
197
|
+
try {
|
|
198
|
+
const response = await this.client.get('/payment/methods');
|
|
199
|
+
|
|
200
|
+
if (response.data.status === 'success') {
|
|
201
|
+
return response.data.data;
|
|
202
|
+
} else {
|
|
203
|
+
throw new Error(response.data.message || 'Failed to get payment methods');
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw new Error(`Payment methods error: ${error.message}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
module.exports = PayID19Client;
|
package/lib/paykun.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
|
|
4
|
+
class PayKunClient {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
const requiredFields = ['merchantId', 'accessToken', 'encryptionKey'];
|
|
7
|
+
for (let field of requiredFields) {
|
|
8
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
this.merchantId = config.merchantId;
|
|
12
|
+
this.accessToken = config.accessToken;
|
|
13
|
+
this.encryptionKey = config.encryptionKey;
|
|
14
|
+
this.baseURL = config.sandbox
|
|
15
|
+
? 'https://sandbox.paykun.com/api'
|
|
16
|
+
: 'https://api.paykun.com';
|
|
17
|
+
|
|
18
|
+
this.client = axios.create({
|
|
19
|
+
baseURL: this.baseURL,
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
'MerchantId': this.merchantId
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async createPayment(options) {
|
|
28
|
+
try {
|
|
29
|
+
const orderId = options.orderId || `ORDER-${Date.now()}`;
|
|
30
|
+
|
|
31
|
+
const paymentData = {
|
|
32
|
+
merchant_id: this.merchantId,
|
|
33
|
+
access_token: this.accessToken,
|
|
34
|
+
order: {
|
|
35
|
+
number: orderId,
|
|
36
|
+
amount: parseFloat(options.amount).toFixed(2),
|
|
37
|
+
currency: options.currency || 'INR'
|
|
38
|
+
},
|
|
39
|
+
customer: {
|
|
40
|
+
name: options.name || options.customerName || '',
|
|
41
|
+
email: options.email || '',
|
|
42
|
+
mobile: options.phone || ''
|
|
43
|
+
},
|
|
44
|
+
custom_fields: {
|
|
45
|
+
field1: options.field1 || '',
|
|
46
|
+
field2: options.field2 || ''
|
|
47
|
+
},
|
|
48
|
+
success_url: options.successUrl || options.callback_link,
|
|
49
|
+
failure_url: options.failureUrl || options.callback_link
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const response = await this.client.post('/payment/initiate', paymentData);
|
|
53
|
+
|
|
54
|
+
if (response.data.status && response.data.data) {
|
|
55
|
+
return {
|
|
56
|
+
status: 'success',
|
|
57
|
+
data: {
|
|
58
|
+
url: response.data.data.url,
|
|
59
|
+
transactionId: response.data.data.transaction_id,
|
|
60
|
+
orderId: orderId,
|
|
61
|
+
amount: paymentData.order.amount,
|
|
62
|
+
currency: paymentData.order.currency
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error(response.data.errors?.errorMessage || 'Payment creation failed');
|
|
67
|
+
}
|
|
68
|
+
} catch (error) {
|
|
69
|
+
throw new Error(`Payment creation error: ${error.response?.data?.errors?.errorMessage || error.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async handleCallback(callbackData) {
|
|
74
|
+
try {
|
|
75
|
+
const transactionId = callbackData.payment_id || callbackData.transaction_id;
|
|
76
|
+
|
|
77
|
+
if (!transactionId) {
|
|
78
|
+
throw new Error('Transaction ID not found in callback data');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Verify payment
|
|
82
|
+
const payment = await this.getTransactionDetails(transactionId);
|
|
83
|
+
|
|
84
|
+
// Status mapping
|
|
85
|
+
const statusMapping = {
|
|
86
|
+
'Success': 'success',
|
|
87
|
+
'Pending': 'pending',
|
|
88
|
+
'Failed': 'failed',
|
|
89
|
+
'Refund': 'refunded',
|
|
90
|
+
'Cancelled': 'failed'
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
status: statusMapping[payment.transaction.status] || 'unknown',
|
|
95
|
+
orderId: payment.transaction.order.orderId,
|
|
96
|
+
transactionId: payment.transaction.payment.id,
|
|
97
|
+
amount: parseFloat(payment.transaction.order.gross_amount),
|
|
98
|
+
currency: payment.transaction.order.currency,
|
|
99
|
+
paymentStatus: payment.transaction.status,
|
|
100
|
+
paymentMethod: payment.transaction.payment.method?.type
|
|
101
|
+
};
|
|
102
|
+
} catch (error) {
|
|
103
|
+
throw new Error(`Error in PayKun callback handling: ${error.message}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async getTransactionDetails(transactionId) {
|
|
108
|
+
try {
|
|
109
|
+
const response = await this.client.get(`/payment/${this.merchantId}/${this.accessToken}/${transactionId}`);
|
|
110
|
+
|
|
111
|
+
if (response.data.status) {
|
|
112
|
+
return response.data.data;
|
|
113
|
+
} else {
|
|
114
|
+
throw new Error(response.data.errors?.errorMessage || 'Failed to get transaction details');
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw new Error(`Error getting transaction details: ${error.response?.data?.errors?.errorMessage || error.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async refundPayment(transactionId, options = {}) {
|
|
122
|
+
try {
|
|
123
|
+
const refundData = {
|
|
124
|
+
merchant_id: this.merchantId,
|
|
125
|
+
access_token: this.accessToken,
|
|
126
|
+
transaction_id: transactionId,
|
|
127
|
+
amount: options.amount,
|
|
128
|
+
reason: options.reason || 'Customer Request'
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const response = await this.client.post('/payment/refund', refundData);
|
|
132
|
+
|
|
133
|
+
if (response.data.status) {
|
|
134
|
+
return response.data.data;
|
|
135
|
+
} else {
|
|
136
|
+
throw new Error(response.data.errors?.errorMessage || 'Refund failed');
|
|
137
|
+
}
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw new Error(`Error processing refund: ${error.response?.data?.errors?.errorMessage || error.message}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = PayKunClient;
|