quickpos 1.0.906 → 1.0.908
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/app.js +2 -1
- package/example-anypay.js +334 -0
- package/example-esnekpos.js +254 -0
- package/example-fedapay.js +217 -0
- package/example-iyzico.js +103 -0
- package/example-paymaya.js +112 -0
- package/lib/anypay.js +246 -0
- package/lib/esnekpos.js +352 -0
- package/lib/fedapay.js +194 -0
- package/lib/iyzico.js +180 -0
- package/lib/paymaya.js +126 -0
- package/package.json +16 -4
- package/readme.md +10 -12
|
@@ -0,0 +1,217 @@
|
|
|
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
|
+
fedapay: {
|
|
12
|
+
apiKey: 'sk_sandbd_92HEJoHiqT3g9dS6', // Sandbox API Key
|
|
13
|
+
environment: 'sandbox', // 'sandbox' veya 'live'
|
|
14
|
+
debug: true // Geliştirme aşamasında hata ayıklama için
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// QuickPos middleware'ini ekle
|
|
20
|
+
app.use(quickPos.middleware());
|
|
21
|
+
|
|
22
|
+
// Ana sayfa - Ödeme form sayfası
|
|
23
|
+
app.get('/', (req, res) => {
|
|
24
|
+
res.send(`
|
|
25
|
+
<h1>FedaPay Ödeme Testi</h1>
|
|
26
|
+
<form action="/create-payment" method="post">
|
|
27
|
+
<div>
|
|
28
|
+
<label>Tutar:</label>
|
|
29
|
+
<input type="text" name="amount" value="1000" required>
|
|
30
|
+
</div>
|
|
31
|
+
<div>
|
|
32
|
+
<label>Para Birimi:</label>
|
|
33
|
+
<select name="currency" required>
|
|
34
|
+
<option value="XOF">XOF (West African CFA franc)</option>
|
|
35
|
+
<option value="USD">USD (US Dollar)</option>
|
|
36
|
+
<option value="EUR">EUR (Euro)</option>
|
|
37
|
+
</select>
|
|
38
|
+
</div>
|
|
39
|
+
<div>
|
|
40
|
+
<label>Ödeme Modu:</label>
|
|
41
|
+
<select name="mode">
|
|
42
|
+
<option value="">Seçiniz (Opsiyonel)</option>
|
|
43
|
+
<option value="mtn">MTN Mobile Money</option>
|
|
44
|
+
<option value="moov">Moov Money</option>
|
|
45
|
+
<option value="mtn_open">MTN Open API</option>
|
|
46
|
+
<option value="moov_open">Moov Open API</option>
|
|
47
|
+
<option value="card">Kredi Kartı</option>
|
|
48
|
+
</select>
|
|
49
|
+
</div>
|
|
50
|
+
<div>
|
|
51
|
+
<label>Sipariş No:</label>
|
|
52
|
+
<input type="text" name="orderId" value="ORDER-${Date.now()}" required>
|
|
53
|
+
</div>
|
|
54
|
+
<div>
|
|
55
|
+
<label>Açıklama:</label>
|
|
56
|
+
<input type="text" name="description" value="Test Ödemesi" required>
|
|
57
|
+
</div>
|
|
58
|
+
<div>
|
|
59
|
+
<label>E-posta:</label>
|
|
60
|
+
<input type="email" name="email" value="customer@example.com">
|
|
61
|
+
</div>
|
|
62
|
+
<div>
|
|
63
|
+
<label>İsim:</label>
|
|
64
|
+
<input type="text" name="firstName" value="John">
|
|
65
|
+
</div>
|
|
66
|
+
<div>
|
|
67
|
+
<label>Soyisim:</label>
|
|
68
|
+
<input type="text" name="lastName" value="Doe">
|
|
69
|
+
</div>
|
|
70
|
+
<div>
|
|
71
|
+
<label>Telefon Numarası:</label>
|
|
72
|
+
<input type="text" name="phone" value="90090909">
|
|
73
|
+
</div>
|
|
74
|
+
<div>
|
|
75
|
+
<label>Telefon Ülkesi:</label>
|
|
76
|
+
<select name="phoneCountry">
|
|
77
|
+
<option value="BJ">Benin (BJ)</option>
|
|
78
|
+
<option value="TG">Togo (TG)</option>
|
|
79
|
+
<option value="CI">Côte d'Ivoire (CI)</option>
|
|
80
|
+
<option value="SN">Senegal (SN)</option>
|
|
81
|
+
</select>
|
|
82
|
+
</div>
|
|
83
|
+
<button type="submit">Ödeme Oluştur</button>
|
|
84
|
+
</form>
|
|
85
|
+
`);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Ödeme oluşturma rotası
|
|
89
|
+
app.post('/create-payment', async (req, res) => {
|
|
90
|
+
try {
|
|
91
|
+
const result = await quickPos.providers['fedapay'].createPayment({
|
|
92
|
+
amount: req.body.amount,
|
|
93
|
+
currency: req.body.currency,
|
|
94
|
+
description: req.body.description,
|
|
95
|
+
orderId: req.body.orderId,
|
|
96
|
+
email: req.body.email,
|
|
97
|
+
firstName: req.body.firstName,
|
|
98
|
+
lastName: req.body.lastName,
|
|
99
|
+
phone: req.body.phone,
|
|
100
|
+
phoneCountry: req.body.phoneCountry,
|
|
101
|
+
mode: req.body.mode || null,
|
|
102
|
+
successUrl: `http://${req.headers.host}/success`,
|
|
103
|
+
failUrl: `http://${req.headers.host}/cancel`,
|
|
104
|
+
notificationUrl: `http://${req.headers.host}/webhook/fedapay`
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (result.status === 'success') {
|
|
108
|
+
console.log('Ödeme başarıyla oluşturuldu:', result.data);
|
|
109
|
+
// Ödeme başarıyla oluşturuldu: {
|
|
110
|
+
// id: 307688,
|
|
111
|
+
// transactionId: 307688,
|
|
112
|
+
// reference: 'trx_Q6E_1742143079406',
|
|
113
|
+
// url: 'https://sandbox-process.fedapay.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjMwNzY4OCwiZXhwIjoxNzQyMjI5NDgwfQ.ZaGo6MmkdLf1eeYKH7KhnjFBBYKaiGhYOWQ9aSy8b38',
|
|
114
|
+
// token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjMwNzY4OCwiZXhwIjoxNzQyMjI5NDgwfQ.ZaGo6MmkdLf1eeYKH7KhnjFBBYKaiGhYOWQ9aSy8b38'
|
|
115
|
+
// }
|
|
116
|
+
// Ödeme sayfasına yönlendir
|
|
117
|
+
res.redirect(result.data.url);
|
|
118
|
+
} else {
|
|
119
|
+
res.status(400).json({ error: 'Ödeme oluşturulamadı', details: result });
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error('Ödeme oluşturma hatası:', error);
|
|
123
|
+
res.status(500).json({ error: error.message });
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Webhook işleme rotası
|
|
128
|
+
app.post('/webhook/fedapay', async (req, res) => {
|
|
129
|
+
try {
|
|
130
|
+
const notification = req.body;
|
|
131
|
+
console.log('Webhook çağrısı alındı:', notification);
|
|
132
|
+
|
|
133
|
+
// FedaPay tarafından gönderilen signature header'i kontrol et
|
|
134
|
+
const signature = req.headers['fedapay-signature'];
|
|
135
|
+
|
|
136
|
+
if (signature) {
|
|
137
|
+
const isValidSignature = await quickPos.providers['fedapay'].verifySignature(
|
|
138
|
+
req.body,
|
|
139
|
+
signature
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
if (!isValidSignature) {
|
|
143
|
+
console.error('Geçersiz imza');
|
|
144
|
+
return res.status(400).send('Invalid signature');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// İşlemi doğrula ve işle
|
|
149
|
+
const paymentResult = await quickPos.providers['fedapay'].handleCallback(notification);
|
|
150
|
+
|
|
151
|
+
console.log('Ödeme sonucu:', paymentResult);
|
|
152
|
+
|
|
153
|
+
if (paymentResult.status === 'success') {
|
|
154
|
+
// Burada sipariş durumunu güncelleyebilir, veritabanı işlemleri yapabilirsiniz
|
|
155
|
+
console.log(`Ödeme başarılı: Sipariş #${paymentResult.orderId}, Tutar: ${paymentResult.amount} ${paymentResult.currency}`);
|
|
156
|
+
|
|
157
|
+
// FedaPay başarılı yanıt bekliyor
|
|
158
|
+
res.status(200).send('OK');
|
|
159
|
+
} else {
|
|
160
|
+
// Başarısız işlem
|
|
161
|
+
res.status(400).send('FAIL');
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error('Webhook hatası:', error);
|
|
165
|
+
res.status(500).send('ERROR');
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Başarılı ödeme sayfası
|
|
170
|
+
app.get('/success', (req, res) => {
|
|
171
|
+
res.send(`
|
|
172
|
+
<h1>Ödemeniz başarıyla tamamlandı!</h1>
|
|
173
|
+
<p>İşlem numarası: ${req.query.transaction_id || 'Belirtilmedi'}</p>
|
|
174
|
+
<a href="/">Ana Sayfaya Dön</a>
|
|
175
|
+
`);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// İptal edilen/başarısız ödeme sayfası
|
|
179
|
+
app.get('/cancel', (req, res) => {
|
|
180
|
+
res.send(`
|
|
181
|
+
<h1>Ödeme işlemi iptal edildi veya başarısız oldu!</h1>
|
|
182
|
+
<a href="/">Tekrar Deneyin</a>
|
|
183
|
+
`);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// İşlem sorgulama
|
|
187
|
+
app.get('/transaction/:id', async (req, res) => {
|
|
188
|
+
try {
|
|
189
|
+
const result = await quickPos.providers['fedapay'].getTransaction(req.params.id);
|
|
190
|
+
res.json(result);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
res.status(500).json({ error: error.message });
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// İşlem listesi
|
|
197
|
+
app.get('/transactions', async (req, res) => {
|
|
198
|
+
try {
|
|
199
|
+
const result = await quickPos.providers['fedapay'].listTransactions({
|
|
200
|
+
page: req.query.page || 1,
|
|
201
|
+
per_page: req.query.per_page || 10
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
res.send(`
|
|
205
|
+
<h1>Son İşlemler</h1>
|
|
206
|
+
<pre>${JSON.stringify(result.data, null, 2)}</pre>
|
|
207
|
+
<p><a href="/">Ana Sayfaya Dön</a></p>
|
|
208
|
+
`);
|
|
209
|
+
} catch (error) {
|
|
210
|
+
res.status(500).json({ error: error.message });
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const PORT = process.env.PORT || 80;
|
|
215
|
+
app.listen(PORT, () => {
|
|
216
|
+
console.log(`Server ${PORT} portunda çalışıyor`);
|
|
217
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
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
|
+
iyzico: {
|
|
12
|
+
apiKey: 'sandbox-x',
|
|
13
|
+
secretKey: 'sandbox-x',
|
|
14
|
+
uri: 'https://sandbox-api.iyzipay.com' // Canlı ortam için: 'https://api.iyzipay.com'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
app.use(quickPos.middleware());
|
|
20
|
+
|
|
21
|
+
// Ödeme oluşturma örneği
|
|
22
|
+
app.get('/', async (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = await quickPos.providers['iyzico'].createPayment({
|
|
25
|
+
name: 'Test Product',
|
|
26
|
+
amount: '100.00',
|
|
27
|
+
currency: 'TRY',
|
|
28
|
+
callbackUrl: 'https://test.dalamangoldtaxi.net/iyzico-callback',
|
|
29
|
+
email: 'customer@example.com',
|
|
30
|
+
buyerName: 'John',
|
|
31
|
+
buyerSurname: 'Doe',
|
|
32
|
+
address: 'Test Address',
|
|
33
|
+
city: 'Istanbul',
|
|
34
|
+
country: 'Turkey',
|
|
35
|
+
zipCode: '34000'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (result.status === 'success') {
|
|
39
|
+
// Ödeme linkini doğrudan yönlendirme veya JSON yanıtı olarak döndürebilirsiniz
|
|
40
|
+
console.log('Ödeme linki oluşturuldu:', result.data.url);
|
|
41
|
+
|
|
42
|
+
// Seçenek 1: Link bilgisini JSON olarak döndür
|
|
43
|
+
res.json({
|
|
44
|
+
status: 'success',
|
|
45
|
+
redirectUrl: result.data.url,
|
|
46
|
+
token: result.data.token
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Seçenek 2: Doğrudan ödeme sayfasına yönlendir
|
|
50
|
+
// res.redirect(result.data.url);
|
|
51
|
+
} else {
|
|
52
|
+
res.status(400).json(result);
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('Ödeme hatası:', error);
|
|
56
|
+
res.status(500).json({ error: error.message });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Callback rotası
|
|
61
|
+
app.post('/iyzico-callback', quickPos.handleCallback('iyzico'), (req, res) => {
|
|
62
|
+
console.log('Ödeme sonucu:', req.paymentResult);
|
|
63
|
+
/*
|
|
64
|
+
Ödeme sonucu: Ödeme sonucu: {
|
|
65
|
+
status: 'success',
|
|
66
|
+
orderId: 'order_1742131444461',
|
|
67
|
+
amount: 100,
|
|
68
|
+
currency: 'TRY',
|
|
69
|
+
paymentId: '23770523',
|
|
70
|
+
paymentType: 'CREDIT_CARD',
|
|
71
|
+
paymentTransactionId: '2b839c1c-7fba-4580-8303-29f78c4228dd',
|
|
72
|
+
installment: 1
|
|
73
|
+
}
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
// Başarılı ödeme sonrası yönlendirme
|
|
77
|
+
if (req.paymentResult && req.paymentResult.status === 'success') {
|
|
78
|
+
res.redirect('/payment-success');
|
|
79
|
+
} else {
|
|
80
|
+
res.redirect('/payment-failed');
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Ayrıca GET isteği ile de callback'i işleyebilmek için
|
|
85
|
+
app.get('/iyzico-callback', quickPos.handleCallback('iyzico'), (req, res) => {
|
|
86
|
+
if (req.paymentResult && req.paymentResult.status === 'success') {
|
|
87
|
+
res.redirect('/payment-success');
|
|
88
|
+
} else {
|
|
89
|
+
res.redirect('/payment-failed');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
app.get('/payment-success', (req, res) => {
|
|
94
|
+
res.send('Ödeme başarıyla tamamlandı!');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
app.get('/payment-failed', (req, res) => {
|
|
98
|
+
res.send('Ödeme başarısız oldu!');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
app.listen(80, () => {
|
|
102
|
+
console.log('Server is running on port 80');
|
|
103
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// package.json'a "paymaya-integration" modülünü eklemeyi unutmayın
|
|
2
|
+
// npm install paymaya-integration
|
|
3
|
+
|
|
4
|
+
const express = require('express');
|
|
5
|
+
const bodyParser = require('body-parser');
|
|
6
|
+
const QuickPos = require('./app');
|
|
7
|
+
const PayMaya = require('./lib/paymaya');
|
|
8
|
+
|
|
9
|
+
const app = express();
|
|
10
|
+
app.use(require('multer')().none());
|
|
11
|
+
app.use(bodyParser.urlencoded({ extended: true }));
|
|
12
|
+
app.use(bodyParser.json());
|
|
13
|
+
|
|
14
|
+
const quickPos = new QuickPos({
|
|
15
|
+
providers: {
|
|
16
|
+
paymaya: {
|
|
17
|
+
publicKey: 'pk-NCLk7JeDbX1m22ZRMDYO9bEPowNWT5J4aNIKIbcTy2a', // Test public key
|
|
18
|
+
secretKey: 'sk-8MqXdZYWV9UJB92Mc0i149CtzTWT7BYBQeiarM27iAi', // Test secret key
|
|
19
|
+
isProduction: false
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
app.use(quickPos.middleware());
|
|
25
|
+
|
|
26
|
+
// Ödeme form sayfası
|
|
27
|
+
app.get('/', (req, res) => {
|
|
28
|
+
res.send(`
|
|
29
|
+
<h1>PayMaya Ödeme Testi</h1>
|
|
30
|
+
<form action="/create-payment" method="post">
|
|
31
|
+
<div>
|
|
32
|
+
<label>Ürün Adı:</label>
|
|
33
|
+
<input type="text" name="name" value="Test Ürünü" required>
|
|
34
|
+
</div>
|
|
35
|
+
<div>
|
|
36
|
+
<label>Tutar:</label>
|
|
37
|
+
<input type="number" name="amount" value="1000" required>
|
|
38
|
+
</div>
|
|
39
|
+
<div>
|
|
40
|
+
<label>Para Birimi:</label>
|
|
41
|
+
<select name="currency" required>
|
|
42
|
+
<option value="PHP">PHP</option>
|
|
43
|
+
<option value="USD">USD</option>
|
|
44
|
+
</select>
|
|
45
|
+
</div>
|
|
46
|
+
<div>
|
|
47
|
+
<label>Sipariş ID:</label>
|
|
48
|
+
<input type="text" name="orderId" value="ORDER-${Date.now()}">
|
|
49
|
+
</div>
|
|
50
|
+
<button type="submit">Ödeme Oluştur</button>
|
|
51
|
+
</form>
|
|
52
|
+
`);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Ödeme oluşturma rotası
|
|
56
|
+
app.post('/create-payment', async (req, res) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await quickPos.providers['paymaya'].createPayment({
|
|
59
|
+
name: req.body.name,
|
|
60
|
+
amount: req.body.amount,
|
|
61
|
+
currency: req.body.currency,
|
|
62
|
+
orderId: req.body.orderId,
|
|
63
|
+
successUrl: `http://${req.headers.host}/payment-callback?checkoutId=${req.body.orderId}`,
|
|
64
|
+
failureUrl: `http://${req.headers.host}/`,
|
|
65
|
+
cancelUrl: `http://${req.headers.host}/`
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (result.status === 'success') {
|
|
69
|
+
console.log('Ödeme başarıyla oluşturuldu:', result.data);
|
|
70
|
+
res.redirect(result.data.url);
|
|
71
|
+
} else {
|
|
72
|
+
res.status(400).json({ error: 'Ödeme oluşturulamadı', details: result });
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('Ödeme oluşturma hatası:', error);
|
|
76
|
+
res.status(500).json({ error: error.message });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Başarılı ödeme geri dönüş noktası
|
|
81
|
+
app.get('/payment-callback', quickPos.handleCallback('paymaya'), (req, res) => {
|
|
82
|
+
if (req.paymentResult && req.paymentResult.status === 'success') {
|
|
83
|
+
console.log('Ödeme sonucu:', req.paymentResult);
|
|
84
|
+
// Ödeme sonucu: {
|
|
85
|
+
// status: 'success',
|
|
86
|
+
// id: 'bef67078-eae7-4a13-96f3-4abb9a131444',
|
|
87
|
+
// orderId: 'ORDER-1742130974673',
|
|
88
|
+
// amount: '1000',
|
|
89
|
+
// currency: 'PHP'
|
|
90
|
+
// }
|
|
91
|
+
return res.redirect('/');
|
|
92
|
+
res.send(`<h1>Ödeme Başarılı</h1>
|
|
93
|
+
<p>Sipariş No: ${req.paymentResult.orderId}</p>
|
|
94
|
+
`);
|
|
95
|
+
} else {
|
|
96
|
+
res.status(400).json({ error: 'Ödeme başarısız', details: req.paymentResult });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Başarısız ve iptal edilen ödeme dönüş sayfaları
|
|
101
|
+
app.get('/payment-failed', (req, res) => {
|
|
102
|
+
res.send('<h1>Ödeme Başarısız</h1><p>İşlem tamamlanamadı.</p>');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
app.get('/payment-canceled', (req, res) => {
|
|
106
|
+
res.send('<h1>Ödeme İptal Edildi</h1><p>İşlem kullanıcı tarafından iptal edildi.</p>');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const PORT = process.env.PORT || 80;
|
|
110
|
+
app.listen(PORT, () => {
|
|
111
|
+
console.log(`Server ${PORT} portunda çalışıyor`);
|
|
112
|
+
});
|
package/lib/anypay.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
const { AnypayClient, crypto } = require('anypay-node');
|
|
2
|
+
|
|
3
|
+
class AnyPay {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config || {};
|
|
6
|
+
const requiredFields = ['merchantId', 'secretKey'];
|
|
7
|
+
for (let field of requiredFields) {
|
|
8
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
this.client = new AnypayClient({
|
|
12
|
+
merchantId: config.merchantId,
|
|
13
|
+
secretKey: config.secretKey,
|
|
14
|
+
apiId: config.apiId || '',
|
|
15
|
+
apiKey: config.apiKey || ''
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
this.debug = config.debug || false;
|
|
19
|
+
this.crypto = crypto; // Crypto yardımcı fonksiyonlarını dışa açalım
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async createPayment(paymentDetails) {
|
|
23
|
+
try {
|
|
24
|
+
const requiredData = ['amount', 'currency', 'orderId', 'desc'];
|
|
25
|
+
for (let data of requiredData) {
|
|
26
|
+
if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Parametre adlarını dönüştür (QuickPos -> AnyPay API)
|
|
30
|
+
const params = {
|
|
31
|
+
pay_id: paymentDetails.orderId,
|
|
32
|
+
amount: paymentDetails.amount,
|
|
33
|
+
currency: paymentDetails.currency,
|
|
34
|
+
desc: paymentDetails.desc,
|
|
35
|
+
method: paymentDetails.method || '',
|
|
36
|
+
email: paymentDetails.email || '',
|
|
37
|
+
success_url: paymentDetails.successUrl || '',
|
|
38
|
+
fail_url: paymentDetails.failUrl || '',
|
|
39
|
+
webhook_url: paymentDetails.notificationUrl || ''
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (this.debug) console.log('Creating payment with params:', params);
|
|
43
|
+
|
|
44
|
+
// Form verisi ve HTML URL'si al
|
|
45
|
+
const formData = this.client.createPaymentFormData(params);
|
|
46
|
+
|
|
47
|
+
if (this.debug) console.log('Payment form data:', formData);
|
|
48
|
+
|
|
49
|
+
// API ile ödeme oluşturma
|
|
50
|
+
if (paymentDetails.useApi) {
|
|
51
|
+
try {
|
|
52
|
+
const apiResponse = await this.client.createPayment(params);
|
|
53
|
+
if (this.debug) console.log('API payment response:', apiResponse);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
status: 'success',
|
|
57
|
+
data: {
|
|
58
|
+
url: apiResponse.payment_url,
|
|
59
|
+
id: apiResponse.id || apiResponse.transaction_id,
|
|
60
|
+
pay_id: params.pay_id,
|
|
61
|
+
amount: params.amount,
|
|
62
|
+
currency: params.currency
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
} catch (apiError) {
|
|
66
|
+
if (this.debug) console.error('API payment error:', apiError);
|
|
67
|
+
throw apiError;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Form HTML oluşturma ya da POST URL'i alma
|
|
72
|
+
if (paymentDetails.returnFormHtml) {
|
|
73
|
+
// HTML formunu döndür
|
|
74
|
+
const formHtml = this.client.createPaymentForm(params);
|
|
75
|
+
return {
|
|
76
|
+
status: 'success',
|
|
77
|
+
data: {
|
|
78
|
+
formHtml: formHtml,
|
|
79
|
+
pay_id: params.pay_id
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
} else {
|
|
83
|
+
// Doğrudan post URL'ini döndür
|
|
84
|
+
return {
|
|
85
|
+
status: 'success',
|
|
86
|
+
data: {
|
|
87
|
+
url: 'https://anypay.io/payment',
|
|
88
|
+
formData: formData,
|
|
89
|
+
pay_id: params.pay_id,
|
|
90
|
+
amount: params.amount,
|
|
91
|
+
currency: params.currency
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (this.debug) console.error('Payment creation error:', error);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
status: 'fail',
|
|
100
|
+
message: error.message || 'Unknown error'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async handleCallback(callbackData) {
|
|
106
|
+
try {
|
|
107
|
+
if (this.debug) console.log('Processing callback data:', callbackData);
|
|
108
|
+
|
|
109
|
+
if (!callbackData || !callbackData.pay_id) {
|
|
110
|
+
throw new Error('Missing required callback parameters');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// IP adresini kontrol edebiliriz (isteğe bağlı)
|
|
114
|
+
// const isValid = this.client.validateNotification(callbackData);
|
|
115
|
+
|
|
116
|
+
// if (!isValid) {
|
|
117
|
+
// throw new Error('Invalid notification signature');
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
// status "paid" ise başarılı
|
|
121
|
+
if (callbackData.status === 'paid') {
|
|
122
|
+
return {
|
|
123
|
+
status: 'success',
|
|
124
|
+
orderId: callbackData.pay_id,
|
|
125
|
+
amount: parseFloat(callbackData.amount),
|
|
126
|
+
currency: callbackData.currency,
|
|
127
|
+
transactionId: callbackData.transaction_id,
|
|
128
|
+
profit: callbackData.profit,
|
|
129
|
+
paymentMethod: callbackData.method,
|
|
130
|
+
email: callbackData.email,
|
|
131
|
+
test: callbackData.test === '1'
|
|
132
|
+
};
|
|
133
|
+
} else {
|
|
134
|
+
throw new Error(`Payment failed with status: ${callbackData.status}`);
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (this.debug) console.error('Callback handling error:', error);
|
|
138
|
+
throw new Error(`Error in AnyPay callback handling: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async getPaymentInfo(transactionId) {
|
|
143
|
+
try {
|
|
144
|
+
const payments = await this.client.getPayments({ trans_id: transactionId });
|
|
145
|
+
|
|
146
|
+
if (payments && Array.isArray(payments) && payments.length > 0) {
|
|
147
|
+
return {
|
|
148
|
+
status: 'success',
|
|
149
|
+
data: payments[0]
|
|
150
|
+
};
|
|
151
|
+
} else {
|
|
152
|
+
throw new Error('Payment not found');
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
if (this.debug) console.error('Get payment info error:', error);
|
|
156
|
+
throw new Error(`Error in AnyPay payment info: ${error.message}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async getBalance() {
|
|
161
|
+
try {
|
|
162
|
+
return await this.client.getBalance();
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (this.debug) console.error('Get balance error:', error);
|
|
165
|
+
throw new Error(`Error getting balance: ${error.message}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async getPayments(params = {}) {
|
|
170
|
+
try {
|
|
171
|
+
return await this.client.getPayments(params);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (this.debug) console.error('Get payments error:', error);
|
|
174
|
+
throw new Error(`Error getting payments: ${error.message}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async getRates() {
|
|
179
|
+
try {
|
|
180
|
+
return await this.client.getRates();
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (this.debug) console.error('Get rates error:', error);
|
|
183
|
+
throw new Error(`Error getting rates: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async getCommissions() {
|
|
188
|
+
try {
|
|
189
|
+
return await this.client.getCommissions();
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (this.debug) console.error('Get commissions error:', error);
|
|
192
|
+
throw new Error(`Error getting commissions: ${error.message}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async createPaymentForm(params) {
|
|
197
|
+
try {
|
|
198
|
+
return this.client.createPaymentForm(params);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
if (this.debug) console.error('Create payment form error:', error);
|
|
201
|
+
throw new Error(`Error creating payment form: ${error.message}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async getNotificationIPs() {
|
|
206
|
+
try {
|
|
207
|
+
return await this.client.getNotificationIPs();
|
|
208
|
+
} catch (error) {
|
|
209
|
+
if (this.debug) console.error('Get notification IPs error:', error);
|
|
210
|
+
throw new Error(`Error getting notification IPs: ${error.message}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async createPayout(params) {
|
|
215
|
+
try {
|
|
216
|
+
return await this.client.createPayout(params);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
if (this.debug) console.error('Create payout error:', error);
|
|
219
|
+
throw new Error(`Error creating payout: ${error.message}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async getPayouts(params = {}) {
|
|
224
|
+
try {
|
|
225
|
+
return await this.client.getPayouts(params);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (this.debug) console.error('Get payouts error:', error);
|
|
228
|
+
throw new Error(`Error getting payouts: ${error.message}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Form verisi ve HTML döndüren yardımcı metodlar
|
|
233
|
+
createPaymentFormData(params) {
|
|
234
|
+
return this.client.createPaymentFormData(params);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
createPaymentForm(params) {
|
|
238
|
+
return this.client.createPaymentForm(params);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
validateNotification(notification, ipAddress) {
|
|
242
|
+
return this.client.validateNotification(notification, ipAddress);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
module.exports = AnyPay;
|