quickpos 1.0.911 → 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.
Files changed (133) hide show
  1. package/PROVIDERS-DETAILS.md +1544 -0
  2. package/examples/example-2checkout.js +78 -0
  3. package/examples/example-bitpay.js +83 -0
  4. package/examples/example-cardcom.js +80 -0
  5. package/examples/example-cashfree.js +109 -0
  6. package/examples/example-checkout.js +85 -0
  7. package/examples/example-coingate.js +101 -0
  8. package/examples/example-coinpayments.js +89 -0
  9. package/examples/example-doku.js +27 -0
  10. package/examples/example-epay.js +64 -0
  11. package/examples/example-epoint.js +91 -0
  12. package/examples/example-freekassa.js +26 -0
  13. package/{example-heleket.js → examples/example-heleket.js} +3 -3
  14. package/examples/example-konnect.js +227 -0
  15. package/examples/example-midtrans.js +80 -0
  16. package/examples/example-noonpayments.js +297 -0
  17. package/examples/example-nowpayments.js +289 -0
  18. package/examples/example-omise.js +27 -0
  19. package/examples/example-paycom.js +82 -0
  20. package/{example-paydisini.js → examples/example-paydisini.js} +1 -1
  21. package/examples/example-payid19.js +87 -0
  22. package/examples/example-paykun.js +29 -0
  23. package/examples/example-payme.js +202 -0
  24. package/examples/example-paymentwall.js +201 -0
  25. package/examples/example-paynet.js +104 -0
  26. package/examples/example-paynettr.js +18 -0
  27. package/examples/example-payoneer.js +74 -0
  28. package/examples/example-payop.js +351 -0
  29. package/examples/example-paypal.js +200 -0
  30. package/examples/example-payriff.js +89 -0
  31. package/examples/example-paysend.js +81 -0
  32. package/examples/example-payspace.js +103 -0
  33. package/examples/example-payssion.js +27 -0
  34. package/examples/example-paytabs.js +28 -0
  35. package/examples/example-paytm.js +78 -0
  36. package/examples/example-payuindia.js +108 -0
  37. package/examples/example-payulatam.js +75 -0
  38. package/examples/example-phonepe.js +27 -0
  39. package/examples/example-picpay.js +27 -0
  40. package/examples/example-plisio.js +84 -0
  41. package/examples/example-portwallet.js +90 -0
  42. package/examples/example-primepayments.js +250 -0
  43. package/examples/example-razorpay.js +30 -0
  44. package/examples/example-senangpay.js +28 -0
  45. package/examples/example-shopier-card.js +67 -0
  46. package/examples/example-shurjopay.js +94 -0
  47. package/examples/example-toyyibpay.js +80 -0
  48. package/examples/example-tripay.js +89 -0
  49. package/examples/example-unitpay.js +26 -0
  50. package/examples/example-urway.js +28 -0
  51. package/examples/example-volet.js +80 -0
  52. package/examples/example-xendit.js +28 -0
  53. package/examples/example-yallapay.js +253 -0
  54. package/examples/example-yookassa.js +27 -0
  55. package/examples/example-youcanpay.js +28 -0
  56. package/examples/example-zarinpal.js +98 -0
  57. package/{example.js → examples/example.js} +1 -1
  58. package/lib/2checkout.js +165 -0
  59. package/lib/amazonpay.js +161 -0
  60. package/lib/billplz.js +79 -0
  61. package/lib/bitpay.js +122 -0
  62. package/lib/cardcom.js +193 -0
  63. package/lib/cashfree.js +184 -0
  64. package/lib/checkout.js +248 -0
  65. package/lib/coinbase.js +150 -0
  66. package/lib/coingate.js +137 -0
  67. package/lib/coinpayments.js +245 -0
  68. package/lib/doku.js +173 -0
  69. package/lib/epay.js +175 -0
  70. package/lib/epoint.js +162 -0
  71. package/lib/freekassa.js +128 -0
  72. package/lib/instamojo.js +158 -0
  73. package/lib/konnect.js +211 -0
  74. package/lib/midtrans.js +227 -0
  75. package/lib/noonpayments.js +650 -0
  76. package/lib/nowpayments.js +361 -0
  77. package/lib/omise.js +150 -0
  78. package/lib/paddle.js +180 -0
  79. package/lib/paycom.js +216 -0
  80. package/lib/payid19.js +211 -0
  81. package/lib/paykun.js +144 -0
  82. package/lib/payme.js +302 -0
  83. package/lib/paymentwall.js +205 -0
  84. package/lib/paynet.js +186 -0
  85. package/lib/paynettr.js +165 -0
  86. package/lib/payoneer.js +128 -0
  87. package/lib/payop.js +345 -0
  88. package/lib/paypal.js +596 -0
  89. package/lib/payriff.js +148 -0
  90. package/lib/paysend.js +189 -0
  91. package/lib/payspace.js +168 -0
  92. package/lib/payssion.js +177 -0
  93. package/lib/paytabs.js +145 -0
  94. package/lib/paytm.js +253 -0
  95. package/lib/payuindia.js +162 -0
  96. package/lib/payulatam.js +179 -0
  97. package/lib/perfectmoney.js +143 -0
  98. package/lib/phonepe.js +174 -0
  99. package/lib/picpay.js +119 -0
  100. package/lib/plisio.js +234 -0
  101. package/lib/portwallet.js +152 -0
  102. package/lib/primepayments.js +338 -0
  103. package/lib/razorpay.js +205 -0
  104. package/lib/senangpay.js +130 -0
  105. package/lib/shopier_card.js +188 -0
  106. package/lib/shurjopay.js +159 -0
  107. package/lib/toyyibpay.js +151 -0
  108. package/lib/tripay.js +220 -0
  109. package/lib/unitpay.js +223 -0
  110. package/lib/urway.js +182 -0
  111. package/lib/volet.js +147 -0
  112. package/lib/xendit.js +206 -0
  113. package/lib/yallapay.js +319 -0
  114. package/lib/yookassa.js +193 -0
  115. package/lib/youcanpay.js +124 -0
  116. package/lib/zarinpal.js +157 -0
  117. package/package.json +138 -64
  118. package/readme.md +348 -105
  119. package/reported.md +347 -0
  120. package/test.js +492 -0
  121. package/lib/vallet.js +0 -22
  122. /package/{example-anypay.js → examples/example-anypay.js} +0 -0
  123. /package/{example-bufpay.js → examples/example-bufpay.js} +0 -0
  124. /package/{example-cryptomus.js → examples/example-cryptomus.js} +0 -0
  125. /package/{example-esnekpos.js → examples/example-esnekpos.js} +0 -0
  126. /package/{example-fedapay.js → examples/example-fedapay.js} +0 -0
  127. /package/{example-iyzico.js → examples/example-iyzico.js} +0 -0
  128. /package/{example-papara.js → examples/example-papara.js} +0 -0
  129. /package/{example-payeer.js → examples/example-payeer.js} +0 -0
  130. /package/{example-paymaya.js → examples/example-paymaya.js} +0 -0
  131. /package/{example-shopier.js → examples/example-shopier.js} +0 -0
  132. /package/{ipaymu.js → examples/ipaymu.js} +0 -0
  133. /package/{oderopay.js → examples/oderopay.js} +0 -0
@@ -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;
@@ -0,0 +1,159 @@
1
+ const axios = require('axios');
2
+ const crypto = require('crypto');
3
+
4
+ class ShurjoPayClient {
5
+ constructor(config) {
6
+ const requiredFields = ['username', 'password', 'prefix'];
7
+ for (let field of requiredFields) {
8
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
9
+ }
10
+
11
+ this.username = config.username;
12
+ this.password = config.password;
13
+ this.prefix = config.prefix;
14
+ this.baseURL = config.sandbox
15
+ ? 'https://sandbox.shurjopayment.com'
16
+ : 'https://engine.shurjopayment.com';
17
+
18
+ this.token = null;
19
+
20
+ this.client = axios.create({
21
+ baseURL: this.baseURL,
22
+ headers: {
23
+ 'Content-Type': 'application/json'
24
+ }
25
+ });
26
+ }
27
+
28
+ async authenticate() {
29
+ try {
30
+ const response = await this.client.post('/api/get_token', {
31
+ username: this.username,
32
+ password: this.password
33
+ });
34
+
35
+ if (response.data.token) {
36
+ this.token = response.data.token;
37
+ this.client.defaults.headers['Authorization'] = `Bearer ${this.token}`;
38
+ return this.token;
39
+ } else {
40
+ throw new Error('Authentication failed');
41
+ }
42
+ } catch (error) {
43
+ throw new Error(`Authentication error: ${error.response?.data?.message || error.message}`);
44
+ }
45
+ }
46
+
47
+ async createPayment(options) {
48
+ try {
49
+ if (!this.token) {
50
+ await this.authenticate();
51
+ }
52
+
53
+ const orderId = options.orderId || `${this.prefix}${Date.now()}`;
54
+
55
+ const paymentData = {
56
+ prefix: this.prefix,
57
+ token: this.token,
58
+ return_url: options.successUrl || options.callback_link,
59
+ cancel_url: options.failUrl || options.callback_link,
60
+ store_id: this.prefix,
61
+ amount: parseFloat(options.amount),
62
+ order_id: orderId,
63
+ currency: options.currency || 'BDT',
64
+ customer_name: options.name || options.customerName || '',
65
+ customer_address: options.address || '',
66
+ customer_city: options.city || 'Dhaka',
67
+ customer_phone: options.phone || '',
68
+ customer_email: options.email || '',
69
+ client_ip: options.clientIp || '127.0.0.1',
70
+ intent: 'sale',
71
+ discsount_amount: options.discount || 0,
72
+ disc_percent: options.discountPercent || 0
73
+ };
74
+
75
+ const response = await this.client.post('/api/secret-pay', paymentData);
76
+
77
+ if (response.data.checkout_url) {
78
+ return {
79
+ status: 'success',
80
+ data: {
81
+ url: response.data.checkout_url,
82
+ orderId: orderId,
83
+ amount: paymentData.amount,
84
+ currency: paymentData.currency,
85
+ sp_order_id: response.data.sp_order_id
86
+ }
87
+ };
88
+ } else {
89
+ throw new Error(response.data.message || 'Payment creation failed');
90
+ }
91
+ } catch (error) {
92
+ throw new Error(`Payment creation error: ${error.response?.data?.message || error.message}`);
93
+ }
94
+ }
95
+
96
+ async handleCallback(callbackData) {
97
+ try {
98
+ const orderId = callbackData.order_id;
99
+
100
+ if (!orderId) {
101
+ throw new Error('Order ID not found in callback data');
102
+ }
103
+
104
+ // Verify payment
105
+ const verification = await this.verifyPayment(orderId);
106
+
107
+ // Status mapping
108
+ const statusMapping = {
109
+ 'success': 'success',
110
+ 'Success': 'success',
111
+ 'failed': 'failed',
112
+ 'Failed': 'failed',
113
+ 'pending': 'pending',
114
+ 'Pending': 'pending',
115
+ 'cancel': 'failed',
116
+ 'Cancel': 'failed'
117
+ };
118
+
119
+ return {
120
+ status: statusMapping[verification[0].sp_status] || 'unknown',
121
+ orderId: verification[0].order_id,
122
+ transactionId: verification[0].bank_trx_id,
123
+ amount: parseFloat(verification[0].amount),
124
+ currency: verification[0].currency,
125
+ paymentStatus: verification[0].sp_status,
126
+ method: verification[0].method,
127
+ bankStatus: verification[0].bank_status
128
+ };
129
+ } catch (error) {
130
+ throw new Error(`Error in ShurjoPay callback handling: ${error.message}`);
131
+ }
132
+ }
133
+
134
+ async verifyPayment(orderId) {
135
+ try {
136
+ if (!this.token) {
137
+ await this.authenticate();
138
+ }
139
+
140
+ const response = await this.client.post('/api/verification', {
141
+ order_id: orderId
142
+ });
143
+
144
+ return response.data;
145
+ } catch (error) {
146
+ throw new Error(`Error verifying payment: ${error.response?.data?.message || error.message}`);
147
+ }
148
+ }
149
+
150
+ async getPaymentStatus(orderId) {
151
+ try {
152
+ return await this.verifyPayment(orderId);
153
+ } catch (error) {
154
+ throw new Error(`Error getting payment status: ${error.message}`);
155
+ }
156
+ }
157
+ }
158
+
159
+ module.exports = ShurjoPayClient;
@@ -0,0 +1,151 @@
1
+ const axios = require('axios');
2
+ const crypto = require('crypto');
3
+
4
+ class ToyyibPayClient {
5
+ constructor(config) {
6
+ const requiredFields = ['secretKey', 'categoryCode'];
7
+ for (let field of requiredFields) {
8
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
9
+ }
10
+
11
+ this.secretKey = config.secretKey;
12
+ this.categoryCode = config.categoryCode;
13
+ this.URL = 'https://dev.toyyibpay.com';
14
+
15
+ this.client = axios.create({
16
+ baseURL: this.URL,
17
+ headers: {
18
+ 'Content-Type': 'application/x-www-form-urlencoded'
19
+ }
20
+ });
21
+
22
+ this.client.interceptors.response.use(response => {
23
+ return response;
24
+ }, error => {
25
+ if (error.response) {
26
+ throw new Error(`ToyyibPay API error: ${error.response.data.message || error.message}`);
27
+ }
28
+ throw new Error(`ToyyibPay API error: ${error.message}`);
29
+ });
30
+ }
31
+
32
+ async createPayment(options) {
33
+ try {
34
+ const params = new URLSearchParams();
35
+ params.append('userSecretKey', this.secretKey);
36
+ params.append('categoryCode', this.categoryCode);
37
+ params.append('billName', options.billName || options.name || 'Bill');
38
+ params.append('billDescription', options.billDescription || options.description || 'Payment');
39
+ params.append('billPriceSetting', '1');
40
+ params.append('billPayorInfo', '1');
41
+ params.append('billAmount', Math.round(parseFloat(options.amount) * 100));
42
+ params.append('billReturnUrl', options.returnUrl || options.callback_link);
43
+ params.append('billCallbackUrl', options.callbackUrl || options.callback_link);
44
+ params.append('billExternalReferenceNo', options.referenceNo || options.orderId || `ORDER-${Date.now()}`);
45
+ params.append('billTo', options.billTo || options.customerName || options.name || 'Customer');
46
+ params.append('billEmail', options.billEmail || options.email);
47
+ params.append('billPhone', options.billPhone || options.phone || '60123456789');
48
+ params.append('billSplitPayment', '0');
49
+ params.append('billSplitPaymentArgs', '');
50
+ params.append('billPaymentChannel', options.paymentChannel || '0');
51
+ params.append('billContentEmail', options.contentEmail || 'Thank you for your payment');
52
+
53
+ if (options.billChargeToCustomer) {
54
+ params.append('billChargeToCustomer', options.billChargeToCustomer);
55
+ }
56
+
57
+ const response = await this.client.post('/index.php/api/createBill', params);
58
+
59
+ if (response.data[0].BillCode) {
60
+ return {
61
+ status: 'success',
62
+ data: {
63
+ billCode: response.data[0].BillCode,
64
+ url: `${this.URL}/${response.data[0].BillCode}`,
65
+ referenceNo: options.referenceNo || options.orderId
66
+ }
67
+ };
68
+ } else {
69
+ throw new Error(response.data[0].error || 'Payment creation failed');
70
+ }
71
+ } catch (error) {
72
+ throw new Error(`Payment creation error: ${error.message}`);
73
+ }
74
+ }
75
+
76
+ async getBillTransactions(billCode) {
77
+ try {
78
+ const params = new URLSearchParams();
79
+ params.append('billCode', billCode);
80
+
81
+ const response = await this.client.post('/index.php/api/getBillTransactions', params);
82
+ return response.data;
83
+ } catch (error) {
84
+ throw new Error(`Bill transactions error: ${error.message}`);
85
+ }
86
+ }
87
+
88
+ async handleCallback(callbackData) {
89
+ try {
90
+ const verification = await this.verifyCallback(callbackData);
91
+
92
+ if (!verification.status) {
93
+ throw new Error(verification.error.message);
94
+ }
95
+
96
+ const data = verification.data;
97
+
98
+ // Status mapping: 1 = success, 2 = pending, 3 = failed
99
+ const statusMapping = {
100
+ '1': 'success',
101
+ '2': 'pending',
102
+ '3': 'failed'
103
+ };
104
+
105
+ return {
106
+ status: statusMapping[data.status_id] || 'unknown',
107
+ billCode: data.billcode,
108
+ orderId: data.order_id || data.billExternalReferenceNo,
109
+ amount: parseFloat(data.amount) / 100,
110
+ transactionId: data.transaction_id,
111
+ paymentStatus: data.status_id,
112
+ transactionTime: data.transaction_time,
113
+ payerName: data.billpayorname,
114
+ payerEmail: data.billpayoremail,
115
+ payerPhone: data.billpayorphone
116
+ };
117
+ } catch (error) {
118
+ throw new Error(`Error in ToyyibPay callback handling: ${error.message}`);
119
+ }
120
+ }
121
+
122
+ async verifyCallback(data) {
123
+ try {
124
+ // ToyyibPay uses hash verification
125
+ if (data.status_id === '3') {
126
+ return {
127
+ status: false,
128
+ error: {
129
+ code: 400,
130
+ message: 'Payment failed'
131
+ }
132
+ };
133
+ }
134
+
135
+ return {
136
+ status: true,
137
+ data: data
138
+ };
139
+ } catch (error) {
140
+ return {
141
+ status: false,
142
+ error: {
143
+ code: 500,
144
+ message: error.message
145
+ }
146
+ };
147
+ }
148
+ }
149
+ }
150
+
151
+ module.exports = ToyyibPayClient;