quickpos 1.0.911 → 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/{example-heleket.js → examples/example-heleket.js} +3 -3
- 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/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/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/midtrans.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
|
|
4
|
+
class MidtransClient {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
const requiredFields = ['serverKey', 'clientKey'];
|
|
7
|
+
for (let field of requiredFields) {
|
|
8
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
this.serverKey = config.serverKey;
|
|
12
|
+
this.clientKey = config.clientKey;
|
|
13
|
+
this.isProduction = config.isProduction || false;
|
|
14
|
+
|
|
15
|
+
this.snapURL = this.isProduction
|
|
16
|
+
? 'https://app.midtrans.com/snap/v1'
|
|
17
|
+
: 'https://app.sandbox.midtrans.com/snap/v1';
|
|
18
|
+
|
|
19
|
+
this.coreURL = this.isProduction
|
|
20
|
+
? 'https://api.midtrans.com/v2'
|
|
21
|
+
: 'https://api.sandbox.midtrans.com/v2';
|
|
22
|
+
|
|
23
|
+
this.client = axios.create({
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
'Accept': 'application/json',
|
|
27
|
+
'Authorization': 'Basic ' + Buffer.from(this.serverKey + ':').toString('base64')
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.client.interceptors.response.use(response => {
|
|
32
|
+
return response;
|
|
33
|
+
}, error => {
|
|
34
|
+
if (error.response) {
|
|
35
|
+
throw new Error(`Midtrans API error: ${error.response.data.error_messages || error.response.data.status_message || error.message}`);
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`Midtrans API error: ${error.message}`);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async createPayment(options) {
|
|
42
|
+
try {
|
|
43
|
+
const orderId = options.orderId || `ORDER-${Date.now()}`;
|
|
44
|
+
|
|
45
|
+
const transactionDetails = {
|
|
46
|
+
transaction_details: {
|
|
47
|
+
order_id: orderId,
|
|
48
|
+
gross_amount: parseFloat(options.amount)
|
|
49
|
+
},
|
|
50
|
+
customer_details: {
|
|
51
|
+
first_name: options.firstName || options.name || 'Customer',
|
|
52
|
+
last_name: options.lastName || '',
|
|
53
|
+
email: options.email,
|
|
54
|
+
phone: options.phone || '+62812345678'
|
|
55
|
+
},
|
|
56
|
+
callbacks: {
|
|
57
|
+
finish: options.callbackUrl || options.callback_link
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Item details ekleme
|
|
62
|
+
if (options.items && Array.isArray(options.items)) {
|
|
63
|
+
transactionDetails.item_details = options.items;
|
|
64
|
+
} else {
|
|
65
|
+
transactionDetails.item_details = [{
|
|
66
|
+
id: 'ITEM-' + orderId,
|
|
67
|
+
price: parseFloat(options.amount),
|
|
68
|
+
quantity: 1,
|
|
69
|
+
name: options.itemName || options.name || 'Product'
|
|
70
|
+
}];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Opsiyonel alanlar
|
|
74
|
+
if (options.creditCard) {
|
|
75
|
+
transactionDetails.credit_card = options.creditCard;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (options.customExpiry) {
|
|
79
|
+
transactionDetails.custom_expiry = options.customExpiry;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const response = await this.client.post(`${this.snapURL}/transactions`, transactionDetails);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
status: 'success',
|
|
86
|
+
data: {
|
|
87
|
+
token: response.data.token,
|
|
88
|
+
url: response.data.redirect_url,
|
|
89
|
+
orderId: orderId
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
} catch (error) {
|
|
93
|
+
throw new Error(`Payment creation error: ${error.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async getTransactionStatus(orderId) {
|
|
98
|
+
try {
|
|
99
|
+
const response = await this.client.get(`${this.coreURL}/${orderId}/status`);
|
|
100
|
+
return response.data;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
throw new Error(`Transaction status error: ${error.message}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async handleCallback(callbackData) {
|
|
107
|
+
try {
|
|
108
|
+
const verification = await this.verifyNotification(callbackData);
|
|
109
|
+
|
|
110
|
+
if (!verification.status) {
|
|
111
|
+
throw new Error(verification.error.message);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const data = verification.data;
|
|
115
|
+
|
|
116
|
+
// Transaction status mapping
|
|
117
|
+
const statusMapping = {
|
|
118
|
+
'capture': 'success',
|
|
119
|
+
'settlement': 'success',
|
|
120
|
+
'pending': 'pending',
|
|
121
|
+
'deny': 'failed',
|
|
122
|
+
'cancel': 'cancelled',
|
|
123
|
+
'expire': 'expired',
|
|
124
|
+
'failure': 'failed'
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
status: statusMapping[data.transaction_status] || 'unknown',
|
|
129
|
+
orderId: data.order_id,
|
|
130
|
+
transactionId: data.transaction_id,
|
|
131
|
+
amount: parseFloat(data.gross_amount),
|
|
132
|
+
currency: data.currency || 'IDR',
|
|
133
|
+
paymentType: data.payment_type,
|
|
134
|
+
transactionStatus: data.transaction_status,
|
|
135
|
+
fraudStatus: data.fraud_status,
|
|
136
|
+
transactionTime: data.transaction_time
|
|
137
|
+
};
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw new Error(`Error in Midtrans callback handling: ${error.message}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async verifyNotification(data) {
|
|
144
|
+
try {
|
|
145
|
+
const orderId = data.order_id;
|
|
146
|
+
const statusCode = data.status_code;
|
|
147
|
+
const grossAmount = data.gross_amount;
|
|
148
|
+
const serverKey = this.serverKey;
|
|
149
|
+
|
|
150
|
+
// Signature verification
|
|
151
|
+
const signatureKey = crypto
|
|
152
|
+
.createHash('sha512')
|
|
153
|
+
.update(orderId + statusCode + grossAmount + serverKey)
|
|
154
|
+
.digest('hex');
|
|
155
|
+
|
|
156
|
+
if (data.signature_key !== signatureKey) {
|
|
157
|
+
return {
|
|
158
|
+
status: false,
|
|
159
|
+
error: {
|
|
160
|
+
code: 401,
|
|
161
|
+
message: 'Invalid signature key'
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Fraud status check
|
|
167
|
+
if (data.transaction_status === 'capture') {
|
|
168
|
+
if (data.fraud_status === 'challenge') {
|
|
169
|
+
return {
|
|
170
|
+
status: false,
|
|
171
|
+
error: {
|
|
172
|
+
code: 403,
|
|
173
|
+
message: 'Transaction challenged by FDS'
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
} else if (data.fraud_status === 'deny') {
|
|
177
|
+
return {
|
|
178
|
+
status: false,
|
|
179
|
+
error: {
|
|
180
|
+
code: 403,
|
|
181
|
+
message: 'Transaction denied by FDS'
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
status: true,
|
|
189
|
+
data: data
|
|
190
|
+
};
|
|
191
|
+
} catch (error) {
|
|
192
|
+
return {
|
|
193
|
+
status: false,
|
|
194
|
+
error: {
|
|
195
|
+
code: 500,
|
|
196
|
+
message: error.message
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async cancelTransaction(orderId) {
|
|
203
|
+
try {
|
|
204
|
+
const response = await this.client.post(`${this.coreURL}/${orderId}/cancel`);
|
|
205
|
+
return response.data;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
throw new Error(`Cancel transaction error: ${error.message}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async refundTransaction(orderId, amount, reason) {
|
|
212
|
+
try {
|
|
213
|
+
const refundData = {
|
|
214
|
+
refund_key: `refund-${orderId}-${Date.now()}`,
|
|
215
|
+
amount: amount,
|
|
216
|
+
reason: reason || 'Customer request'
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const response = await this.client.post(`${this.coreURL}/${orderId}/refund`, refundData);
|
|
220
|
+
return response.data;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw new Error(`Refund transaction error: ${error.message}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
module.exports = MidtransClient;
|