quickpos 1.0.2 → 1.0.4
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/example-payeer.js +74 -0
- package/lib/cryptomus.js +122 -0
- package/lib/payeer.js +110 -0
- package/package.json +4 -2
- package/readme.md +6 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const bodyParser = require('body-parser');
|
|
3
|
+
const QuickPos = require('quickpos');
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
app.use(bodyParser.json({ limit: '50mb', extended: true }));
|
|
7
|
+
app.use(bodyParser.urlencoded({ extended: true }));
|
|
8
|
+
app.use(require('multer')().none());
|
|
9
|
+
|
|
10
|
+
const quickPos = new QuickPos({
|
|
11
|
+
providers: {
|
|
12
|
+
payeer: {
|
|
13
|
+
m_shop: 'XXXX',
|
|
14
|
+
m_key: 'XXXXXX'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
app.use(quickPos.middleware());
|
|
20
|
+
|
|
21
|
+
app.use(async (req, res, next) => {
|
|
22
|
+
console.log('Middleware çalıştı');
|
|
23
|
+
console.log(req.method, req.url);
|
|
24
|
+
next();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
(async () => {
|
|
28
|
+
const payment = await quickPos.providers['payeer'].createPayment({
|
|
29
|
+
orderId: 'S12345',
|
|
30
|
+
amount: '0.01',
|
|
31
|
+
currency: 'RUB',
|
|
32
|
+
description: 'Test payment'
|
|
33
|
+
});
|
|
34
|
+
console.log(payment);
|
|
35
|
+
})();
|
|
36
|
+
|
|
37
|
+
app.post('/status', quickPos.handleCallback('payeer'), async (req, res) => {
|
|
38
|
+
/*
|
|
39
|
+
POST /status
|
|
40
|
+
{
|
|
41
|
+
status: 'success',
|
|
42
|
+
orderId: 'S12345',
|
|
43
|
+
amount: '0.01',
|
|
44
|
+
currency: 'RUB',
|
|
45
|
+
operationId: '2175845325',
|
|
46
|
+
paymentDate: '29.12.2024 20:37:43'
|
|
47
|
+
}
|
|
48
|
+
Ödeme başarılı: {
|
|
49
|
+
status: 'success',
|
|
50
|
+
orderId: 'S12345',
|
|
51
|
+
amount: '0.01',
|
|
52
|
+
currency: 'RUB',
|
|
53
|
+
operationId: 'xxxx',
|
|
54
|
+
paymentDate: '29.12.2024 20:37:43'
|
|
55
|
+
}
|
|
56
|
+
*/
|
|
57
|
+
console.log(req.paymentResult);
|
|
58
|
+
try {
|
|
59
|
+
if (req.paymentResult.status === 'success') {
|
|
60
|
+
console.log('Ödeme başarılı:', req.paymentResult);
|
|
61
|
+
} else {
|
|
62
|
+
console.error('Ödeme başarısız:', req.paymentResult);
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('Webhook hatası:', error);
|
|
66
|
+
res.status(400).json({error: error.message});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
const PORT = 80;
|
|
72
|
+
app.listen(PORT, () => {
|
|
73
|
+
console.log(`Webhook server running on port ${PORT}`);
|
|
74
|
+
});
|
package/lib/cryptomus.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
const axios = require('axios');
|
|
3
|
+
|
|
4
|
+
class Cryptomus {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
const requiredFields = ['merchantId', 'paymentKey'];
|
|
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.paymentKey = config.paymentKey;
|
|
13
|
+
this.apiUrl = 'https://api.cryptomus.com/v1';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createSignature(payload) {
|
|
17
|
+
const data = Buffer.from(JSON.stringify(payload)).toString('base64');
|
|
18
|
+
return crypto.createHash('md5').update(data + this.paymentKey).digest('hex');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async createPayment(options) {
|
|
22
|
+
const payload = {
|
|
23
|
+
merchant_id: this.merchantId,
|
|
24
|
+
order_id: options.orderId,
|
|
25
|
+
amount: options.amount,
|
|
26
|
+
currency: options.currency || 'USD',
|
|
27
|
+
network: options.network || 'ETH',
|
|
28
|
+
url_callback: options.callbackUrl,
|
|
29
|
+
url_return: options.returnUrl,
|
|
30
|
+
is_payment_multiple: false,
|
|
31
|
+
lifetime: options.lifetime || 3600,
|
|
32
|
+
to_currency: options.toCurrency || 'ETH'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const sign = this.createSignature(payload);
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const response = await axios.post(`${this.apiUrl}/payment`, payload, {
|
|
39
|
+
headers: {
|
|
40
|
+
'merchant': this.merchantId,
|
|
41
|
+
'sign': sign
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return response.data;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return error.response.data;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async getPaymentStatus(orderId) {
|
|
51
|
+
const payload = {
|
|
52
|
+
merchant_id: this.merchantId,
|
|
53
|
+
order_id: orderId
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const sign = this.createSignature(payload);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const response = await axios.post(`${this.apiUrl}/payment/status`, payload, {
|
|
60
|
+
headers: {
|
|
61
|
+
'merchant': this.merchantId,
|
|
62
|
+
'sign': sign
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return response.data;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
throw new Error(`Payment status query error: ${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async testWebhook(payload) {
|
|
72
|
+
const sign = this.createSignature(payload);
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const response = await axios.post(`${this.apiUrl}/test-webhook/payment`, payload, {
|
|
76
|
+
headers: {
|
|
77
|
+
'merchant': this.merchantId,
|
|
78
|
+
'sign': sign
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return response.data;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw new Error(`Test webhook error: ${error.message}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
verifyWebhook(payload, signature) {
|
|
89
|
+
if (payload?.sign) delete payload.sign;
|
|
90
|
+
const data = Buffer.from(JSON.stringify(payload)).toString('base64');
|
|
91
|
+
const hash = crypto.createHash('md5').update(data + this.paymentKey).digest('hex');
|
|
92
|
+
return hash === signature;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async handleCallback(callbackData) {
|
|
96
|
+
try {
|
|
97
|
+
if (!this.verifyWebhook(callbackData, callbackData.sign)) {
|
|
98
|
+
throw new Error("Cryptomus notification failed: invalid signature");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (callbackData.status === 'paid') {
|
|
102
|
+
return {
|
|
103
|
+
status: 'success',
|
|
104
|
+
orderId: callbackData.order_id,
|
|
105
|
+
uuid: callbackData.uuid,
|
|
106
|
+
amount: parseFloat(callbackData.amount),
|
|
107
|
+
payment_amount: parseFloat(callbackData.payment_amount),
|
|
108
|
+
payment_amount_usd: parseFloat(callbackData.payment_amount_usd),
|
|
109
|
+
currency: callbackData.currency,
|
|
110
|
+
paymentMethod: callbackData.payment_method,
|
|
111
|
+
network: callbackData.network
|
|
112
|
+
};
|
|
113
|
+
} else {
|
|
114
|
+
throw new Error(`Payment failed with status: ${callbackData.status}`);
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw new Error(`Error in Cryptomus callback handling: ${error.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = Cryptomus;
|
package/lib/payeer.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
const axios = require('axios');
|
|
3
|
+
|
|
4
|
+
class Payeer {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config || {};
|
|
7
|
+
const requiredFields = ['m_shop', 'm_key'];
|
|
8
|
+
for (let field of requiredFields) {
|
|
9
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
this.m_shop = config.m_shop;
|
|
13
|
+
this.m_key = config.m_key;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async createPayment(paymentDetails) {
|
|
17
|
+
try {
|
|
18
|
+
const requiredData = ['orderId', 'amount', 'currency', 'description'];
|
|
19
|
+
for (let data of requiredData) {
|
|
20
|
+
if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const m_sign = this.generateSignature(
|
|
24
|
+
paymentDetails.orderId,
|
|
25
|
+
paymentDetails.amount,
|
|
26
|
+
paymentDetails.currency,
|
|
27
|
+
Buffer.from(paymentDetails.description).toString('base64')
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const paymentUrl = `https://payeer.com/merchant/?m_shop=${this.m_shop}&m_orderid=${paymentDetails.orderId}&m_amount=${paymentDetails.amount}&m_curr=${paymentDetails.currency}&m_desc=${Buffer.from(paymentDetails.description).toString('base64')}&m_sign=${m_sign}&lang=${paymentDetails.lang || 'en'}`;
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
status: 'success',
|
|
34
|
+
data: {
|
|
35
|
+
url: paymentUrl,
|
|
36
|
+
orderId: paymentDetails.orderId,
|
|
37
|
+
amount: paymentDetails.amount,
|
|
38
|
+
currency: paymentDetails.currency
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
} catch (error) {
|
|
42
|
+
throw new Error(`Error in Payeer payment creation: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async handleCallback(callbackData) {
|
|
47
|
+
try {
|
|
48
|
+
const signHash = this.generatePaymentStatusSignature(callbackData);
|
|
49
|
+
|
|
50
|
+
if (callbackData.m_sign === signHash && callbackData.m_status === 'success') {
|
|
51
|
+
return {
|
|
52
|
+
status: 'success',
|
|
53
|
+
orderId: callbackData.m_orderid,
|
|
54
|
+
amount: callbackData.m_amount,
|
|
55
|
+
currency: callbackData.m_curr,
|
|
56
|
+
operationId: callbackData.m_operation_id,
|
|
57
|
+
paymentDate: callbackData.m_operation_pay_date
|
|
58
|
+
};
|
|
59
|
+
} else {
|
|
60
|
+
throw new Error('Payment validation failed');
|
|
61
|
+
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
throw new Error(`Error in Payeer callback handling: ${error.message}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
generateSignature(m_orderid, m_amount, m_curr, m_desc) {
|
|
68
|
+
const arHash = [
|
|
69
|
+
this.m_shop,
|
|
70
|
+
m_orderid,
|
|
71
|
+
m_amount,
|
|
72
|
+
m_curr,
|
|
73
|
+
m_desc,
|
|
74
|
+
this.m_key
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
return crypto.createHash('sha256')
|
|
78
|
+
.update(arHash.join(':'))
|
|
79
|
+
.digest('hex')
|
|
80
|
+
.toUpperCase();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
generatePaymentStatusSignature(paymentData) {
|
|
84
|
+
const arHash = [
|
|
85
|
+
paymentData.m_operation_id,
|
|
86
|
+
paymentData.m_operation_ps,
|
|
87
|
+
paymentData.m_operation_date,
|
|
88
|
+
paymentData.m_operation_pay_date,
|
|
89
|
+
paymentData.m_shop,
|
|
90
|
+
paymentData.m_orderid,
|
|
91
|
+
paymentData.m_amount,
|
|
92
|
+
paymentData.m_curr,
|
|
93
|
+
paymentData.m_desc,
|
|
94
|
+
paymentData.m_status
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
if (paymentData.m_params) {
|
|
98
|
+
arHash.push(paymentData.m_params);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
arHash.push(this.m_key);
|
|
102
|
+
|
|
103
|
+
return crypto.createHash('sha256')
|
|
104
|
+
.update(arHash.join(':'))
|
|
105
|
+
.digest('hex')
|
|
106
|
+
.toUpperCase();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = Payeer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quickpos",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"main": "app.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"paynet",
|
|
24
24
|
"stripe",
|
|
25
25
|
"paypal",
|
|
26
|
-
"shopier"
|
|
26
|
+
"shopier",
|
|
27
|
+
"cryptomus",
|
|
28
|
+
"payeer"
|
|
27
29
|
],
|
|
28
30
|
"repository": {
|
|
29
31
|
"type": "git",
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 💳 QuickPos 🚀
|
|
2
2
|
|
|
3
|
-
QuickPos, farklı ödeme sağlayıcılarını destekleyen güçlü bir ödeme entegrasyon modülüdür. Şu anda PayTR sağlayıcısını desteklemektedir ve gelecekte birçok yeni sağlayıcı ile özellik eklemeyi planlamaktadır. Yol haritamıza göz atarak gelecek özellikleri keşfedebilirsiniz.
|
|
3
|
+
QuickPos, farklı ödeme sağlayıcılarını destekleyen güçlü bir ödeme entegrasyon modülüdür. Şu anda PayTR, Shopier, Cryptomus, Payeer sağlayıcısını desteklemektedir ve gelecekte birçok yeni sağlayıcı ile özellik eklemeyi planlamaktadır. Yol haritamıza göz atarak gelecek özellikleri keşfedebilirsiniz.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -134,6 +134,8 @@ const quickPos = new QuickPos({
|
|
|
134
134
|
|
|
135
135
|
- PayTR
|
|
136
136
|
- Shopier
|
|
137
|
+
- Cryptomus
|
|
138
|
+
- Payeer
|
|
137
139
|
|
|
138
140
|
---
|
|
139
141
|
|
|
@@ -149,6 +151,9 @@ const quickPos = new QuickPos({
|
|
|
149
151
|
### İlerleme Durumu
|
|
150
152
|
|
|
151
153
|
- [x] PayTR entegrasyonu
|
|
154
|
+
- [x] Shopier entegrasyonu
|
|
155
|
+
- [x] Cryptomus entegrasyonu
|
|
156
|
+
- [x] Payeer entegrasyonu
|
|
152
157
|
- [ ] İyzico entegrasyonu
|
|
153
158
|
- [ ] Vallet entegrasyonu
|
|
154
159
|
- [ ] Shipy entegrasyonu
|