quickpos 1.0.908 → 1.0.910
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-heleket.js +83 -0
- package/example-paydisini.js +354 -0
- package/ipaymu.js +46 -0
- package/lib/billplz.js +0 -0
- package/lib/heleket.js +151 -0
- package/lib/paydisini.js +293 -0
- package/oderopay.js +15 -0
- package/package.json +3 -1
- package/readme.md +4 -2
|
@@ -0,0 +1,83 @@
|
|
|
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-fbac2bcd498',
|
|
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
|
+
// Webhook callback işleme örneği
|
|
58
|
+
async function handleCallbackExample() {
|
|
59
|
+
const webhookData = {
|
|
60
|
+
order_id: 'test-123',
|
|
61
|
+
transaction_id: 'tx-456789',
|
|
62
|
+
status: 'completed',
|
|
63
|
+
amount: '20',
|
|
64
|
+
currency: 'USDT',
|
|
65
|
+
network: 'tron',
|
|
66
|
+
sign: 'example-signature-here'
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const result = await heleket.handleCallback(webhookData);
|
|
71
|
+
console.log('Callback işleme sonucu:', result);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('Callback işlenirken hata:', error.message);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Örnek fonksiyonları çalıştır
|
|
78
|
+
(async () => {
|
|
79
|
+
await createSampleInvoice();
|
|
80
|
+
// await getServices();
|
|
81
|
+
verifyWebhook();
|
|
82
|
+
handleCallbackExample();
|
|
83
|
+
})();
|
|
@@ -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/billplz.js
ADDED
|
File without changes
|
package/lib/heleket.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
* Handle callback from Heleket webhook
|
|
116
|
+
* @param {object} webhookData - Webhook data received from Heleket
|
|
117
|
+
* @returns {object} - Processed payment result
|
|
118
|
+
*/
|
|
119
|
+
async handleCallback(webhookData) {
|
|
120
|
+
try {
|
|
121
|
+
// Verify signature first
|
|
122
|
+
const isValidSignature = this.verifyWebhookSignature(webhookData);
|
|
123
|
+
|
|
124
|
+
if (!isValidSignature) {
|
|
125
|
+
throw new Error("Heleket notification failed: invalid signature");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Clone webhook data to avoid modifying the original
|
|
129
|
+
const data = {...webhookData};
|
|
130
|
+
|
|
131
|
+
// Process successful payments
|
|
132
|
+
if (data.status === 'completed' || data.status === 'success') {
|
|
133
|
+
return {
|
|
134
|
+
status: 'success',
|
|
135
|
+
orderId: data.order_id,
|
|
136
|
+
transactionId: data.transaction_id || data.order_id,
|
|
137
|
+
amount: data.amount,
|
|
138
|
+
currency: data.currency,
|
|
139
|
+
network: data.network || null,
|
|
140
|
+
paymentType: 'crypto'
|
|
141
|
+
};
|
|
142
|
+
} else {
|
|
143
|
+
throw new Error(`Payment failed with status: ${data.status}`);
|
|
144
|
+
}
|
|
145
|
+
} catch (error) {
|
|
146
|
+
throw new Error(`Error in Heleket callback handling: ${error.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = Heleket;
|
package/lib/paydisini.js
ADDED
|
@@ -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.
|
|
3
|
+
"version": "1.0.910",
|
|
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
|
-
-
|
|
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
|
|