quickpos 1.0.907 → 1.0.909

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.
@@ -0,0 +1,62 @@
1
+ const Heleket = require('./lib/heleket');
2
+ const QuickPos = require('./app');
3
+
4
+
5
+
6
+ const quickPos = new QuickPos({
7
+ providers: {
8
+ heleket: {
9
+ merchantId: '6764fdb7-7a2c-4599-962e-',
10
+ apiKey: ''
11
+ }
12
+ }
13
+ });
14
+
15
+ let heleket = quickPos.providers['heleket'];
16
+
17
+ // Örnek fatura oluşturma
18
+ async function createSampleInvoice() {
19
+ try {
20
+ const result = await heleket.createInvoice({
21
+ amount: "20",
22
+ currency: "USDT",
23
+ order_id: "test-1234",
24
+ network: "tron"
25
+ });
26
+
27
+ console.log('Fatura oluşturuldu:', result);
28
+ } catch (error) {
29
+ console.error('Fatura oluşturulurken hata:', error.message);
30
+ }
31
+ }
32
+
33
+ // Örnek ödeme hizmetlerini getirme
34
+ async function getServices() {
35
+ try {
36
+ const services = await heleket.getPaymentServices();
37
+ console.log('Ödeme hizmetleri:', services);
38
+ } catch (error) {
39
+ console.error('Hizmetler alınırken hata:', error.message);
40
+ }
41
+ }
42
+
43
+ // Webhook imzasını doğrulama örneği
44
+ function verifyWebhook() {
45
+ const webhookData = {
46
+ order_id: 'test-123',
47
+ status: 'completed',
48
+ amount: '20',
49
+ currency: 'USDT',
50
+ sign: 'example-signature-here'
51
+ };
52
+
53
+ const isValid = heleket.verifyWebhookSignature(webhookData);
54
+ console.log('Webhook geçerli mi:', isValid);
55
+ }
56
+
57
+ // Örnek fonksiyonları çalıştır
58
+ (async () => {
59
+ await createSampleInvoice();
60
+ // await getServices();
61
+ verifyWebhook();
62
+ })();
@@ -0,0 +1,354 @@
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
+ // QuickPos sağlayıcı yapılandırması
10
+ const quickPos = new QuickPos({
11
+ providers: {
12
+ paydisini: {
13
+ apiKey: 'YOUR_API_KEY', // Gerçek API anahtarınızla değiştirin
14
+ debug: true // Geliştirme modunda hata ayıklama için
15
+ }
16
+ }
17
+ });
18
+
19
+ // QuickPos middleware'ini ekle
20
+ app.use(quickPos.middleware());
21
+
22
+ // Ana sayfa - Ödeme formu
23
+ app.get('/', (req, res) => {
24
+ res.send(`
25
+ <h1>Paydisini Ödeme Testi</h1>
26
+ <form action="/create-payment" method="post">
27
+ <div>
28
+ <label>Tutar:</label>
29
+ <input type="text" name="amount" value="10000" required>
30
+ </div>
31
+ <div>
32
+ <label>Benzersiz Kod:</label>
33
+ <input type="text" name="uniqueCode" value="ORD${Date.now().toString().substring(5)}" required>
34
+ </div>
35
+ <div>
36
+ <label>Servis:</label>
37
+ <select name="service" required>
38
+ <option value="1">Virtual Account Bank BCA (Min: 10,000 IDR)</option>
39
+ <option value="2">Virtual Account Bank BRI (Min: 10,000 IDR)</option>
40
+ <option value="3">Virtual Account Bank CIMB (Min: 10,000 IDR)</option>
41
+ <option value="4">Virtual Account Bank BNI (Min: 10,000 IDR)</option>
42
+ <option value="5">Virtual Account Bank MANDIRI (Min: 10,000 IDR)</option>
43
+ <option value="7">Virtual Account Bank Permata (Min: 10,000 IDR)</option>
44
+ <option value="8">Virtual Account BANK DANAMON (Min: 10,000 IDR)</option>
45
+ <option value="9">Virtual Account BANK BSI (Min: 10,000 IDR)</option>
46
+ <option value="10">Virtual Account BANK BNC - Neo Commerce (Min: 10,000 IDR)</option>
47
+ <option value="11" selected>QRIS Merchant PayDisini (Min: 100 IDR)</option>
48
+ <option value="12">OVO (Min: 1,000 IDR)</option>
49
+ <option value="13">DANA (Min: 1,000 IDR)</option>
50
+ <option value="14">LINKAJA (Min: 1,000 IDR)</option>
51
+ <option value="17">QRIS Custom [Perlu KTP] (Min: 100 IDR)</option>
52
+ <option value="18">ALFAMART (Min: 10,000 IDR)</option>
53
+ <option value="19">INDOMARET (Min: 10,000 IDR)</option>
54
+ <option value="20">QRIS Merchant PayDisini by Danamon (Min: 1,000 IDR)</option>
55
+ <option value="21">Virtual Account Bank OCBC (Min: 10,000 IDR)</option>
56
+ <option value="22">Virtual Account Bank Muamalat (Min: 10,000 IDR)</option>
57
+ </select>
58
+ </div>
59
+ <div>
60
+ <label>Not:</label>
61
+ <input type="text" name="note" value="Test ödeme" required>
62
+ </div>
63
+ <div>
64
+ <label>Geçerlilik Süresi (saniye):</label>
65
+ <input type="number" name="validTime" value="1800">
66
+ </div>
67
+ <div>
68
+ <label>Ücret Tipi:</label>
69
+ <select name="typeFee">
70
+ <option value="1">Müşteri Öder</option>
71
+ <option value="2">Satıcı Öder</option>
72
+ </select>
73
+ </div>
74
+ <div>
75
+ <label>Ödeme Kılavuzu:</label>
76
+ <select name="paymentGuide">
77
+ <option value="TRUE">Göster</option>
78
+ <option value="FALSE">Gösterme</option>
79
+ </select>
80
+ </div>
81
+ <div>
82
+ <label>Dönüş URL'i:</label>
83
+ <input type="text" name="returnUrl" value="http://${req.headers.host}/payment-return">
84
+ </div>
85
+ <button type="submit">Ödeme Oluştur</button>
86
+ </form>
87
+
88
+ <hr>
89
+
90
+ <h3>Diğer İşlemler</h3>
91
+ <ul>
92
+ <li><a href="/services">Servis Listesi</a></li>
93
+ <li><a href="/balance">Bakiye Sorgula</a></li>
94
+ </ul>
95
+
96
+ <hr>
97
+
98
+ <h3>Ödeme Kanalları Referans Bilgisi</h3>
99
+ <table border="1" cellpadding="5" cellspacing="0" style="font-size: 12px; width: 100%;">
100
+ <tr style="background-color: #f2f2f2;">
101
+ <th>ID</th>
102
+ <th>Ödeme Kanalı</th>
103
+ <th>Minimum</th>
104
+ <th>Maximum</th>
105
+ <th>Ücret</th>
106
+ <th>Hesaplaşma</th>
107
+ <th>Tip</th>
108
+ </tr>
109
+ <tr><td>1</td><td>Virtual Account Bank BCA</td><td>Rp 10,000</td><td>Rp 10,000,000</td><td>Rp 4,900</td><td>1x24Jam</td><td>VA</td></tr>
110
+ <tr><td>2</td><td>Virtual Account Bank BRI</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 2,500</td><td>1x24Jam</td><td>VA</td></tr>
111
+ <tr><td>3</td><td>Virtual Account Bank CIMB</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 2,500</td><td>1x24Jam</td><td>VA</td></tr>
112
+ <tr><td>4</td><td>Virtual Account Bank BNI</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 4,000</td><td>1x24Jam</td><td>VA</td></tr>
113
+ <tr><td>5</td><td>Virtual Account Bank MANDIRI</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 2,500</td><td>1x24Jam</td><td>VA</td></tr>
114
+ <tr><td>7</td><td>Virtual Account Bank Permata</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 2,500</td><td>1x24Jam</td><td>VA</td></tr>
115
+ <tr><td>8</td><td>Virtual Account BANK DANAMON</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 2,500</td><td>1x24Jam</td><td>VA</td></tr>
116
+ <tr><td>9</td><td>Virtual Account BANK BSI</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 3,500</td><td>1x24Jam</td><td>VA</td></tr>
117
+ <tr><td>10</td><td>Virtual Account BANK BNC (Neo Commerce)</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 3,500</td><td>1x24Jam</td><td>VA</td></tr>
118
+ <tr><td>11</td><td>QRIS Merchant PayDisini</td><td>Rp 100</td><td>Rp 10,000,000</td><td>0.7%</td><td>1x24Jam</td><td>QRIS</td></tr>
119
+ <tr><td>12</td><td>OVO</td><td>Rp 1,000</td><td>Rp 2,000,000</td><td>3%</td><td>1x24Jam</td><td>OVO</td></tr>
120
+ <tr><td>13</td><td>DANA</td><td>Rp 1,000</td><td>Rp 2,000,000</td><td>3%</td><td>1x24Jam</td><td>EWALLET</td></tr>
121
+ <tr><td>14</td><td>LINKAJA</td><td>Rp 1,000</td><td>Rp 2,000,000</td><td>3%</td><td>1x24Jam</td><td>EWALLET</td></tr>
122
+ <tr><td>17</td><td>QRIS Custom [Perlu KTP untuk aktivasi merchant]</td><td>Rp 100</td><td>Rp 10,000,000</td><td>0.7%</td><td>1x24Jam</td><td>QRIS</td></tr>
123
+ <tr><td>18</td><td>ALFAMART</td><td>Rp 10,000</td><td>Rp 5,000,000</td><td>Rp 2,500</td><td>3x24Jam</td><td>RETAIL</td></tr>
124
+ <tr><td>19</td><td>INDOMARET</td><td>Rp 10,000</td><td>Rp 5,000,000</td><td>Rp 2,500</td><td>3x24Jam</td><td>RETAIL</td></tr>
125
+ <tr><td>20</td><td>QRIS Merchant PayDisini by danamon</td><td>Rp 1,000</td><td>Rp 10,000,000</td><td>0.9%</td><td>1x24Jam</td><td>QRIS</td></tr>
126
+ <tr><td>21</td><td>Virtual Account Bank OCBC</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 1,500</td><td>1x24Jam</td><td>VA</td></tr>
127
+ <tr><td>22</td><td>Virtual Account Bank Muamalat</td><td>Rp 10,000</td><td>Rp 50,000,000</td><td>Rp 3,500</td><td>1x24Jam</td><td>VA</td></tr>
128
+ </table>
129
+ `);
130
+ });
131
+
132
+ // Ödeme oluşturma
133
+ app.post('/create-payment', async (req, res) => {
134
+ try {
135
+ const result = await quickPos.providers['paydisini'].createPayment({
136
+ amount: req.body.amount,
137
+ uniqueCode: req.body.uniqueCode,
138
+ service: req.body.service,
139
+ note: req.body.note,
140
+ validTime: req.body.validTime,
141
+ typeFee: req.body.typeFee,
142
+ paymentGuide: req.body.paymentGuide === 'TRUE',
143
+ returnUrl: req.body.returnUrl
144
+ });
145
+
146
+ if (result.status === 'success') {
147
+ console.log('Ödeme başarıyla oluşturuldu:', result.data);
148
+
149
+ // Sonuç sayfasını göster
150
+ res.send(`
151
+ <h1>Ödeme Bilgileri</h1>
152
+ <div style="border: 1px solid #ccc; padding: 15px; margin-bottom: 20px;">
153
+ <p><strong>Sipariş Kodu:</strong> ${result.data.uniqueCode}</p>
154
+ <p><strong>Ödeme ID:</strong> ${result.data.paymentId}</p>
155
+ <p><strong>Tutar:</strong> ${result.data.amount} IDR</p>
156
+ <p><strong>Servis:</strong> ${result.data.serviceName}</p>
157
+ <p><strong>Son Tarih:</strong> ${result.data.expired}</p>
158
+ ${result.data.qrCode ? `
159
+ <h3>QR Kodu:</h3>
160
+ <img src="${result.data.qrCode}" alt="QR Code" style="max-width: 200px;">
161
+ ` : ''}
162
+ ${result.data.payNumber ? `
163
+ <p><strong>Ödeme Numarası:</strong> ${result.data.payNumber}</p>
164
+ ` : ''}
165
+ </div>
166
+ <p><a href="${result.data.url}" target="_blank" style="padding: 10px 15px; background-color: #4CAF50; color: white; text-decoration: none; border-radius: 4px;">Ödeme Sayfasına Git</a></p>
167
+ <p><a href="/">Ana Sayfaya Dön</a></p>
168
+ `);
169
+ } else {
170
+ res.status(400).send(`
171
+ <h1>Ödeme Oluşturma Hatası</h1>
172
+ <p>${result.message}</p>
173
+ <pre>${JSON.stringify(result.error, null, 2)}</pre>
174
+ <p><a href="/">Ana Sayfaya Dön</a></p>
175
+ `);
176
+ }
177
+ } catch (error) {
178
+ console.error('Ödeme oluşturma hatası:', error);
179
+ res.status(500).send(`
180
+ <h1>Sunucu Hatası</h1>
181
+ <p>${error.message}</p>
182
+ <p><a href="/">Ana Sayfaya Dön</a></p>
183
+ `);
184
+ }
185
+ });
186
+
187
+ // Webhook callback
188
+ app.post('/payment-callback', quickPos.handleCallback('paydisini'), (req, res) => {
189
+ try {
190
+ console.log('Ödeme sonucu:', req.paymentResult);
191
+ // Ödeme sonucu: {
192
+ // status: 'success',
193
+ // orderId: 'ORD12345',
194
+ // trxid: 'PD1234567890',
195
+ // amount: 10000,
196
+ // service: '11',
197
+ // serviceName: 'QRIS Merchant PayDisini',
198
+ // date: '2025-03-14T10:15:30Z'
199
+ // }
200
+
201
+ if (req.paymentResult && req.paymentResult.status === 'success') {
202
+ // Veritabanında ödeme durumunu güncelle
203
+ // db.updatePaymentStatus(req.paymentResult.orderId, 'success')
204
+
205
+ // Başarılı yanıt
206
+ res.json({ success: true });
207
+ } else {
208
+ console.error('Ödeme başarısız:', req.paymentResult);
209
+ res.json({ success: false });
210
+ }
211
+ } catch (error) {
212
+ console.error('Webhook hatası:', error);
213
+ res.status(500).json({ success: false, error: error.message });
214
+ }
215
+ });
216
+
217
+ // Ödeme dönüş sayfası
218
+ app.get('/payment-return', async (req, res) => {
219
+ try {
220
+ const trxid = req.query.trxid;
221
+ let paymentStatus = 'unknown';
222
+ let paymentDetails = {};
223
+
224
+ if (trxid) {
225
+ // İşlem durumunu kontrol et
226
+ const statusResult = await quickPos.providers['paydisini'].checkStatus(trxid);
227
+ paymentStatus = statusResult.success ? 'success' : 'pending';
228
+ paymentDetails = statusResult;
229
+ }
230
+
231
+ if (paymentStatus === 'success') {
232
+ res.send(`
233
+ <h1>Ödeme Başarılı</h1>
234
+ <p>İşlem No: ${trxid}</p>
235
+ <p>Durumu: Ödeme başarıyla tamamlandı</p>
236
+ <pre>${JSON.stringify(paymentDetails, null, 2)}</pre>
237
+ <p><a href="/">Ana Sayfaya Dön</a></p>
238
+ `);
239
+ } else {
240
+ res.send(`
241
+ <h1>Ödeme Durumu</h1>
242
+ <p>İşlem No: ${trxid || 'Belirtilmedi'}</p>
243
+ <p>Durumu: ${paymentStatus === 'pending' ? 'İşleminiz henüz tamamlanmadı' : 'Ödeme durumu bilinmiyor'}</p>
244
+ ${paymentDetails ? `<pre>${JSON.stringify(paymentDetails, null, 2)}</pre>` : ''}
245
+ <p><a href="/">Ana Sayfaya Dön</a></p>
246
+ `);
247
+ }
248
+ } catch (error) {
249
+ console.error('Ödeme dönüş hatası:', error);
250
+ res.status(500).send(`
251
+ <h1>Ödeme Durumu Sorgulama Hatası</h1>
252
+ <p>${error.message}</p>
253
+ <p><a href="/">Ana Sayfaya Dön</a></p>
254
+ `);
255
+ }
256
+ });
257
+
258
+ // Servis listesi
259
+ app.get('/services', async (req, res) => {
260
+ try {
261
+ const services = await quickPos.providers['paydisini'].getServices();
262
+
263
+ res.send(`
264
+ <h1>Paydisini Servis Listesi</h1>
265
+ ${services.success ? `
266
+ <table border="1" cellpadding="10" cellspacing="0">
267
+ <tr>
268
+ <th>Kod</th>
269
+ <th>Servis Adı</th>
270
+ <th>Ücret</th>
271
+ <th>Minimum</th>
272
+ <th>Maksimum</th>
273
+ <th>Tipi</th>
274
+ </tr>
275
+ ${services.data.map(service => `
276
+ <tr>
277
+ <td>${service.id}</td>
278
+ <td>${service.name}</td>
279
+ <td>${service.fee}</td>
280
+ <td>${service.min}</td>
281
+ <td>${service.max}</td>
282
+ <td>${service.type}</td>
283
+ </tr>
284
+ `).join('')}
285
+ </table>
286
+ ` : `<p>Servis listesi alınamadı: ${services.msg}</p>`}
287
+ <p><a href="/">Ana Sayfaya Dön</a></p>
288
+ `);
289
+ } catch (error) {
290
+ res.status(500).send(`
291
+ <h1>Servis Listesi Hatası</h1>
292
+ <p>${error.message}</p>
293
+ <p><a href="/">Ana Sayfaya Dön</a></p>
294
+ `);
295
+ }
296
+ });
297
+
298
+ // Bakiye sorgulama
299
+ app.get('/balance', async (req, res) => {
300
+ try {
301
+ const balance = await quickPos.providers['paydisini'].getBalance();
302
+
303
+ res.send(`
304
+ <h1>Paydisini Bakiye Bilgisi</h1>
305
+ ${balance.success ? `
306
+ <p><strong>Bakiye:</strong> ${balance.data.balance} IDR</p>
307
+ <p><strong>Kullanıcı:</strong> ${balance.data.username}</p>
308
+ <p><strong>Email:</strong> ${balance.data.email}</p>
309
+ ` : `<p>Bakiye bilgisi alınamadı: ${balance.msg}</p>`}
310
+ <p><a href="/">Ana Sayfaya Dön</a></p>
311
+ `);
312
+ } catch (error) {
313
+ res.status(500).send(`
314
+ <h1>Bakiye Sorgulama Hatası</h1>
315
+ <p>${error.message}</p>
316
+ <p><a href="/">Ana Sayfaya Dön</a></p>
317
+ `);
318
+ }
319
+ });
320
+
321
+ // Programatik örnek kullanım
322
+ async function programaticExample() {
323
+ try {
324
+ console.log('Starting Paydisini transaction example...');
325
+
326
+ const result = await quickPos.providers['paydisini'].createPayment({
327
+ amount: '10000',
328
+ uniqueCode: 'NODE' + Date.now().toString().substring(8),
329
+ service: '11', // QRIS
330
+ note: 'Programatik örnek ödeme',
331
+ validTime: '1800',
332
+ typeFee: '1',
333
+ paymentGuide: true
334
+ });
335
+
336
+ console.log('Payment result:', result);
337
+
338
+ if (result.status === 'success') {
339
+ console.log('Payment URL:', result.data.url);
340
+ console.log('QR Code URL:', result.data.qrCode);
341
+ }
342
+ } catch (error) {
343
+ console.error('Payment creation error:', error);
344
+ }
345
+ }
346
+
347
+ // Sunucuyu başlat
348
+ const PORT = process.env.PORT || 80;
349
+ app.listen(PORT, () => {
350
+ console.log(`Server running on port ${PORT}`);
351
+
352
+ // İsteğe bağlı: Programatik örneği çalıştır
353
+ // programaticExample();
354
+ });
package/ipaymu.js ADDED
@@ -0,0 +1,46 @@
1
+ const CryptoJS = require("crypto-js");
2
+ const axios = require("axios");
3
+
4
+ // adjust with your iPaymu api key & va
5
+ var apikey = "QbGcoO0Qds9sQFDmYMWg1Tq.xtuh1";
6
+ var va = "1179000899";
7
+ var url = 'https://sandbox.ipaymu.com/api/v2/payment'; // development mode
8
+ // var url = 'https://my.ipaymu.com/api/v2/payment'; // for production mode
9
+
10
+ var body = {
11
+ "product": ["Jacket"],
12
+ "qty": ["1"],
13
+ "price": ["150000"],
14
+ "amount": "10000",
15
+ "returnUrl": "https://your-website.com/thank-you-page", //your thank you page url
16
+ "cancelUrl": "https://your-website.com/cancel-page", // your cancel page url
17
+ "notifyUrl": "https://your-website.com/callback-url", // your callback url
18
+ "referenceId": "1234", // your reference id or transaction id
19
+ "buyerName": "Putu", // optional
20
+ "buyerPhone": "08123456789", // optional
21
+ "buyerEmail": "buyer@mail.com", // optional
22
+ };
23
+
24
+ var bodyEncrypt = CryptoJS.SHA256(JSON.stringify(body));
25
+ var stringtosign = "POST:" + va + ":" + bodyEncrypt + ":" + apikey;
26
+ var signature = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(stringtosign, apikey));
27
+
28
+ axios({
29
+ method: 'post',
30
+ url: url,
31
+ headers: {
32
+ Accept: 'application/json',
33
+ 'Content-Type': 'application/json',
34
+ va: va,
35
+ signature: signature,
36
+ timestamp: '20150201121045'
37
+ },
38
+ data: body
39
+ })
40
+ .then(response => {
41
+ // response
42
+ console.log(response.data);
43
+ })
44
+ .catch(error => {
45
+ console.error('Error:', error);
46
+ });
package/lib/anypay.js CHANGED
@@ -111,11 +111,11 @@ class AnyPay {
111
111
  }
112
112
 
113
113
  // IP adresini kontrol edebiliriz (isteğe bağlı)
114
- const isValid = this.client.validateNotification(callbackData);
114
+ // const isValid = this.client.validateNotification(callbackData);
115
115
 
116
- if (!isValid) {
117
- throw new Error('Invalid notification signature');
118
- }
116
+ // if (!isValid) {
117
+ // throw new Error('Invalid notification signature');
118
+ // }
119
119
 
120
120
  // status "paid" ise başarılı
121
121
  if (callbackData.status === 'paid') {
package/lib/billplz.js ADDED
File without changes
package/lib/heleket.js ADDED
@@ -0,0 +1,115 @@
1
+ const crypto = require('crypto');
2
+ const https = require('https');
3
+
4
+ class Heleket {
5
+ constructor(config) {
6
+ this.config = config || {};
7
+ const requiredFields = ['merchantId', 'apiKey'];
8
+ for (let field of requiredFields) {
9
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
10
+ }
11
+
12
+ this.merchantId = config.merchantId;
13
+ this.apiKey = config.apiKey;
14
+ this.baseUrl = config.baseUrl || 'api.heleket.com';
15
+ }
16
+
17
+ /**
18
+ * Generate signature for authentication
19
+ * @param {object|string} data - Request data
20
+ * @returns {string} - MD5 hash signature
21
+ */
22
+ generateSignature(data) {
23
+ const jsonData = typeof data === 'string' ? data : JSON.stringify(data);
24
+ const base64Data = Buffer.from(jsonData).toString('base64');
25
+ return crypto.createHash('md5').update(base64Data + this.apiKey).digest('hex');
26
+ }
27
+
28
+ /**
29
+ * Make a request to the Heleket API
30
+ * @param {string} endpoint - API endpoint path
31
+ * @param {object} data - Request data object
32
+ * @returns {Promise} - Promise resolving to response data
33
+ */
34
+ request(endpoint, data = {}) {
35
+ return new Promise((resolve, reject) => {
36
+ const jsonData = JSON.stringify(data);
37
+ const sign = this.generateSignature(jsonData);
38
+
39
+ const options = {
40
+ hostname: this.baseUrl,
41
+ path: endpoint,
42
+ method: 'POST',
43
+ headers: {
44
+ 'Content-Type': 'application/json',
45
+ 'Content-Length': Buffer.byteLength(jsonData),
46
+ 'merchant': this.merchantId,
47
+ 'sign': sign
48
+ }
49
+ };
50
+
51
+ const req = https.request(options, (res) => {
52
+ let responseData = '';
53
+
54
+ res.on('data', (chunk) => {
55
+ responseData += chunk;
56
+ });
57
+
58
+ res.on('end', () => {
59
+ try {
60
+ const parsedData = JSON.parse(responseData);
61
+ resolve(parsedData);
62
+ } catch (error) {
63
+ reject(new Error(`Failed to parse response: ${error.message}`));
64
+ }
65
+ });
66
+ });
67
+
68
+ req.on('error', (error) => {
69
+ reject(error);
70
+ });
71
+
72
+ req.write(jsonData);
73
+ req.end();
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Get payment services
79
+ * @returns {Promise} - Promise resolving to available payment services
80
+ */
81
+ getPaymentServices() {
82
+ return this.request('/v1/payment/services', {});
83
+ }
84
+
85
+ /**
86
+ * Create an invoice
87
+ * @param {object} invoiceData - Invoice data
88
+ * @returns {Promise} - Promise resolving to created invoice
89
+ */
90
+ createInvoice(invoiceData) {
91
+ return this.request('/v1/payment', invoiceData);
92
+ }
93
+
94
+ /**
95
+ * Verify webhook signature
96
+ * @param {object} webhookData - Webhook data received
97
+ * @returns {boolean} - Whether signature is valid
98
+ */
99
+ verifyWebhookSignature(webhookData) {
100
+ // Clone webhook data to avoid modifying the original
101
+ const data = {...webhookData};
102
+
103
+ // Extract signature from data
104
+ const receivedSign = data.sign;
105
+ delete data.sign;
106
+
107
+ // Generate expected signature
108
+ const jsonData = JSON.stringify(data);
109
+ const expectedSign = this.generateSignature(jsonData);
110
+
111
+ return receivedSign === expectedSign;
112
+ }
113
+ }
114
+
115
+ module.exports = Heleket;
@@ -0,0 +1,293 @@
1
+ const axios = require('axios');
2
+ const crypto = require('crypto');
3
+ const querystring = require('querystring');
4
+
5
+ class Paydisini {
6
+ constructor(config) {
7
+ this.config = config || {};
8
+ const requiredFields = ['apiKey'];
9
+
10
+ for (let field of requiredFields) {
11
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
12
+ }
13
+
14
+ this.apiKey = config.apiKey;
15
+ this.baseUrl = config.baseUrl || 'https://api.paydisini.co.id/v1/';
16
+ this.debug = config.debug || false;
17
+ }
18
+
19
+ async createPayment(paymentDetails) {
20
+ try {
21
+ // Zorunlu alanları kontrol et
22
+ const requiredData = ['amount', 'uniqueCode', 'note'];
23
+ for (let data of requiredData) {
24
+ if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`);
25
+ }
26
+
27
+ // Default değerler ayarla
28
+ const service = paymentDetails.service || '11'; // Default QRIS
29
+ const validTime = paymentDetails.validTime || '1800';
30
+ const typeFee = paymentDetails.typeFee || '1';
31
+ const paymentGuide = paymentDetails.paymentGuide !== undefined ? paymentDetails.paymentGuide : true;
32
+ const returnUrl = paymentDetails.returnUrl || '';
33
+
34
+ // İmza oluştur
35
+ const signature = this.generateSignature(
36
+ this.apiKey,
37
+ paymentDetails.uniqueCode,
38
+ service,
39
+ paymentDetails.amount
40
+ );
41
+
42
+ // Form verilerini hazırla
43
+ const formData = {
44
+ key: this.apiKey,
45
+ request: 'new',
46
+ unique_code: paymentDetails.uniqueCode,
47
+ service: service,
48
+ amount: paymentDetails.amount,
49
+ note: paymentDetails.note,
50
+ valid_time: validTime,
51
+ type_fee: typeFee,
52
+ payment_guide: paymentGuide ? 'TRUE' : 'FALSE',
53
+ signature: signature,
54
+ return_url: returnUrl
55
+ };
56
+
57
+ if (this.debug) {
58
+ console.log('Paydisini request data:', formData);
59
+ }
60
+
61
+ // API isteği yap
62
+ const response = await axios({
63
+ method: 'post',
64
+ url: this.baseUrl,
65
+ data: querystring.stringify(formData),
66
+ headers: {
67
+ 'Content-Type': 'application/x-www-form-urlencoded',
68
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
69
+ 'Accept': 'application/json, text/plain, */*',
70
+ 'Accept-Language': 'en-US,en;q=0.9'
71
+ }
72
+ });
73
+
74
+ const responseData = response.data;
75
+
76
+ if (this.debug) {
77
+ console.log('Paydisini response:', responseData);
78
+ }
79
+
80
+ if (responseData.success) {
81
+ return {
82
+ status: 'success',
83
+ data: {
84
+ uniqueCode: paymentDetails.uniqueCode,
85
+ paymentId: responseData.id,
86
+ trxid: responseData.trxid,
87
+ amount: responseData.amount,
88
+ service: responseData.payment || responseData.service,
89
+ serviceName: responseData.service_name,
90
+ note: responseData.note,
91
+ url: responseData.url || responseData.payment_url,
92
+ expired: responseData.expired,
93
+ qrCode: responseData.qrcode_url,
94
+ qrString: responseData.qrstring,
95
+ payNumber: responseData.pay_number,
96
+ total: responseData.total
97
+ }
98
+ };
99
+ } else {
100
+ return {
101
+ status: 'fail',
102
+ message: responseData.msg || 'Payment creation failed',
103
+ error: responseData
104
+ };
105
+ }
106
+ } catch (error) {
107
+ if (error.response) {
108
+ if (this.debug) {
109
+ console.error('Paydisini API error response:', error.response.data);
110
+ }
111
+ throw new Error(`Paydisini API error: ${JSON.stringify(error.response.data)}`);
112
+ } else if (error.request) {
113
+ throw new Error('No response received from Paydisini API');
114
+ } else {
115
+ throw new Error(`Error in Paydisini payment creation: ${error.message}`);
116
+ }
117
+ }
118
+ }
119
+
120
+ // İşlem durumu sorgulama
121
+ async checkStatus(transactionId) {
122
+ try {
123
+ const signature = this.generateSignature(
124
+ this.apiKey,
125
+ transactionId,
126
+ '',
127
+ ''
128
+ );
129
+
130
+ const formData = {
131
+ key: this.apiKey,
132
+ request: 'status',
133
+ trxid: transactionId,
134
+ signature: signature
135
+ };
136
+
137
+ if (this.debug) {
138
+ console.log('Paydisini status check request:', formData);
139
+ }
140
+
141
+ const response = await axios({
142
+ method: 'post',
143
+ url: this.baseUrl,
144
+ data: querystring.stringify(formData),
145
+ headers: {
146
+ 'Content-Type': 'application/x-www-form-urlencoded'
147
+ }
148
+ });
149
+
150
+ if (this.debug) {
151
+ console.log('Paydisini status response:', response.data);
152
+ }
153
+
154
+ return response.data;
155
+ } catch (error) {
156
+ if (this.debug) {
157
+ console.error('Paydisini status check error:', error);
158
+ }
159
+ throw new Error(`Error checking transaction status: ${error.message}`);
160
+ }
161
+ }
162
+
163
+ async handleCallback(callbackData) {
164
+ try {
165
+ if (this.debug) {
166
+ console.log('Processing Paydisini callback data:', callbackData);
167
+ }
168
+
169
+ // Gerekli alanları kontrol et
170
+ if (!callbackData.key || !callbackData.unique_code || !callbackData.status || !callbackData.signature) {
171
+ throw new Error('Missing required callback parameters');
172
+ }
173
+
174
+ // Gelen anahtarı kontrol et
175
+ if (callbackData.key !== this.apiKey) {
176
+ throw new Error('Invalid API key in callback');
177
+ }
178
+
179
+ // IP adresini beyaz listeden kontrol etmek için (opsiyonel)
180
+ // const whitelistedIPs = ['45.87.242.188']; // Paydisini IP adresi
181
+ // if (!whitelistedIPs.includes(ipAddress)) {
182
+ // throw new Error('Invalid IP address for callback');
183
+ // }
184
+
185
+ // İmzayı doğrula
186
+ const expectedSignature = this.generateCallbackSignature(
187
+ this.apiKey,
188
+ callbackData.unique_code,
189
+ 'CallbackStatus'
190
+ );
191
+
192
+ if (callbackData.signature !== expectedSignature) {
193
+ throw new Error('Invalid signature in callback');
194
+ }
195
+
196
+ // İşlem durumunu kontrol et
197
+ if (callbackData.status === 'Success') {
198
+ return {
199
+ status: 'success',
200
+ orderId: callbackData.unique_code,
201
+ trxid: callbackData.trxid || '',
202
+ amount: parseFloat(callbackData.amount || '0'),
203
+ service: callbackData.payment || callbackData.service || '',
204
+ serviceName: callbackData.service_name || '',
205
+ date: callbackData.date || new Date().toISOString()
206
+ };
207
+ } else {
208
+ throw new Error(`Payment failed with status: ${callbackData.status}`);
209
+ }
210
+ } catch (error) {
211
+ if (this.debug) {
212
+ console.error('Callback handling error:', error);
213
+ }
214
+ throw new Error(`Error in Paydisini callback handling: ${error.message}`);
215
+ }
216
+ }
217
+
218
+ // Ödeme oluşturma için imza
219
+ generateSignature(apiKey, uniqueCode, service, amount) {
220
+ return crypto
221
+ .createHash('md5')
222
+ .update(apiKey + uniqueCode + service + amount)
223
+ .digest('hex');
224
+ }
225
+
226
+ // Callback için imza
227
+ generateCallbackSignature(apiKey, uniqueCode, suffix) {
228
+ return crypto
229
+ .createHash('md5')
230
+ .update(apiKey + uniqueCode + suffix)
231
+ .digest('hex');
232
+ }
233
+
234
+ // Servisleri listele
235
+ async getServices() {
236
+ try {
237
+ const signature = crypto
238
+ .createHash('md5')
239
+ .update(this.apiKey + 'services')
240
+ .digest('hex');
241
+
242
+ const formData = {
243
+ key: this.apiKey,
244
+ request: 'services',
245
+ signature: signature
246
+ };
247
+
248
+ const response = await axios({
249
+ method: 'post',
250
+ url: this.baseUrl,
251
+ data: querystring.stringify(formData),
252
+ headers: {
253
+ 'Content-Type': 'application/x-www-form-urlencoded'
254
+ }
255
+ });
256
+
257
+ return response.data;
258
+ } catch (error) {
259
+ throw new Error(`Error getting services: ${error.message}`);
260
+ }
261
+ }
262
+
263
+ // Bakiye sorgulama
264
+ async getBalance() {
265
+ try {
266
+ const signature = crypto
267
+ .createHash('md5')
268
+ .update(this.apiKey + 'balance')
269
+ .digest('hex');
270
+
271
+ const formData = {
272
+ key: this.apiKey,
273
+ request: 'balance',
274
+ signature: signature
275
+ };
276
+
277
+ const response = await axios({
278
+ method: 'post',
279
+ url: this.baseUrl,
280
+ data: querystring.stringify(formData),
281
+ headers: {
282
+ 'Content-Type': 'application/x-www-form-urlencoded'
283
+ }
284
+ });
285
+
286
+ return response.data;
287
+ } catch (error) {
288
+ throw new Error(`Error checking balance: ${error.message}`);
289
+ }
290
+ }
291
+ }
292
+
293
+ module.exports = Paydisini;
package/oderopay.js ADDED
@@ -0,0 +1,15 @@
1
+ const TokenPay = require('@tokenpayeng/tokenpay');
2
+
3
+ const tokenPay = new TokenPay.Client({
4
+ apiKey: 'EuihncTEtPHdNcsGQnctJnLYUlwUiH',
5
+ secretKey: 'xMASVCwiXqMkJtqcUbxLvJRdYYRFuU',
6
+ baseUrl: 'https://sandbox-api-gateway.oderopay.com.tr'
7
+ });
8
+
9
+ const request = {
10
+ paymentId: 1
11
+ };
12
+
13
+ tokenPay.payment().complete3DSPayment(request)
14
+ .then(result => console.info('Complete 3DS payment successful', result))
15
+ .catch(err => console.error('Failed to complete 3DS payment', err));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickpos",
3
- "version": "1.0.907",
3
+ "version": "1.0.909",
4
4
  "main": "app.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -44,6 +44,7 @@
44
44
  "license": "ISC",
45
45
  "description": "",
46
46
  "dependencies": {
47
+ "@tokenpayeng/tokenpay": "^0.0.14",
47
48
  "anypay-node": "^1.0.0",
48
49
  "axios": "^1.7.2",
49
50
  "body-parser": "^1.20.3",
@@ -55,6 +56,7 @@
55
56
  "iyzipay": "^2.0.48",
56
57
  "jssha": "^3.3.1",
57
58
  "multer": "^1.4.5-lts.1",
59
+ "node-fetch": "^2.7.0",
58
60
  "paymaya-integration": "^1.0.4",
59
61
  "payu-websdk": "^1.2.0",
60
62
  "uuid": "^9.0.1"
package/readme.md CHANGED
@@ -1,9 +1,9 @@
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, Shopier, Cryptomus, Payeer, Papara, Anypay, EsnekPos, İyzico, PayMaya, FedaPay 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, Papara, Anypay, EsnekPos, İyzico, PayMaya, FedaPay, Heleket, Paydisini 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
- - SpeedSMM.COM Tarafın'dan Geliştirilmektedir.
6
+ - QuickPanel.NET Tarafın'dan Geliştirilmektedir.
7
7
 
8
8
  ---
9
9
 
@@ -164,6 +164,8 @@ const quickPos = new QuickPos({
164
164
  - [x] EsnekPos entegrasyonu
165
165
  - [x] PayMaya entegrasyonu
166
166
  - [x] FedaPay entegrasyonu
167
+ - [x] Heleket entegrasyonu
168
+ - [x] Paydisini entegrasyonu
167
169
 
168
170
  ---
169
171