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.
Files changed (131) hide show
  1. package/PROVIDERS-DETAILS.md +1544 -0
  2. package/examples/example-2checkout.js +78 -0
  3. package/examples/example-bitpay.js +83 -0
  4. package/examples/example-cardcom.js +80 -0
  5. package/examples/example-cashfree.js +109 -0
  6. package/examples/example-checkout.js +85 -0
  7. package/examples/example-coingate.js +101 -0
  8. package/examples/example-coinpayments.js +89 -0
  9. package/examples/example-doku.js +27 -0
  10. package/examples/example-epay.js +64 -0
  11. package/examples/example-epoint.js +91 -0
  12. package/examples/example-freekassa.js +26 -0
  13. package/examples/example-heleket.js +139 -0
  14. package/examples/example-konnect.js +227 -0
  15. package/examples/example-midtrans.js +80 -0
  16. package/examples/example-noonpayments.js +297 -0
  17. package/examples/example-nowpayments.js +289 -0
  18. package/examples/example-omise.js +27 -0
  19. package/examples/example-paycom.js +82 -0
  20. package/{example-paydisini.js → examples/example-paydisini.js} +1 -1
  21. package/examples/example-payid19.js +87 -0
  22. package/examples/example-paykun.js +29 -0
  23. package/examples/example-payme.js +202 -0
  24. package/examples/example-paymentwall.js +201 -0
  25. package/examples/example-paynet.js +104 -0
  26. package/examples/example-paynettr.js +18 -0
  27. package/examples/example-payoneer.js +74 -0
  28. package/examples/example-payop.js +351 -0
  29. package/examples/example-paypal.js +200 -0
  30. package/examples/example-payriff.js +89 -0
  31. package/examples/example-paysend.js +81 -0
  32. package/examples/example-payspace.js +103 -0
  33. package/examples/example-payssion.js +27 -0
  34. package/examples/example-paytabs.js +28 -0
  35. package/examples/example-paytm.js +78 -0
  36. package/examples/example-payuindia.js +108 -0
  37. package/examples/example-payulatam.js +75 -0
  38. package/examples/example-phonepe.js +27 -0
  39. package/examples/example-picpay.js +27 -0
  40. package/examples/example-plisio.js +84 -0
  41. package/examples/example-portwallet.js +90 -0
  42. package/examples/example-primepayments.js +250 -0
  43. package/examples/example-razorpay.js +30 -0
  44. package/examples/example-senangpay.js +28 -0
  45. package/examples/example-shurjopay.js +94 -0
  46. package/examples/example-toyyibpay.js +80 -0
  47. package/examples/example-tripay.js +89 -0
  48. package/examples/example-unitpay.js +26 -0
  49. package/examples/example-urway.js +28 -0
  50. package/examples/example-volet.js +80 -0
  51. package/examples/example-xendit.js +28 -0
  52. package/examples/example-yallapay.js +253 -0
  53. package/examples/example-yookassa.js +27 -0
  54. package/examples/example-youcanpay.js +28 -0
  55. package/examples/example-zarinpal.js +98 -0
  56. package/{example.js → examples/example.js} +1 -1
  57. package/lib/2checkout.js +165 -0
  58. package/lib/amazonpay.js +161 -0
  59. package/lib/bitpay.js +122 -0
  60. package/lib/cardcom.js +193 -0
  61. package/lib/cashfree.js +184 -0
  62. package/lib/checkout.js +248 -0
  63. package/lib/coinbase.js +150 -0
  64. package/lib/coingate.js +137 -0
  65. package/lib/coinpayments.js +245 -0
  66. package/lib/doku.js +173 -0
  67. package/lib/epay.js +175 -0
  68. package/lib/epoint.js +162 -0
  69. package/lib/freekassa.js +128 -0
  70. package/lib/heleket.js +67 -1
  71. package/lib/instamojo.js +158 -0
  72. package/lib/konnect.js +211 -0
  73. package/lib/midtrans.js +227 -0
  74. package/lib/noonpayments.js +650 -0
  75. package/lib/nowpayments.js +311 -0
  76. package/lib/omise.js +150 -0
  77. package/lib/paddle.js +180 -0
  78. package/lib/paycom.js +216 -0
  79. package/lib/payid19.js +211 -0
  80. package/lib/paykun.js +144 -0
  81. package/lib/payme.js +302 -0
  82. package/lib/paymentwall.js +205 -0
  83. package/lib/paynet.js +186 -0
  84. package/lib/paynettr.js +165 -0
  85. package/lib/payoneer.js +128 -0
  86. package/lib/payop.js +256 -0
  87. package/lib/paypal.js +542 -0
  88. package/lib/payriff.js +148 -0
  89. package/lib/paysend.js +189 -0
  90. package/lib/payspace.js +168 -0
  91. package/lib/payssion.js +177 -0
  92. package/lib/paytabs.js +145 -0
  93. package/lib/paytm.js +253 -0
  94. package/lib/payuindia.js +162 -0
  95. package/lib/payulatam.js +179 -0
  96. package/lib/perfectmoney.js +143 -0
  97. package/lib/phonepe.js +174 -0
  98. package/lib/picpay.js +119 -0
  99. package/lib/plisio.js +234 -0
  100. package/lib/portwallet.js +152 -0
  101. package/lib/primepayments.js +256 -0
  102. package/lib/razorpay.js +205 -0
  103. package/lib/senangpay.js +130 -0
  104. package/lib/shurjopay.js +159 -0
  105. package/lib/toyyibpay.js +151 -0
  106. package/lib/tripay.js +220 -0
  107. package/lib/unitpay.js +223 -0
  108. package/lib/urway.js +182 -0
  109. package/lib/volet.js +147 -0
  110. package/lib/xendit.js +206 -0
  111. package/lib/yallapay.js +279 -0
  112. package/lib/yookassa.js +193 -0
  113. package/lib/youcanpay.js +124 -0
  114. package/lib/zarinpal.js +157 -0
  115. package/package.json +138 -64
  116. package/readme.md +348 -105
  117. package/test.js +492 -0
  118. package/example-heleket.js +0 -83
  119. package/lib/vallet.js +0 -22
  120. /package/{example-anypay.js → examples/example-anypay.js} +0 -0
  121. /package/{example-bufpay.js → examples/example-bufpay.js} +0 -0
  122. /package/{example-cryptomus.js → examples/example-cryptomus.js} +0 -0
  123. /package/{example-esnekpos.js → examples/example-esnekpos.js} +0 -0
  124. /package/{example-fedapay.js → examples/example-fedapay.js} +0 -0
  125. /package/{example-iyzico.js → examples/example-iyzico.js} +0 -0
  126. /package/{example-papara.js → examples/example-papara.js} +0 -0
  127. /package/{example-payeer.js → examples/example-payeer.js} +0 -0
  128. /package/{example-paymaya.js → examples/example-paymaya.js} +0 -0
  129. /package/{example-shopier.js → examples/example-shopier.js} +0 -0
  130. /package/{ipaymu.js → examples/ipaymu.js} +0 -0
  131. /package/{oderopay.js → examples/oderopay.js} +0 -0
@@ -0,0 +1,253 @@
1
+ const YallaPayService = require('./lib/yallapay');
2
+ const express = require('express');
3
+ const bodyParser = require('body-parser');
4
+ const app = express();
5
+
6
+ // Body parser middleware
7
+ app.use(bodyParser.json());
8
+ app.use(bodyParser.urlencoded({ extended: true }));
9
+
10
+ // Tüm istekleri loglama
11
+ app.use((req, res, next) => {
12
+ console.log(`[${new Date().toISOString()}] Gelen istek: ${req.method} ${req.url}`);
13
+ if (Object.keys(req.query).length > 0) {
14
+ console.log('Query:', JSON.stringify(req.query));
15
+ }
16
+ if (req.body && Object.keys(req.body).length > 0) {
17
+ console.log('Body:', JSON.stringify(req.body));
18
+ }
19
+ next();
20
+ });
21
+
22
+ // YallaPay konfigürasyonu - kendi API anahtarınızı kullanmalısınız
23
+ const yallapayConfig = {
24
+ privateKey: 'YOUR_PRIVATE_KEY', // YallaPay Merchant Dashboard'dan alınır
25
+ currency: 'USD', // İşlem para birimi
26
+ webhookSecret: 'YOUR_WEBHOOK_SECRET_KEY', // YallaPay Webhook Dashboard'dan alınır
27
+ debug: true // Debug modu açık (geliştirme sırasında)
28
+ };
29
+
30
+ // YallaPay servisini başlat
31
+ const yallapay = new YallaPayService(yallapayConfig);
32
+
33
+ // Ödeme oluşturma örneği
34
+ async function createPaymentExample() {
35
+ try {
36
+ console.log('Yeni ödeme isteği oluşturuluyor...');
37
+
38
+ const paymentResult = await yallapay.createPayment({
39
+ amount: 100, // Ödeme tutarı
40
+ purpose: 'Premium Üyelik', // Ödeme açıklaması
41
+ external_id: 'siparis-' + Date.now(), // Sipariş ID'si
42
+ is_fallback: '1', // Fallback URL kullan
43
+ fallback_url: 'https://test.quickpanel.net/success', // Başarılı ödeme dönüş sayfası
44
+ generateQr: true // QR kod oluştur
45
+ });
46
+
47
+ console.log('Ödeme bağlantısı oluşturuldu:');
48
+ console.log(JSON.stringify(paymentResult, null, 2));
49
+
50
+ return paymentResult;
51
+ } catch (error) {
52
+ console.error('Ödeme oluşturma hatası:', error.message);
53
+ return { status: 'error', message: error.message };
54
+ }
55
+ }
56
+
57
+ // Örnek işlem doğrulama
58
+ async function verifyTransactionExample(transactionId) {
59
+ try {
60
+ console.log(`${transactionId} işlemi doğrulanıyor...`);
61
+
62
+ const result = await yallapay.verifyTransaction(transactionId);
63
+ console.log('İşlem durumu:', result);
64
+
65
+ return result;
66
+ } catch (error) {
67
+ console.error('İşlem doğrulama hatası:', error.message);
68
+ return { status: 'error', message: error.message };
69
+ }
70
+ }
71
+
72
+ // Webhook endpoint
73
+ app.post('/webhook/yallapay', async (req, res) => {
74
+ console.log('🔔 YallaPay webhook çağrısı alındı!');
75
+
76
+ try {
77
+ // Webhook verilerini işle - artık webhook secret'ı ayrıca vermiyoruz
78
+ const result = await yallapay.handleWebhook(req.body);
79
+ console.log('✅ Ödeme durumu:', result);
80
+
81
+ if (result.status === 'success') {
82
+ console.log(`✅ Başarılı Ödeme: Sipariş ${result.orderId} için ${result.amount} ${result.currency} ödeme alındı`);
83
+
84
+ // Burada başarılı ödeme işlemleri yapılabilir
85
+ // - Veritabanı güncelleme
86
+ // - Sipariş durumu değiştirme
87
+ // - Kullanıcı hesabını aktifleştirme vb.
88
+ } else if (result.status === 'refunded') {
89
+ console.log(`♻️ İade Edilen Ödeme: Sipariş ${result.orderId} için ${result.amount} ${result.currency} iade edildi`);
90
+ } else if (result.status === 'failed') {
91
+ console.log(`❌ Başarısız Ödeme: Sipariş ${result.orderId}`);
92
+ }
93
+
94
+ // YallaPay'e başarılı yanıt gönder
95
+ res.status(200).json({ status: 'success' });
96
+ } catch (error) {
97
+ console.error('⚠️ Webhook işleme hatası:', error.message);
98
+ // YallaPay'e hata yanıtı gönder
99
+ res.status(400).json({ status: 'error', message: error.message });
100
+ }
101
+ });
102
+
103
+ // Başarılı ödeme dönüş sayfası
104
+ app.get('/success', (req, res) => {
105
+ res.send(`
106
+ <html>
107
+ <head>
108
+ <title>Ödeme Başarılı</title>
109
+ <style>
110
+ body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
111
+ .success { color: green; font-size: 24px; margin-bottom: 20px; }
112
+ </style>
113
+ </head>
114
+ <body>
115
+ <div class="success">Ödemeniz başarıyla tamamlandı!</div>
116
+ <p>Teşekkür ederiz. Siparişiniz işleme alındı.</p>
117
+ <pre>${JSON.stringify(req.query, null, 2)}</pre>
118
+ </body>
119
+ </html>
120
+ `);
121
+ });
122
+
123
+ // İşlem doğrulama endpoint'i
124
+ app.get('/verify/:transactionId', async (req, res) => {
125
+ try {
126
+ const result = await verifyTransactionExample(req.params.transactionId);
127
+ res.json(result);
128
+ } catch (error) {
129
+ res.status(400).json({ status: 'error', message: error.message });
130
+ }
131
+ });
132
+
133
+ // Ana sayfa
134
+ app.get('/', (req, res) => {
135
+ res.send(`
136
+ <html>
137
+ <head>
138
+ <title>YallaPay Ödeme Testi</title>
139
+ <style>
140
+ body { font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
141
+ button { padding: 10px 15px; background: #0066ff; color: white; border: none; border-radius: 4px; cursor: pointer; }
142
+ .container { margin-top: 20px; }
143
+ pre { background: #f4f4f4; padding: 10px; border-radius: 4px; overflow: auto; }
144
+ .error { color: red; }
145
+ .verify-form { margin-top: 30px; padding: 15px; border: 1px solid #ddd; border-radius: 4px; }
146
+ input { padding: 8px; width: 300px; }
147
+ </style>
148
+ </head>
149
+ <body>
150
+ <h1>YallaPay Ödeme Testi</h1>
151
+ <p>YallaPay API ile ödeme bağlantısı oluşturma testi.</p>
152
+ <button onclick="createPayment()">Yeni Ödeme Oluştur</button>
153
+
154
+ <div class="container" id="result">
155
+ <p>Bu test için aşağıdaki bilgileri kullanıyoruz:</p>
156
+ <pre>Private Key: ${yallapayConfig.privateKey.substring(0, 10)}...
157
+ Para Birimi: ${yallapayConfig.currency}</pre>
158
+ </div>
159
+
160
+ <div class="verify-form">
161
+ <h3>İşlem Doğrulama</h3>
162
+ <p>YallaPay işlem ID'si ile ödeme durumunu kontrol edin:</p>
163
+ <input type="text" id="transactionId" placeholder="İşlem ID'si girin">
164
+ <button onclick="verifyTransaction()">Doğrula</button>
165
+ <div id="verifyResult"></div>
166
+ </div>
167
+
168
+ <script>
169
+ function createPayment() {
170
+ document.getElementById('result').innerHTML = '<p>Ödeme oluşturuluyor...</p>';
171
+
172
+ fetch('/create-payment')
173
+ .then(response => response.json())
174
+ .then(data => {
175
+ if (data.status === 'success') {
176
+ let html = \`
177
+ <h3>Ödeme Bağlantısı Oluşturuldu</h3>
178
+ <p>İşlem ID: \${data.data.id}</p>
179
+ <p>Ödeme URL: <a href="\${data.data.url}" target="_blank">\${data.data.url}</a></p>
180
+ \`;
181
+
182
+ if (data.data.fallbackUrl) {
183
+ html += \`<p>Dönüş URL: \${data.data.fallbackUrl}</p>\`;
184
+ }
185
+
186
+ if (data.data.qr) {
187
+ html += \`<p>QR Kod:</p><img src="\${data.data.qr}" width="200" />\`;
188
+ }
189
+
190
+ document.getElementById('result').innerHTML = html;
191
+ } else {
192
+ document.getElementById('result').innerHTML = '<p class="error">Hata: ' + data.message + '</p>';
193
+ }
194
+ })
195
+ .catch(error => {
196
+ document.getElementById('result').innerHTML = '<p class="error">Hata: ' + error + '</p>';
197
+ });
198
+ }
199
+
200
+ function verifyTransaction() {
201
+ const transactionId = document.getElementById('transactionId').value.trim();
202
+ if (!transactionId) {
203
+ alert('Lütfen bir işlem ID\'si girin');
204
+ return;
205
+ }
206
+
207
+ document.getElementById('verifyResult').innerHTML = '<p>İşlem doğrulanıyor...</p>';
208
+
209
+ fetch(\`/verify/\${transactionId}\`)
210
+ .then(response => response.json())
211
+ .then(data => {
212
+ let html = '<pre>' + JSON.stringify(data, null, 2) + '</pre>';
213
+ document.getElementById('verifyResult').innerHTML = html;
214
+ })
215
+ .catch(error => {
216
+ document.getElementById('verifyResult').innerHTML = '<p class="error">Hata: ' + error + '</p>';
217
+ });
218
+ }
219
+ </script>
220
+ </body>
221
+ </html>
222
+ `);
223
+ });
224
+
225
+ // API endpoint - yeni ödeme oluşturma
226
+ app.get('/create-payment', async (req, res) => {
227
+ try {
228
+ const result = await createPaymentExample();
229
+ res.json(result);
230
+ } catch (error) {
231
+ res.status(400).json({ status: 'error', message: error.message });
232
+ }
233
+ });
234
+
235
+ // Test sunucusunu başlat
236
+ const PORT = process.env.PORT || 3000;
237
+ app.listen(PORT, () => {
238
+ console.log(`🚀 Test sunucusu başlatıldı: http://localhost:${PORT}`);
239
+ console.log(`🔔 Webhook URL: http://localhost:${PORT}/webhook/yallapay`);
240
+ console.log('⚠️ YallaPay Entegrasyon Ayarları:');
241
+ console.log(` - Private Key: ${yallapayConfig.privateKey.substring(0, 10)}...`);
242
+ console.log(` - Para Birimi: ${yallapayConfig.currency}`);
243
+ console.log(` - Webhook Secret: ${yallapayConfig.webhookSecret ? (yallapayConfig.webhookSecret.substring(0, 10) + '...') : 'Ayarlanmadı'}`);
244
+
245
+ console.log('⚠️ Not: Gerçek ortamda, webhook URL\'inizi YallaPay panelinde ayarlayın');
246
+ console.log('⚠️ Ayrıca, example-yallapay.js dosyasındaki private key ve webhook secret\'ı kendi değerlerinizle değiştirmeyi unutmayın');
247
+ });
248
+
249
+ // Sunucuyu kapatmak için CTRL+C
250
+ process.on('SIGINT', () => {
251
+ console.log('Test sunucusu kapatılıyor...');
252
+ process.exit(0);
253
+ });
@@ -0,0 +1,27 @@
1
+ const YooKassaClient = require('../lib/yookassa');
2
+
3
+ const client = new YooKassaClient({
4
+ shopId: 'YOUR_SHOP_ID',
5
+ secretKey: 'YOUR_SECRET_KEY'
6
+ });
7
+
8
+ async function example() {
9
+ try {
10
+ const payment = await client.createPayment({
11
+ amount: 1000,
12
+ orderId: 'TEST-001',
13
+ currency: 'RUB',
14
+ callback_link: 'https://yoursite.com/callback',
15
+ description: 'Test Payment',
16
+ email: 'customer@example.com',
17
+ phone: '+79001234567'
18
+ });
19
+
20
+ console.log('Payment URL:', payment.data.url);
21
+ console.log('Payment ID:', payment.data.id);
22
+ } catch (error) {
23
+ console.error('Error:', error.message);
24
+ }
25
+ }
26
+
27
+ example();
@@ -0,0 +1,28 @@
1
+ const YouCanPayClient = require('../lib/youcanpay');
2
+
3
+ const client = new YouCanPayClient({
4
+ privateKey: 'YOUR_PRIVATE_KEY',
5
+ publicKey: 'YOUR_PUBLIC_KEY',
6
+ sandbox: true
7
+ });
8
+
9
+ async function example() {
10
+ try {
11
+ const payment = await client.createPayment({
12
+ amount: 100,
13
+ orderId: 'TEST-001',
14
+ currency: 'MAD',
15
+ callback_link: 'https://yoursite.com/callback',
16
+ name: 'Hassan Alaoui',
17
+ email: 'hassan@example.com',
18
+ phone: '+212600000000'
19
+ });
20
+
21
+ console.log('Payment URL:', payment.data.url);
22
+ console.log('Token:', payment.data.token);
23
+ } catch (error) {
24
+ console.error('Error:', error.message);
25
+ }
26
+ }
27
+
28
+ example();
@@ -0,0 +1,98 @@
1
+ const express = require('express');
2
+ const bodyParser = require('body-parser');
3
+ const QuickPos = require('./app');
4
+
5
+ const app = express();
6
+ app.use(bodyParser.urlencoded({ extended: true }));
7
+ app.use(bodyParser.json());
8
+
9
+ const quickPos = new QuickPos({
10
+ providers: {
11
+ zarinpal: {
12
+ merchantId: 'your-merchant-id',
13
+ sandbox: true // Set to false for production
14
+ }
15
+ },
16
+ });
17
+
18
+ app.use(quickPos.middleware());
19
+
20
+ // Payment form
21
+ app.get('/', (req, res) => {
22
+ res.send(`
23
+ <h1>Zarinpal Payment Example (Iran)</h1>
24
+ <form action="/payment/zarinpal" method="post">
25
+ <input type="text" name="amount" placeholder="Amount (Toman)" required>
26
+ <input type="email" name="email" placeholder="Email" required>
27
+ <input type="text" name="mobile" placeholder="Mobile" required>
28
+ <input type="text" name="orderId" placeholder="Order ID" required>
29
+ <input type="text" name="description" placeholder="Description" required>
30
+ <button type="submit">Pay with Zarinpal</button>
31
+ </form>
32
+ `);
33
+ });
34
+
35
+ // Create payment
36
+ app.post('/payment/:provider', async (req, res) => {
37
+ const { provider } = req.params;
38
+
39
+ if (!req.quickPos[provider]) {
40
+ return res.status(400).json({ error: 'Invalid payment provider' });
41
+ }
42
+
43
+ try {
44
+ const result = await req.quickPos[provider].createPayment({
45
+ amount: req.body.amount,
46
+ description: req.body.description,
47
+ email: req.body.email,
48
+ mobile: req.body.mobile,
49
+ orderId: req.body.orderId,
50
+ callback_link: `http://localhost:3000/payment-callback/${provider}`
51
+ });
52
+
53
+ if (result.status === 'success') {
54
+ res.json({
55
+ success: true,
56
+ redirectUrl: result.data.url,
57
+ authority: result.data.authority
58
+ });
59
+ } else {
60
+ res.status(400).json(result);
61
+ }
62
+ } catch (error) {
63
+ res.status(500).json({ error: error.message });
64
+ }
65
+ });
66
+
67
+ // Payment callback
68
+ app.get('/payment-callback/:provider', async (req, res) => {
69
+ const { provider } = req.params;
70
+ const authority = req.query.Authority;
71
+ const status = req.query.Status;
72
+
73
+ if (status === 'OK') {
74
+ try {
75
+ // You need to verify the payment with the amount stored in your database
76
+ const amount = 1000; // Get this from your database based on authority
77
+
78
+ const result = await quickPos.providers[provider].verifyPayment(authority, amount);
79
+ console.log('Payment verified:', result);
80
+
81
+ res.send(`
82
+ <h1>Payment Successful!</h1>
83
+ <p>Reference ID: ${result.data.refId}</p>
84
+ <p>Authority: ${authority}</p>
85
+ `);
86
+ } catch (error) {
87
+ res.send(`<h1>Payment Verification Failed!</h1><p>${error.message}</p>`);
88
+ }
89
+ } else {
90
+ res.send('<h1>Payment Cancelled!</h1>');
91
+ }
92
+ });
93
+
94
+ const PORT = process.env.PORT || 3000;
95
+ app.listen(PORT, () => {
96
+ console.log(`Server is running on port ${PORT}`);
97
+ console.log(`Open http://localhost:${PORT} to test`);
98
+ });
@@ -1,6 +1,6 @@
1
1
  const express = require('express');
2
2
  const bodyParser = require('body-parser');
3
- const QuickPos = require('./app');
3
+ const QuickPos = require('../app');
4
4
 
5
5
  const app = express();
6
6
  app.use(bodyParser.urlencoded({ extended: true }));
@@ -0,0 +1,165 @@
1
+ const axios = require('axios');
2
+ const crypto = require('crypto');
3
+
4
+ class TwoCheckoutClient {
5
+ constructor(config) {
6
+ const requiredFields = ['merchantCode', 'secretKey'];
7
+ for (let field of requiredFields) {
8
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
9
+ }
10
+
11
+ this.merchantCode = config.merchantCode;
12
+ this.secretKey = config.secretKey;
13
+ this.baseURL = config.sandbox
14
+ ? 'https://api.sandbox.2checkout.com'
15
+ : 'https://api.2checkout.com';
16
+
17
+ this.client = axios.create({
18
+ baseURL: this.baseURL,
19
+ headers: {
20
+ 'Content-Type': 'application/json'
21
+ }
22
+ });
23
+ }
24
+
25
+ generateSignature(params) {
26
+ const signatureString = Object.keys(params)
27
+ .sort()
28
+ .map(key => params[key].length + params[key])
29
+ .join('');
30
+
31
+ return crypto
32
+ .createHmac('sha256', this.secretKey)
33
+ .update(signatureString)
34
+ .digest('hex');
35
+ }
36
+
37
+ async createPayment(options) {
38
+ try {
39
+ const orderId = options.orderId || `ORDER-${Date.now()}`;
40
+ const timestamp = new Date().toISOString();
41
+
42
+ const params = {
43
+ 'merchant': this.merchantCode,
44
+ 'dynamic': '1',
45
+ 'return-url': options.successUrl || options.callback_link,
46
+ 'return-type': 'redirect',
47
+ 'expiration': timestamp,
48
+ 'order-ext-ref': orderId,
49
+ 'item-ext-ref': orderId,
50
+ 'customer-ext-ref': options.customerId || '',
51
+ 'currency': options.currency || 'USD',
52
+ 'language': options.language || 'en',
53
+ 'test': options.sandbox ? '1' : '0',
54
+ 'prod-name[0]': options.name || 'Payment',
55
+ 'prod-type[0]': 'PRODUCT',
56
+ 'prod-price[0]': parseFloat(options.amount).toString(),
57
+ 'prod-qty[0]': '1',
58
+ 'prod-description[0]': options.description || '',
59
+ 'customer-email': options.email || '',
60
+ 'customer-name': options.customerName || ''
61
+ };
62
+
63
+ const signature = this.generateSignature(params);
64
+ params.signature = signature;
65
+
66
+ // Create form URL
67
+ const formParams = new URLSearchParams(params);
68
+ const paymentUrl = `https://secure.2checkout.com/order/checkout.php?${formParams.toString()}`;
69
+
70
+ return {
71
+ status: 'success',
72
+ data: {
73
+ url: paymentUrl,
74
+ orderId: orderId,
75
+ params: params
76
+ }
77
+ };
78
+ } catch (error) {
79
+ throw new Error(`Payment creation error: ${error.message}`);
80
+ }
81
+ }
82
+
83
+ async handleCallback(callbackData) {
84
+ try {
85
+ const verification = await this.verifyCallback(callbackData);
86
+
87
+ if (!verification.status) {
88
+ throw new Error(verification.error.message);
89
+ }
90
+
91
+ const data = verification.data;
92
+
93
+ // Status mapping
94
+ const statusMapping = {
95
+ 'COMPLETE': 'success',
96
+ 'PENDING': 'pending',
97
+ 'REFUND': 'refunded',
98
+ 'REVERSED': 'failed'
99
+ };
100
+
101
+ return {
102
+ status: statusMapping[data.order_status] || 'unknown',
103
+ orderId: data['order-ext-ref'] || data.order_number,
104
+ transactionId: data.order_number,
105
+ amount: parseFloat(data.invoice_list_amount || data.order_amount),
106
+ currency: data.list_currency,
107
+ paymentStatus: data.order_status,
108
+ invoiceId: data.invoice_id
109
+ };
110
+ } catch (error) {
111
+ throw new Error(`Error in 2Checkout callback handling: ${error.message}`);
112
+ }
113
+ }
114
+
115
+ async verifyCallback(data) {
116
+ try {
117
+ const hash = data.hash || data.HASH;
118
+
119
+ if (!hash) {
120
+ return {
121
+ status: false,
122
+ error: {
123
+ code: 400,
124
+ message: 'Hash not found in callback data'
125
+ }
126
+ };
127
+ }
128
+
129
+ // Verify IPN hash
130
+ const params = { ...data };
131
+ delete params.hash;
132
+ delete params.HASH;
133
+
134
+ const calculatedHash = crypto
135
+ .createHmac('md5', this.secretKey)
136
+ .update(JSON.stringify(params))
137
+ .digest('hex');
138
+
139
+ if (hash !== calculatedHash) {
140
+ return {
141
+ status: false,
142
+ error: {
143
+ code: 401,
144
+ message: 'Invalid hash'
145
+ }
146
+ };
147
+ }
148
+
149
+ return {
150
+ status: true,
151
+ data: data
152
+ };
153
+ } catch (error) {
154
+ return {
155
+ status: false,
156
+ error: {
157
+ code: 500,
158
+ message: error.message
159
+ }
160
+ };
161
+ }
162
+ }
163
+ }
164
+
165
+ module.exports = TwoCheckoutClient;