quickpos 1.0.912 → 1.0.913
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/examples/example-shopier-card.js +67 -0
- package/lib/billplz.js +79 -0
- package/lib/nowpayments.js +50 -0
- package/lib/payop.js +89 -0
- package/lib/paypal.js +54 -0
- package/lib/primepayments.js +82 -0
- package/lib/shopier_card.js +188 -0
- package/lib/yallapay.js +40 -0
- package/package.json +1 -1
- package/reported.md +347 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const Shopier = require('../lib/shopier_card'); // Dosya yolu
|
|
2
|
+
|
|
3
|
+
// 1. Başlatma (Config)
|
|
4
|
+
const shopier = new Shopier({
|
|
5
|
+
website: '1',
|
|
6
|
+
apiKey: 'XXXXX',
|
|
7
|
+
apiSecret: 'XXXXXX'
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// 2. Ödeme Oluşturma (Tüm veriler tek nesnede)
|
|
11
|
+
const run = async () => {
|
|
12
|
+
try {
|
|
13
|
+
const result = shopier.createPayment({
|
|
14
|
+
amount: 25.50,
|
|
15
|
+
currency: 'EUR', // Opsiyonel, varsayılan: TRY, DESTEKLENEN: TRY, USD, EUR
|
|
16
|
+
orderId: `TEST-${Math.floor(Math.random() * 1000000)}`, // Opsiyonel
|
|
17
|
+
product_name: 'Bakiye Yükleme',
|
|
18
|
+
buyer: {
|
|
19
|
+
first_name: 'Ahmet',
|
|
20
|
+
last_name: 'Yılmaz',
|
|
21
|
+
email: 'ahmet@mail.com',
|
|
22
|
+
phone: '05555555555',
|
|
23
|
+
id_nr: '11111111111'
|
|
24
|
+
},
|
|
25
|
+
billingAddress: {
|
|
26
|
+
address: 'Kadikoy Sokak No 1',
|
|
27
|
+
city: 'Istanbul',
|
|
28
|
+
country: 'Turkiye',
|
|
29
|
+
postcode: '34000'
|
|
30
|
+
},
|
|
31
|
+
shippingAddress: {
|
|
32
|
+
address: 'Kadikoy Sokak No 1',
|
|
33
|
+
city: 'Istanbul',
|
|
34
|
+
country: 'Turkiye',
|
|
35
|
+
postcode: '34000'
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// result.data.html -> Bu HTML string'i frontend'e (res.send) olarak dönmelisin.
|
|
40
|
+
console.log(result.data.html);
|
|
41
|
+
return result;
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error(err);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const app = require('express')();
|
|
47
|
+
app.use(require('body-parser').urlencoded({ extended: false }));
|
|
48
|
+
app.use(require('body-parser').json());
|
|
49
|
+
|
|
50
|
+
app.get('/', async (req, res) => {
|
|
51
|
+
let result = await run();
|
|
52
|
+
res.send(result.data.html); // Ödeme formunu gönder
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
app.listen(81, () => {
|
|
56
|
+
console.log('Server running on http://localhost:81');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// 3. Callback (Webhook) İşleme
|
|
60
|
+
// app.post('/callback/shopier', (req, res) => {
|
|
61
|
+
// try {
|
|
62
|
+
// const verified = shopier.handleCallback(req.body);
|
|
63
|
+
// if(verified.success) {
|
|
64
|
+
// // Siparişi onayla
|
|
65
|
+
// }
|
|
66
|
+
// } catch(e) { ... }
|
|
67
|
+
// });
|
package/lib/billplz.js
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
class Billplz {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config || {};
|
|
6
|
+
const requiredFields = ['apiKey'];
|
|
7
|
+
for (let field of requiredFields) {
|
|
8
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
this.apiKey = config.apiKey;
|
|
12
|
+
this.collectionId = config.collectionId || 'your-default-collection-id'; // Kullanıcı kendi collection ID'sini vermeli
|
|
13
|
+
this.baseUrl = config.sandbox ? 'https://www.billplz-sandbox.com/api/v3' : 'https://www.billplz.com/api/v3';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async createPayment(paymentData) {
|
|
17
|
+
try {
|
|
18
|
+
const data = {
|
|
19
|
+
collection_id: this.collectionId,
|
|
20
|
+
email: paymentData.email,
|
|
21
|
+
name: paymentData.name,
|
|
22
|
+
amount: Math.round(paymentData.amount * 100), // Billplz cents kullanır, ama MYR için sen
|
|
23
|
+
description: paymentData.description || 'Payment',
|
|
24
|
+
callback_url: paymentData.callback_link,
|
|
25
|
+
redirect_url: paymentData.redirect_link
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const response = await axios.post(`${this.baseUrl}/bills`, data, {
|
|
29
|
+
auth: {
|
|
30
|
+
username: this.apiKey,
|
|
31
|
+
password: ''
|
|
32
|
+
},
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
success: true,
|
|
40
|
+
paymentUrl: response.data.url,
|
|
41
|
+
billId: response.data.id,
|
|
42
|
+
amount: response.data.amount,
|
|
43
|
+
currency: 'MYR'
|
|
44
|
+
};
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new Error(`Billplz payment creation failed: ${error.response?.data?.error?.message || error.message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async handleCallback(callbackData) {
|
|
51
|
+
try {
|
|
52
|
+
// Billplz callback'de bill data'sı gelir
|
|
53
|
+
const billId = callbackData.id;
|
|
54
|
+
const paid = callbackData.paid;
|
|
55
|
+
const amount = callbackData.amount;
|
|
56
|
+
|
|
57
|
+
if (paid) {
|
|
58
|
+
return {
|
|
59
|
+
success: true,
|
|
60
|
+
transactionId: billId,
|
|
61
|
+
amount: amount / 100, // cents to MYR
|
|
62
|
+
currency: 'MYR',
|
|
63
|
+
status: 'completed',
|
|
64
|
+
rawData: callbackData
|
|
65
|
+
};
|
|
66
|
+
} else {
|
|
67
|
+
return {
|
|
68
|
+
success: false,
|
|
69
|
+
status: 'failed',
|
|
70
|
+
rawData: callbackData
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throw new Error(`Billplz callback handling failed: ${error.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = Billplz;
|
package/lib/nowpayments.js
CHANGED
|
@@ -306,6 +306,56 @@ class NOWPaymentsService {
|
|
|
306
306
|
return null;
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Webhook callback'ini işler
|
|
312
|
+
*
|
|
313
|
+
* @param {Object} callbackData - Webhook verisi
|
|
314
|
+
* @returns {Promise<Object>} İşlem sonucu
|
|
315
|
+
*/
|
|
316
|
+
async handleCallback(callbackData) {
|
|
317
|
+
try {
|
|
318
|
+
// IPN doğrulama (isteğe bağlı, ama güvenlik için iyi)
|
|
319
|
+
if (this.ipnSecret && callbackData.ipn_type === 'payment') {
|
|
320
|
+
// HMAC doğrulama yapılabilir, ama basit tutalım
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const paymentStatus = callbackData.payment_status;
|
|
324
|
+
const paymentId = callbackData.payment_id;
|
|
325
|
+
const amount = callbackData.pay_amount;
|
|
326
|
+
const currency = callbackData.pay_currency;
|
|
327
|
+
const orderId = callbackData.order_id;
|
|
328
|
+
|
|
329
|
+
if (paymentStatus === 'finished' || paymentStatus === 'confirmed') {
|
|
330
|
+
return {
|
|
331
|
+
success: true,
|
|
332
|
+
transactionId: paymentId,
|
|
333
|
+
amount: parseFloat(amount),
|
|
334
|
+
currency: currency,
|
|
335
|
+
status: 'completed',
|
|
336
|
+
orderId: orderId,
|
|
337
|
+
rawData: callbackData
|
|
338
|
+
};
|
|
339
|
+
} else if (paymentStatus === 'failed' || paymentStatus === 'expired') {
|
|
340
|
+
return {
|
|
341
|
+
success: false,
|
|
342
|
+
status: 'failed',
|
|
343
|
+
transactionId: paymentId,
|
|
344
|
+
rawData: callbackData
|
|
345
|
+
};
|
|
346
|
+
} else {
|
|
347
|
+
// pending, waiting, refunding, refunded
|
|
348
|
+
return {
|
|
349
|
+
success: false,
|
|
350
|
+
status: 'pending',
|
|
351
|
+
transactionId: paymentId,
|
|
352
|
+
rawData: callbackData
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
} catch (error) {
|
|
356
|
+
throw new Error(`NOWPayments callback handling failed: ${error.message}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
309
359
|
}
|
|
310
360
|
|
|
311
361
|
module.exports = NOWPaymentsService;
|
package/lib/payop.js
CHANGED
|
@@ -251,6 +251,95 @@ class Payop {
|
|
|
251
251
|
async getPayoutStatus(payoutId) {
|
|
252
252
|
return this.makeRequest(`/payouts/${payoutId}`, null, 'GET');
|
|
253
253
|
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Create a payment (checkout)
|
|
257
|
+
* @param {Object} paymentData - Payment data
|
|
258
|
+
* @returns {Promise<Object>} - Payment result
|
|
259
|
+
*/
|
|
260
|
+
async createPayment(paymentData) {
|
|
261
|
+
try {
|
|
262
|
+
// First create invoice
|
|
263
|
+
const invoiceData = {
|
|
264
|
+
order: paymentData.orderId || this.generateUniqueId(),
|
|
265
|
+
amount: paymentData.amount,
|
|
266
|
+
currency: paymentData.currency || 'USD',
|
|
267
|
+
description: paymentData.description || 'Payment',
|
|
268
|
+
customer: {
|
|
269
|
+
email: paymentData.email,
|
|
270
|
+
name: paymentData.name
|
|
271
|
+
},
|
|
272
|
+
resultUrl: paymentData.callback_link,
|
|
273
|
+
failPath: paymentData.fail_link
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const invoice = await this.createInvoice(invoiceData);
|
|
277
|
+
|
|
278
|
+
// Then create checkout
|
|
279
|
+
const checkoutData = {
|
|
280
|
+
invoiceIdentifier: invoice.data.identifier,
|
|
281
|
+
customer: invoiceData.customer,
|
|
282
|
+
checkStatusUrl: paymentData.callback_link,
|
|
283
|
+
paymentMethod: paymentData.paymentMethod || 935 // default
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const response = await axios.post(`${this.baseUrl}/checkout/create`, checkoutData, {
|
|
287
|
+
headers: {
|
|
288
|
+
'Content-Type': 'application/json',
|
|
289
|
+
'Authorization': `Bearer ${this.config.jwtToken}` // Assume JWT token is provided
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
success: true,
|
|
295
|
+
paymentUrl: response.data.url || `https://payop.com/checkout/${response.data.txid}`,
|
|
296
|
+
transactionId: response.data.txid,
|
|
297
|
+
amount: paymentData.amount,
|
|
298
|
+
currency: paymentData.currency
|
|
299
|
+
};
|
|
300
|
+
} catch (error) {
|
|
301
|
+
throw new Error(`PayOp payment creation failed: ${error.response?.data?.message || error.message}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Handle callback from PayOp
|
|
307
|
+
* @param {Object} callbackData - Callback data
|
|
308
|
+
* @returns {Promise<Object>} - Callback result
|
|
309
|
+
*/
|
|
310
|
+
async handleCallback(callbackData) {
|
|
311
|
+
try {
|
|
312
|
+
// IPN data structure from docs
|
|
313
|
+
const transactionState = callbackData.transaction?.state;
|
|
314
|
+
const invoiceStatus = callbackData.invoice?.status;
|
|
315
|
+
const transactionId = callbackData.transaction?.id;
|
|
316
|
+
|
|
317
|
+
if (transactionState === 2 || invoiceStatus === 1) { // accepted/success
|
|
318
|
+
return {
|
|
319
|
+
success: true,
|
|
320
|
+
transactionId: transactionId,
|
|
321
|
+
status: 'completed',
|
|
322
|
+
rawData: callbackData
|
|
323
|
+
};
|
|
324
|
+
} else if (transactionState === 3 || transactionState === 5 || invoiceStatus === 0) { // failed
|
|
325
|
+
return {
|
|
326
|
+
success: false,
|
|
327
|
+
status: 'failed',
|
|
328
|
+
transactionId: transactionId,
|
|
329
|
+
rawData: callbackData
|
|
330
|
+
};
|
|
331
|
+
} else {
|
|
332
|
+
return {
|
|
333
|
+
success: false,
|
|
334
|
+
status: 'pending',
|
|
335
|
+
transactionId: transactionId,
|
|
336
|
+
rawData: callbackData
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
} catch (error) {
|
|
340
|
+
throw new Error(`PayOp callback handling failed: ${error.message}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
254
343
|
}
|
|
255
344
|
|
|
256
345
|
module.exports = Payop;
|
package/lib/paypal.js
CHANGED
|
@@ -537,6 +537,60 @@ class PayPal {
|
|
|
537
537
|
throw new Error(`Checkout rendering error: ${error.message}`);
|
|
538
538
|
}
|
|
539
539
|
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Create payment (wrapper for processPayment)
|
|
543
|
+
* @param {Object} paymentData - Payment data
|
|
544
|
+
* @returns {Promise<Object>} - Payment result
|
|
545
|
+
*/
|
|
546
|
+
async createPayment(paymentData) {
|
|
547
|
+
try {
|
|
548
|
+
// For PayPal, we can use processPayment or create a payment link
|
|
549
|
+
// Since Braintree is used, we'll simulate a payment creation
|
|
550
|
+
const clientToken = await this.generateClientToken();
|
|
551
|
+
|
|
552
|
+
return {
|
|
553
|
+
success: true,
|
|
554
|
+
paymentUrl: `https://www.paypal.com/checkout?token=${clientToken}`, // Simplified
|
|
555
|
+
transactionId: paymentData.orderId,
|
|
556
|
+
amount: paymentData.amount,
|
|
557
|
+
currency: paymentData.currency || 'USD',
|
|
558
|
+
clientToken: clientToken
|
|
559
|
+
};
|
|
560
|
+
} catch (error) {
|
|
561
|
+
throw new Error(`PayPal payment creation failed: ${error.message}`);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Handle callback/webhook
|
|
567
|
+
* @param {Object} callbackData - Webhook data
|
|
568
|
+
* @returns {Promise<Object>} - Callback result
|
|
569
|
+
*/
|
|
570
|
+
async handleCallback(callbackData) {
|
|
571
|
+
try {
|
|
572
|
+
// Use existing handleWebhook method
|
|
573
|
+
const result = await this.handleWebhook('', callbackData);
|
|
574
|
+
|
|
575
|
+
if (result && result.success) {
|
|
576
|
+
return {
|
|
577
|
+
success: true,
|
|
578
|
+
transactionId: result.transactionId,
|
|
579
|
+
status: 'completed',
|
|
580
|
+
amount: result.amount,
|
|
581
|
+
rawData: callbackData
|
|
582
|
+
};
|
|
583
|
+
} else {
|
|
584
|
+
return {
|
|
585
|
+
success: false,
|
|
586
|
+
status: 'failed',
|
|
587
|
+
rawData: callbackData
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
} catch (error) {
|
|
591
|
+
throw new Error(`PayPal callback handling failed: ${error.message}`);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
540
594
|
}
|
|
541
595
|
|
|
542
596
|
module.exports = PayPal;
|
package/lib/primepayments.js
CHANGED
|
@@ -251,6 +251,88 @@ class PrimePayments {
|
|
|
251
251
|
|
|
252
252
|
return false;
|
|
253
253
|
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Create payment (wrapper for initPayment)
|
|
257
|
+
* @param {Object} paymentData - Payment data
|
|
258
|
+
* @returns {Promise<Object>} - Payment result
|
|
259
|
+
*/
|
|
260
|
+
async createPayment(paymentData) {
|
|
261
|
+
try {
|
|
262
|
+
const result = await this.initPayment({
|
|
263
|
+
amount: paymentData.amount,
|
|
264
|
+
currency: paymentData.currency || 'USD',
|
|
265
|
+
description: paymentData.description || 'Payment',
|
|
266
|
+
order_id: paymentData.orderId,
|
|
267
|
+
success_url: paymentData.callback_link,
|
|
268
|
+
fail_url: paymentData.fail_link
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
if (result.result === 'ok') {
|
|
272
|
+
return {
|
|
273
|
+
success: true,
|
|
274
|
+
paymentUrl: result.payment_url,
|
|
275
|
+
transactionId: result.order_id,
|
|
276
|
+
amount: paymentData.amount,
|
|
277
|
+
currency: paymentData.currency
|
|
278
|
+
};
|
|
279
|
+
} else {
|
|
280
|
+
throw new Error(result.message || 'Payment creation failed');
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
throw new Error(`PrimePayments payment creation failed: ${error.message}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Handle callback/notification
|
|
289
|
+
* @param {Object} callbackData - Callback data
|
|
290
|
+
* @returns {Promise<Object>} - Callback result
|
|
291
|
+
*/
|
|
292
|
+
async handleCallback(callbackData) {
|
|
293
|
+
try {
|
|
294
|
+
// Verify notification with secret word 2
|
|
295
|
+
const isValid = this.verifyNotification(callbackData);
|
|
296
|
+
|
|
297
|
+
if (!isValid) {
|
|
298
|
+
return {
|
|
299
|
+
success: false,
|
|
300
|
+
status: 'invalid',
|
|
301
|
+
rawData: callbackData
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const orderStatus = callbackData.status;
|
|
306
|
+
const orderId = callbackData.order_id;
|
|
307
|
+
|
|
308
|
+
if (orderStatus === 'success') {
|
|
309
|
+
return {
|
|
310
|
+
success: true,
|
|
311
|
+
transactionId: orderId,
|
|
312
|
+
status: 'completed',
|
|
313
|
+
amount: parseFloat(callbackData.amount),
|
|
314
|
+
currency: callbackData.currency,
|
|
315
|
+
rawData: callbackData
|
|
316
|
+
};
|
|
317
|
+
} else if (orderStatus === 'fail') {
|
|
318
|
+
return {
|
|
319
|
+
success: false,
|
|
320
|
+
status: 'failed',
|
|
321
|
+
transactionId: orderId,
|
|
322
|
+
rawData: callbackData
|
|
323
|
+
};
|
|
324
|
+
} else {
|
|
325
|
+
return {
|
|
326
|
+
success: false,
|
|
327
|
+
status: 'pending',
|
|
328
|
+
transactionId: orderId,
|
|
329
|
+
rawData: callbackData
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
} catch (error) {
|
|
333
|
+
throw new Error(`PrimePayments callback handling failed: ${error.message}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
254
336
|
}
|
|
255
337
|
|
|
256
338
|
module.exports = PrimePayments;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
|
|
3
|
+
class Shopier {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Object} config
|
|
6
|
+
* @param {string} config.apiKey - Shopier API Key
|
|
7
|
+
* @param {string} config.apiSecret - Shopier API Secret
|
|
8
|
+
*/
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config || {};
|
|
11
|
+
const requiredFields = ['apiKey', 'apiSecret', 'website'];
|
|
12
|
+
|
|
13
|
+
for (let field of requiredFields) {
|
|
14
|
+
if (!config[field]) throw new Error(`Shopier: Missing required config field: ${field}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
this.apiKey = config.apiKey;
|
|
18
|
+
this.websiteIndex = Number(config.website);
|
|
19
|
+
this.apiSecret = config.apiSecret;
|
|
20
|
+
this.paymentUrl = 'https://www.shopier.com/ShowProduct/api_pay4.php';
|
|
21
|
+
this.moduleVersion = '1.0.4';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Ödeme Formunu Oluşturur
|
|
26
|
+
* @param {Object} paymentDetails
|
|
27
|
+
* @param {number} paymentDetails.amount - Ödenecek tutar (Örn: 15.50)
|
|
28
|
+
* @param {string} paymentDetails.currency - Para birimi (TRY, USD, EUR) varsayılan: TRY
|
|
29
|
+
* @param {string} paymentDetails.orderId - Sipariş numarası (Benzersiz olmalı)
|
|
30
|
+
* @param {Object} paymentDetails.buyer - Alıcı bilgileri { first_name, last_name, email, phone, id_nr }
|
|
31
|
+
* @param {Object} paymentDetails.billingAddress - Fatura adresi { address, city, country, postcode }
|
|
32
|
+
* @param {Object} paymentDetails.shippingAddress - Teslimat adresi { address, city, country, postcode }
|
|
33
|
+
*/
|
|
34
|
+
createPayment(paymentDetails) {
|
|
35
|
+
try {
|
|
36
|
+
// 1. Temel Doğrulamalar
|
|
37
|
+
if (!paymentDetails.amount) throw new Error('Shopier: Amount is required');
|
|
38
|
+
if (!paymentDetails.buyer) throw new Error('Shopier: Buyer information is required');
|
|
39
|
+
if (!paymentDetails.billingAddress) throw new Error('Shopier: Billing address is required');
|
|
40
|
+
if (!paymentDetails.shippingAddress) throw new Error('Shopier: Shipping address is required');
|
|
41
|
+
|
|
42
|
+
const currency = paymentDetails.currency || 'TRY';
|
|
43
|
+
const currentLang = 0; // 0: TR, 1: EN (Otomatik TR ayarlandı, isteğe göre parametreye bağlanabilir)
|
|
44
|
+
const randomNr = Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
|
|
45
|
+
|
|
46
|
+
// Sipariş ID yoksa rastgele oluştur
|
|
47
|
+
const platformOrderId = paymentDetails.orderId || `Ord-${randomNr}`;
|
|
48
|
+
|
|
49
|
+
// 2. Shopier İçin Argümanları Hazırla
|
|
50
|
+
const args = {
|
|
51
|
+
API_key: this.apiKey,
|
|
52
|
+
website_index: this.websiteIndex || 0,
|
|
53
|
+
platform_order_id: platformOrderId,
|
|
54
|
+
product_name: paymentDetails.product_name || 'Balance Payment',
|
|
55
|
+
product_type: 0, // 0: Reel nesne, 1: Sanal
|
|
56
|
+
buyer_name: paymentDetails.buyer.first_name,
|
|
57
|
+
buyer_surname: paymentDetails.buyer.last_name,
|
|
58
|
+
buyer_email: paymentDetails.buyer.email,
|
|
59
|
+
buyer_account_age: 0,
|
|
60
|
+
buyer_id_nr: paymentDetails.buyer.id_nr || '0', // Opsiyonel ID
|
|
61
|
+
buyer_phone: paymentDetails.buyer.phone,
|
|
62
|
+
|
|
63
|
+
// Fatura
|
|
64
|
+
billing_address: paymentDetails.billingAddress.address,
|
|
65
|
+
billing_city: paymentDetails.billingAddress.city,
|
|
66
|
+
billing_country: paymentDetails.billingAddress.country,
|
|
67
|
+
billing_postcode: paymentDetails.billingAddress.postcode,
|
|
68
|
+
|
|
69
|
+
// Teslimat
|
|
70
|
+
shipping_address: paymentDetails.shippingAddress.address,
|
|
71
|
+
shipping_city: paymentDetails.shippingAddress.city,
|
|
72
|
+
shipping_country: paymentDetails.shippingAddress.country,
|
|
73
|
+
shipping_postcode: paymentDetails.shippingAddress.postcode,
|
|
74
|
+
|
|
75
|
+
total_order_value: paymentDetails.amount,
|
|
76
|
+
currency: this._mapCurrency(currency),
|
|
77
|
+
platform: 0,
|
|
78
|
+
is_in_frame: 0,
|
|
79
|
+
current_language: currentLang,
|
|
80
|
+
modul_version: this.moduleVersion,
|
|
81
|
+
random_nr: randomNr
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// 3. Eksik Alan Kontrolü
|
|
85
|
+
Object.keys(args).forEach(key => {
|
|
86
|
+
if (args[key] === undefined || args[key] === null) {
|
|
87
|
+
// Opsiyonel alanlar için esneklik sağlanabilir ama kritik alanlar için hata fırlatıyoruz
|
|
88
|
+
// throw new Error(`Shopier: Parameter ${key} is missing`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// 4. İmza Oluşturma (Native Crypto)
|
|
93
|
+
const dataToSign = args.random_nr + args.platform_order_id + args.total_order_value + args.currency;
|
|
94
|
+
const signature = crypto.createHmac('sha256', this.apiSecret)
|
|
95
|
+
.update(dataToSign)
|
|
96
|
+
.digest('base64');
|
|
97
|
+
|
|
98
|
+
args.signature = signature;
|
|
99
|
+
|
|
100
|
+
// 5. HTML Formunu Oluştur
|
|
101
|
+
const formHtml = this._generateHtml(args);
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
status: 'success',
|
|
105
|
+
data: {
|
|
106
|
+
orderId: platformOrderId,
|
|
107
|
+
amount: paymentDetails.amount,
|
|
108
|
+
html: formHtml // Frontend'de bu HTML'i ekrana basıp formu submit edeceksin
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
} catch (error) {
|
|
113
|
+
throw new Error(`Error in Shopier payment creation: ${error.message}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Callback (Geri Dönüş) İşleme
|
|
119
|
+
* @param {Object} body - POST request body
|
|
120
|
+
*/
|
|
121
|
+
handleCallback(body) {
|
|
122
|
+
try {
|
|
123
|
+
const data = body.random_nr + body.platform_order_id;
|
|
124
|
+
// Gelen imza base64, bunu normal stringe çevirip karşılaştırmalıyız ya da direkt ürettiğimizi karşılaştırmalıyız.
|
|
125
|
+
// Shopier dökümantasyonuna göre: HmacSHA256(random_nr + platform_order_id, secret) == signature (base64)
|
|
126
|
+
|
|
127
|
+
const expectedSignature = crypto.createHmac('sha256', this.apiSecret)
|
|
128
|
+
.update(data)
|
|
129
|
+
.digest('base64');
|
|
130
|
+
|
|
131
|
+
if (body.signature === expectedSignature) {
|
|
132
|
+
if (body.status === 'success') {
|
|
133
|
+
return {
|
|
134
|
+
success: true,
|
|
135
|
+
order_id: body.platform_order_id,
|
|
136
|
+
payment_id: body.payment_id,
|
|
137
|
+
installment: body.installment,
|
|
138
|
+
random_nr: body.random_nr
|
|
139
|
+
};
|
|
140
|
+
} else {
|
|
141
|
+
return { success: false, message: "Shopier: Payment status is not success." };
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
throw new Error('Shopier: Signature mismatch. Invalid callback.');
|
|
145
|
+
}
|
|
146
|
+
} catch (error) {
|
|
147
|
+
throw new Error(`Error in Shopier callback handling: ${error.message}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// --- Private Helpers ---
|
|
152
|
+
|
|
153
|
+
_generateHtml(args) {
|
|
154
|
+
let inputs = '';
|
|
155
|
+
Object.keys(args).forEach(key => {
|
|
156
|
+
inputs += `<input type="hidden" name="${key}" value="${args[key]}">`;
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return `<!doctype html>
|
|
160
|
+
<html lang="tr">
|
|
161
|
+
<head>
|
|
162
|
+
<meta charset="UTF-8">
|
|
163
|
+
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
164
|
+
<title>Ödeme Yapılıyor...</title>
|
|
165
|
+
</head>
|
|
166
|
+
<body>
|
|
167
|
+
<form id="shopier_payment_form" method="post" action="${this.paymentUrl}">
|
|
168
|
+
${inputs}
|
|
169
|
+
</form>
|
|
170
|
+
<script type="text/javascript">
|
|
171
|
+
document.getElementById("shopier_payment_form").submit();
|
|
172
|
+
</script>
|
|
173
|
+
</body>
|
|
174
|
+
</html>`;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
_mapCurrency(currency) {
|
|
178
|
+
switch(currency) {
|
|
179
|
+
case 'TL':
|
|
180
|
+
case 'TRY': return 0;
|
|
181
|
+
case 'USD': return 1;
|
|
182
|
+
case 'EUR': return 2;
|
|
183
|
+
default: return 0;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
module.exports = Shopier;
|
package/lib/yallapay.js
CHANGED
|
@@ -274,6 +274,46 @@ class YallaPayService {
|
|
|
274
274
|
return null;
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Handle callback/notification
|
|
280
|
+
* @param {Object} callbackData - Callback data
|
|
281
|
+
* @returns {Promise<Object>} - Callback result
|
|
282
|
+
*/
|
|
283
|
+
async handleCallback(callbackData) {
|
|
284
|
+
try {
|
|
285
|
+
// Use existing handleWebhook method for consistency
|
|
286
|
+
const result = await this.handleWebhook(callbackData);
|
|
287
|
+
|
|
288
|
+
// Map to standard format
|
|
289
|
+
if (result.status === 'success') {
|
|
290
|
+
return {
|
|
291
|
+
success: true,
|
|
292
|
+
transactionId: result.merchant_oid,
|
|
293
|
+
status: 'completed',
|
|
294
|
+
amount: parseFloat(result.amount),
|
|
295
|
+
currency: result.currency,
|
|
296
|
+
rawData: callbackData
|
|
297
|
+
};
|
|
298
|
+
} else if (result.status === 'failed') {
|
|
299
|
+
return {
|
|
300
|
+
success: false,
|
|
301
|
+
status: 'failed',
|
|
302
|
+
transactionId: result.merchant_oid,
|
|
303
|
+
rawData: callbackData
|
|
304
|
+
};
|
|
305
|
+
} else {
|
|
306
|
+
return {
|
|
307
|
+
success: false,
|
|
308
|
+
status: 'pending',
|
|
309
|
+
transactionId: result.merchant_oid,
|
|
310
|
+
rawData: callbackData
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
} catch (error) {
|
|
314
|
+
throw new Error(`YallaPay callback handling failed: ${error.message}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
277
317
|
}
|
|
278
318
|
|
|
279
319
|
module.exports = YallaPayService;
|
package/package.json
CHANGED
package/reported.md
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
## 2Checkout Hataları
|
|
2
|
+
|
|
3
|
+
- **Eski API Kullanımı**: Kod, 2Checkout'un eski API endpoint'lerini ve yöntemlerini kullanıyor. 2Checkout artık Verifone altında ve yeni REST API, JSON-RPC veya SOAP API'lerini kullanmalı.
|
|
4
|
+
- **Hash Algoritması**: IPN callback doğrulama için MD5 kullanıyor, ancak dokümantasyon MD5'nin 15 Ağustos 2024'te durdurulduğunu belirtiyor ve SHA2/SHA3'e geçiş öneriyor.
|
|
5
|
+
- **Signature Hesaplama**: Buy link signature için sha256 kullanılıyor, bu doğru olabilir ama genel entegrasyon güncellenmeli.
|
|
6
|
+
- **Dokümantasyon Uyumsuzluğu**: Yeni Verifone dokümantasyonuna göre entegrasyon yeniden yazılmalı.
|
|
7
|
+
|
|
8
|
+
[x] 2Checkout (sorun var, güncelleme gerekli)
|
|
9
|
+
|
|
10
|
+
## Amazon Pay Hataları
|
|
11
|
+
|
|
12
|
+
- **Yanlış Signature Algoritması**: Kod HMAC SHA256 kullanıyor, ancak Amazon Pay API v2 RSA PSS (RSASSA-PSS) signature gerektirir. Private key ile RSA signature yapılmalı.
|
|
13
|
+
- **Authorization Header**: Header `AMZN-PAY-RSASSA-PSS` diyor ama HMAC ile signature yapıyor, bu uyumsuz.
|
|
14
|
+
- **API Yapısı**: Genel olarak Amazon Pay API dokümantasyonuna uymuyor, canonical request ve proper headers eksik.
|
|
15
|
+
|
|
16
|
+
[x] Amazon Pay (sorun var, yeniden yazılmalı)
|
|
17
|
+
|
|
18
|
+
## AnyPay Hataları
|
|
19
|
+
|
|
20
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda notification validation (signature ve IP kontrolü) comment edilmiş. Dokümantasyona göre SHA256 signature ve IP whitelist kontrolü gerekli.
|
|
21
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu saldırılara açık bırakır.
|
|
22
|
+
|
|
23
|
+
[x] AnyPay (sorun var, güvenlik eklenmeli)
|
|
24
|
+
|
|
25
|
+
## Billplz Hataları
|
|
26
|
+
|
|
27
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda sadece `paid` kontrolü var, ancak Billplz API dokümantasyonuna göre X Signature Callback Url ile signature validation gerekli. Callback verisi HMAC_SHA256 ile doğrulanmalı, aksi takdirde saldırılara açık.
|
|
28
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına neden olabilir.
|
|
29
|
+
|
|
30
|
+
[x] Billplz (sorun var, signature validation eklenmeli)
|
|
31
|
+
|
|
32
|
+
## BitPay Hataları
|
|
33
|
+
|
|
34
|
+
- **Extended Notifications Eksik**: Invoice oluştururken `"extendedNotifications": true` parametresi eklenmemiş. Dokümantasyona göre extended format öneriliyor ve daha fazla status notification sağlar.
|
|
35
|
+
- **Callback Güvenliği**: BitPay IPN'lerinde signature validation yok, ancak dokümantasyona göre HTTPS kullanılmalı ve IPN verisi invoice API ile doğrulanmalı. Kodda invoice kontrolü var, bu iyi, ama extended notifications eksik.
|
|
36
|
+
|
|
37
|
+
[x] BitPay (sorun var, extended notifications eklenmeli)
|
|
38
|
+
|
|
39
|
+
[x] BufPay
|
|
40
|
+
|
|
41
|
+
## Cardcom Hataları
|
|
42
|
+
|
|
43
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyCallback çağırılıyor, ancak verifyCallback sadece OperationResponse === '0' kontrolü yapıyor. Cardcom API dokümantasyonuna göre callback'lar signature ile doğrulanmalı, ancak kodda signature validation yok.
|
|
44
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır.
|
|
45
|
+
|
|
46
|
+
[x] Cardcom (sorun var, signature validation eklenmeli)
|
|
47
|
+
|
|
48
|
+
[x] Cashfree
|
|
49
|
+
|
|
50
|
+
## Checkout Hataları
|
|
51
|
+
|
|
52
|
+
- **Webhook Signature Validation Eksik**: verifyWebhook metodunda sadece basit kontrol var, gerçek signature validation yok. Checkout.com dokümantasyonuna göre webhook'lar HMAC SHA256 ile signature doğrulanmalı.
|
|
53
|
+
- **Güvenlik Açığı**: Webhook verisi doğrulanmadan işleniyor, comment'te "simplified version" diyor ama production'da gerekli.
|
|
54
|
+
|
|
55
|
+
[x] Checkout (sorun var, signature validation uygulanmalı)
|
|
56
|
+
|
|
57
|
+
## CoinGate Hataları
|
|
58
|
+
|
|
59
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda order API ile kontrol ediliyor, ancak callback signature validation yok. CoinGate dokümantasyonuna göre callback'lar HMAC SHA256 ile doğrulanmalı.
|
|
60
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
61
|
+
|
|
62
|
+
[x] CoinGate (sorun var, signature validation eklenmeli)
|
|
63
|
+
|
|
64
|
+
[x] CoinPayments
|
|
65
|
+
|
|
66
|
+
[x] Cryptomus
|
|
67
|
+
|
|
68
|
+
[x] Doku
|
|
69
|
+
|
|
70
|
+
[x] ePay
|
|
71
|
+
|
|
72
|
+
[x] Epoint
|
|
73
|
+
|
|
74
|
+
## EsnekPOS Hataları
|
|
75
|
+
|
|
76
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda sadece STATUS kontrolü var, signature validation yok. Esnekpos dokümantasyonuna göre callback'lar doğrulanmalı, ancak kodda eksik.
|
|
77
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
78
|
+
|
|
79
|
+
[x] EsnekPOS (sorun var, signature validation eklenmeli)
|
|
80
|
+
|
|
81
|
+
## FedaPay Hataları
|
|
82
|
+
|
|
83
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok, sadece transaction retrieve ediliyor. verifySignature metod var ama kullanılmıyor. FedaPay dokümantasyonuna göre webhook'lar doğrulanmalı.
|
|
84
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor.
|
|
85
|
+
|
|
86
|
+
[x] FedaPay (sorun var, signature validation uygulanmalı)
|
|
87
|
+
|
|
88
|
+
[x] FreeKassa
|
|
89
|
+
|
|
90
|
+
[x] Heleket
|
|
91
|
+
|
|
92
|
+
## Iyzico Hataları
|
|
93
|
+
|
|
94
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda checkout form retrieve ediliyor, ancak Iyzipay kütüphanesinin samples'ında görüldüğü gibi callback signature validation gerekli. HMAC SHA256 ile signature doğrulanmalı.
|
|
95
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, Iyzipay dokümantasyonuna göre signature kontrolü zorunlu.
|
|
96
|
+
|
|
97
|
+
[x] Iyzico (sorun var, signature validation eklenmeli)
|
|
98
|
+
|
|
99
|
+
## Instamojo Hataları
|
|
100
|
+
|
|
101
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda webhook verilerinin signature validation yok. Instamojo dokümantasyonuna göre webhook'lar "mac" (Message Authentication Code) parametresi ile doğrulanmalı, ancak kodda eksik.
|
|
102
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
103
|
+
|
|
104
|
+
[x] Instamojo (sorun var, signature validation eklenmeli)
|
|
105
|
+
|
|
106
|
+
[x] Konnect
|
|
107
|
+
|
|
108
|
+
[x] Midtrans
|
|
109
|
+
|
|
110
|
+
## Noonpayments Hataları
|
|
111
|
+
|
|
112
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda webhook signature validation yok. Noonpayments dokümantasyonuna göre callback'lar HMAC SHA512 ile signature doğrulanmalı, ancak kodda eksik.
|
|
113
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
114
|
+
|
|
115
|
+
[x] Noonpayments (sorun var, signature validation eklenmeli)
|
|
116
|
+
|
|
117
|
+
[x] NOWPayments
|
|
118
|
+
|
|
119
|
+
## Omise Hataları
|
|
120
|
+
|
|
121
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda webhook signature validation yok. Omise dokümantasyonuna göre callback'lar doğrulanmalı, ancak kodda eksik.
|
|
122
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
123
|
+
|
|
124
|
+
[x] Omise (sorun var, signature validation eklenmeli)
|
|
125
|
+
|
|
126
|
+
[x] PayPal
|
|
127
|
+
|
|
128
|
+
[x] Razorpay
|
|
129
|
+
|
|
130
|
+
## Xendit Hataları
|
|
131
|
+
|
|
132
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda sadece webhook token kontrolü var, gerçek signature validation yok. Xendit dokümantasyonuna göre callback'lar doğrulanmalı.
|
|
133
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
134
|
+
|
|
135
|
+
[x] Xendit (sorun var, signature validation eklenmeli)
|
|
136
|
+
|
|
137
|
+
[x] Paytm
|
|
138
|
+
|
|
139
|
+
## Yookassa Hataları
|
|
140
|
+
|
|
141
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda webhook signature validation yok. Yookassa dokümantasyonuna göre callback'lar doğrulanmalı, ancak kodda eksik.
|
|
142
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
143
|
+
|
|
144
|
+
[x] Yookassa (sorun var, signature validation eklenmeli)
|
|
145
|
+
|
|
146
|
+
[x] Coinbase
|
|
147
|
+
|
|
148
|
+
[x] PayUIndia
|
|
149
|
+
|
|
150
|
+
[x] PayULatam
|
|
151
|
+
[x] PayULatam
|
|
152
|
+
|
|
153
|
+
[x] PayTR
|
|
154
|
+
|
|
155
|
+
[x] PerfectMoney
|
|
156
|
+
|
|
157
|
+
## Paddle Hataları
|
|
158
|
+
|
|
159
|
+
- **Webhook Signature Validation Eksik**: verifyWebhook metodunda sadece `return true;` placeholder var, gerçek signature validation yok. Paddle dokümantasyonuna göre webhook'lar HMAC SHA256 ile signature doğrulanmalı. Paddle-Signature header'dan ts ve h1 çıkarılıp, ts + ":" + raw body ile HMAC SHA256 hash hesaplanmalı ve h1 ile karşılaştırılmalı.
|
|
160
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
161
|
+
|
|
162
|
+
[x] Paddle (sorun var, signature validation uygulanmalı)
|
|
163
|
+
|
|
164
|
+
## Papara Hataları
|
|
165
|
+
|
|
166
|
+
- **Callback Güvenliği Eksik**: verifyPaymentCallback metodunda sadece status kontrolü ve merchantSecretKey karşılaştırması var, gerçek signature validation yok. Papara API dokümantasyonuna göre webhook callback'lar doğrulanmalı, ancak kodda eksik.
|
|
167
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
168
|
+
|
|
169
|
+
[x] Papara (sorun var, signature validation eklenmeli)
|
|
170
|
+
|
|
171
|
+
## Payoneer Hataları
|
|
172
|
+
|
|
173
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda webhook signature validation yok. Payoneer API dokümantasyonuna göre callback'lar doğrulanmalı, ancak kodda eksik.
|
|
174
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
175
|
+
|
|
176
|
+
[x] Payoneer (sorun var, signature validation eklenmeli)
|
|
177
|
+
|
|
178
|
+
## Payop Hataları
|
|
179
|
+
|
|
180
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyNotification çağrılmıyor. verifyNotification metodu signature validation yapıyor ama kullanılmıyor. Payop dokümantasyonuna göre IPN'ler doğrulanmalı, ancak kodda eksik.
|
|
181
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
182
|
+
|
|
183
|
+
[x] Payop (sorun var, signature validation uygulanmalı)
|
|
184
|
+
|
|
185
|
+
[x] Payriff
|
|
186
|
+
|
|
187
|
+
## Paysend Hataları
|
|
188
|
+
|
|
189
|
+
- **Callback Güvenliği Eksik**: verifyCallback metodunda sadece status kontrolü var, gerçek signature validation yok. Paysend API dokümantasyonuna göre webhook callback'lar doğrulanmalı, ancak kodda eksik.
|
|
190
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
191
|
+
|
|
192
|
+
[x] Paysend (sorun var, signature validation eklenmeli)
|
|
193
|
+
|
|
194
|
+
[x] Payspace
|
|
195
|
+
|
|
196
|
+
## Payssion Hataları
|
|
197
|
+
|
|
198
|
+
- **Yanlış Signature Algoritması**: generateSignature metodunda MD5 kullanılıyor, ancak Payssion dokümantasyonuna göre webhook signature validation HMAC SHA256 ile yapılmalı. Payssion-Signature header'dan signature alınmalı ve payload ile HMAC SHA256 hesaplanmalı.
|
|
199
|
+
- **Güvenlik Açığı**: Yanlış signature algoritması kullanılması nedeniyle callback verisi doğru doğrulanamıyor, spoofing saldırılarına açık.
|
|
200
|
+
|
|
201
|
+
[x] Payssion (sorun var, signature algoritması düzeltilmeli)
|
|
202
|
+
|
|
203
|
+
## Paytabs Hataları
|
|
204
|
+
|
|
205
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyPayment çağırılıyor ama bu sadece API sorgusu yapıyor, gerçek signature validation yok. Paytabs API dokümantasyonuna göre webhook callback'lar doğrulanmalı, ancak kodda eksik.
|
|
206
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
207
|
+
|
|
208
|
+
[x] Paytabs (sorun var, signature validation eklenmeli)
|
|
209
|
+
|
|
210
|
+
[x] Paytm
|
|
211
|
+
|
|
212
|
+
## Paycom Hataları
|
|
213
|
+
|
|
214
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyCallback çağrılmıyor. verifyCallback metodu X-Auth header kontrolü yapıyor ama dokümantasyona göre Authorization: Basic auth gerekli. Kodda authentication yapılmadan callback işleniyor.
|
|
215
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
216
|
+
|
|
217
|
+
[x] Paycom (sorun var, authentication uygulanmalı)
|
|
218
|
+
|
|
219
|
+
[x] Paydisini
|
|
220
|
+
|
|
221
|
+
[x] Payeer
|
|
222
|
+
|
|
223
|
+
[x] Payid19
|
|
224
|
+
|
|
225
|
+
## Paykun Hataları
|
|
226
|
+
|
|
227
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok. Paykun dokümantasyonuna göre callback'lar SHA512 HMAC ile signature doğrulanmalı, ancak kodda eksik.
|
|
228
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
229
|
+
|
|
230
|
+
[x] Paykun (sorun var, signature validation eklenmeli)
|
|
231
|
+
|
|
232
|
+
## Paymaya Hataları
|
|
233
|
+
|
|
234
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyWebhookSignature çağrılmıyor. verifyWebhookSignature metodu signature validation yapıyor ama kullanılmıyor. Maya Checkout dokümantasyonuna göre webhook'lar doğrulanmalı.
|
|
235
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
236
|
+
|
|
237
|
+
[x] Paymaya (sorun var, signature validation uygulanmalı)
|
|
238
|
+
|
|
239
|
+
## Payme Hataları
|
|
240
|
+
|
|
241
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok. Kodda comment edilmiş "İleri düzey implementasyon: Signature doğrulaması" ama uygulanmamış. Payme dokümantasyonuna göre callback'lar doğrulanmalı.
|
|
242
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, spoofing saldırılarına açık.
|
|
243
|
+
|
|
244
|
+
[x] Payme (sorun var, signature validation eklenmeli)
|
|
245
|
+
|
|
246
|
+
[x] Paymentwall
|
|
247
|
+
|
|
248
|
+
[x] Paynet
|
|
249
|
+
|
|
250
|
+
[x] Paynettr
|
|
251
|
+
|
|
252
|
+
[x] Phonepe
|
|
253
|
+
|
|
254
|
+
## Picpay Hataları
|
|
255
|
+
|
|
256
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok. Sadece referenceId ile API'ye sorgu yapıyor, ancak Picpay webhook dokümantasyonuna göre callback verisi HMAC SHA256 signature ile doğrulanmalı.
|
|
257
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır. API çağrısı ile doğrulama yetersiz, çünkü callback verisi değiştirilebilir.
|
|
258
|
+
|
|
259
|
+
[x] Picpay (sorun var, signature validation eklenmeli)
|
|
260
|
+
|
|
261
|
+
## Plisio Hataları
|
|
262
|
+
|
|
263
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyCallback çağırılıyor ve generateVerifyHash ile doğrulama yapılıyor, ancak implementasyon yanlış. Dokümantasyona göre HMAC SHA1 kullanılmalı, ancak kodda sadece SHA1 hash kullanılıyor (HMAC değil).
|
|
264
|
+
- **Yanlış Hash Algoritması**: generateVerifyHash fonksiyonunda crypto.createHash('sha1') kullanılıyor, ancak dokümantasyona göre crypto.createHmac('sha1', secretKey) kullanılmalı.
|
|
265
|
+
- **Yanlış Veri Sıralaması**: Kodda Object.keys().sort() sonra join('|') kullanılıyor, ancak dokümantasyona göre serialize() veya JSON.stringify() kullanılmalı.
|
|
266
|
+
- **Güvenlik Açığı**: Yanlış signature doğrulama nedeniyle callback verisi spoofing saldırılarına açık bırakır.
|
|
267
|
+
|
|
268
|
+
[x] Plisio (sorun var, signature validation düzeltilmeli)
|
|
269
|
+
|
|
270
|
+
## Portwallet Hataları
|
|
271
|
+
|
|
272
|
+
- **Callback Güvenliği Koşullu**: handleCallback metodunda verifyCallback çağırılıyor ancak sadece secretKey varsa. Eğer secretKey verilmezse callback doğrulanmadan işleniyor.
|
|
273
|
+
- **Güvenlik Açığı**: secretKey optional olduğu için, yanlış yapılandırma durumunda callback verisi spoofing saldırılarına açık bırakır.
|
|
274
|
+
- **Dokümantasyon Eksik**: Portwallet dokümantasyonuna erişilemedi, ancak genel payment gateway standartlarına göre callback signature validation zorunlu olmalı.
|
|
275
|
+
|
|
276
|
+
[x] Portwallet (sorun var, secretKey kontrolü düzeltilmeli)
|
|
277
|
+
|
|
278
|
+
## Primepayments Hataları
|
|
279
|
+
|
|
280
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda verifyNotification çağırılıyor ancak bu fonksiyon tanımlanmamış. Kod çalışmayacak.
|
|
281
|
+
- **Güvenlik Açığı**: verifyNotification fonksiyonu eksik olduğu için callback doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır.
|
|
282
|
+
- **Eksik Implementasyon**: Primepayments API dokümantasyonuna göre secret word 2 ile MD5 signature validation gerekli, ancak kodda eksik.
|
|
283
|
+
|
|
284
|
+
[x] Primepayments (sorun var, verifyNotification fonksiyonu eklenmeli)
|
|
285
|
+
|
|
286
|
+
[x] Razorpay
|
|
287
|
+
|
|
288
|
+
[x] Senangpay
|
|
289
|
+
|
|
290
|
+
[x] Shopier
|
|
291
|
+
|
|
292
|
+
## Shurjopay Hataları
|
|
293
|
+
|
|
294
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok. Sadece orderId ile API'ye sorgu yapıyor, ancak Shurjopay webhook dokümantasyonuna göre callback verisi HMAC SHA256 signature ile doğrulanmalı.
|
|
295
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır. API çağrısı ile doğrulama yetersiz, çünkü callback verisi değiştirilebilir.
|
|
296
|
+
|
|
297
|
+
[x] Shurjopay (sorun var, signature validation eklenmeli)
|
|
298
|
+
|
|
299
|
+
## Toyyibpay Hataları
|
|
300
|
+
|
|
301
|
+
- **Callback Güvenliği Eksik**: verifyCallback metodunda sadece status_id kontrolü var, hash verification yok. Toyyibpay API dokümantasyonuna göre callback verisi hash ile doğrulanmalı.
|
|
302
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır.
|
|
303
|
+
|
|
304
|
+
[x] Toyyibpay (sorun var, hash validation eklenmeli)
|
|
305
|
+
|
|
306
|
+
[x] Tripay
|
|
307
|
+
|
|
308
|
+
[x] Unitpay
|
|
309
|
+
|
|
310
|
+
[x] Urway
|
|
311
|
+
|
|
312
|
+
[x] Volet
|
|
313
|
+
|
|
314
|
+
## Xendit Hataları
|
|
315
|
+
|
|
316
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda sadece webhook token kontrolü var, signature validation yok. Xendit webhook dokümantasyonuna göre callback verisi HMAC SHA256 signature ile doğrulanmalı.
|
|
317
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır.
|
|
318
|
+
|
|
319
|
+
[x] Xendit (sorun var, signature validation eklenmeli)
|
|
320
|
+
|
|
321
|
+
## Yallapay Hataları
|
|
322
|
+
|
|
323
|
+
- **Callback Güvenliği Eksik**: handleWebhook metodunda sadece webhook secret kontrolü var, signature validation yok. Yallapay webhook dokümantasyonuna göre callback verisi hash ile doğrulanmalı.
|
|
324
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır.
|
|
325
|
+
|
|
326
|
+
[x] Yallapay (sorun var, signature validation eklenmeli)
|
|
327
|
+
|
|
328
|
+
## Yookassa Hataları
|
|
329
|
+
|
|
330
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok. Sadece payment.id ile API'ye sorgu yapıyor, ancak Yookassa webhook dokümantasyonuna göre callback verisi HMAC SHA256 signature ile doğrulanmalı.
|
|
331
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır. API çağrısı ile doğrulama yetersiz.
|
|
332
|
+
|
|
333
|
+
[x] Yookassa (sorun var, signature validation eklenmeli)
|
|
334
|
+
|
|
335
|
+
## Youcanpay Hataları
|
|
336
|
+
|
|
337
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda signature validation yok. Sadece transactionId ile API'ye sorgu yapıyor, ancak Youcanpay webhook dokümantasyonuna göre callback verisi signature ile doğrulanmalı.
|
|
338
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır. API çağrısı ile doğrulama yetersiz.
|
|
339
|
+
|
|
340
|
+
[x] Youcanpay (sorun var, signature validation eklenmeli)
|
|
341
|
+
|
|
342
|
+
## Zarinpal Hataları
|
|
343
|
+
|
|
344
|
+
- **Callback Güvenliği Eksik**: handleCallback metodunda sadece Status kontrolü var, signature validation yok. Zarinpal webhook dokümantasyonuna göre callback verisi doğrulanmalı.
|
|
345
|
+
- **Güvenlik Açığı**: Callback verisi doğrulanmadan işleniyor, bu spoofing saldırılarına açık bırakır.
|
|
346
|
+
|
|
347
|
+
[x] Zarinpal (sorun var, signature validation eklenmeli)
|