quickpos 1.0.914 → 1.0.915

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/lib/paytr.js CHANGED
@@ -1,26 +1,39 @@
1
1
  const crypto = require('crypto');
2
- const jsSHA = require('jssha');
3
2
  const axios = require('axios');
4
3
 
5
4
  class PayTR {
6
5
  constructor(config) {
7
6
  this.config = config || {};
7
+
8
8
  const requiredFields = ['merchantId', 'merchantKey', 'merchantSalt'];
9
9
  for (let field of requiredFields) {
10
- if (!config[field]) throw new Error(`Missing required field: ${field}`);
10
+ if (!this.config[field]) throw new Error(`Missing required field: ${field}`);
11
11
  }
12
12
 
13
- this.merchantId = config.merchantId;
14
- this.merchantKey = config.merchantKey;
15
- this.merchantSalt = config.merchantSalt;
16
- this.debug_on = String(config?.debug_on) || '0';
13
+ this.merchantId = this.config.merchantId;
14
+ this.merchantKey = this.config.merchantKey;
15
+ this.merchantSalt = this.config.merchantSalt;
16
+ this.testMode = this.config.testMode ? '1' : '0';
17
+ this.debugOn = this.config.debugOn ? '1' : '0';
18
+
19
+ this.iframe = {
20
+ createToken: this.createIframeToken.bind(this)
21
+ };
22
+
23
+ this.direct = {
24
+ createPayment: this.createDirectPayment.bind(this)
25
+ };
26
+
27
+ this.link = {
28
+ createPayment: this.createLinkPayment.bind(this)
29
+ };
17
30
  }
18
31
 
19
- async createPayment(paymentDetails) {
32
+ async createLinkPayment(paymentDetails) {
20
33
  try {
21
- let requiredData = ['name', 'amount', 'currency', 'maxInstallment', 'expiry_date'];
22
- for (let data of requiredData) {
23
- if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`);
34
+ const requiredFields = ['name', 'amount', 'currency', 'maxInstallment', 'expiry_date'];
35
+ for (let field of requiredFields) {
36
+ if (!paymentDetails[field]) throw new Error(`Missing required data: ${field}`);
24
37
  }
25
38
 
26
39
  const price = Math.round(paymentDetails.amount * 100).toString();
@@ -42,14 +55,16 @@ class PayTR {
42
55
  lang: lang,
43
56
  min_count: minCount,
44
57
  paytr_token: paytrToken,
45
- expiry_date: paymentDetails?.expiry_date,
58
+ expiry_date: paymentDetails.expiry_date,
46
59
  get_qr: '1',
47
- max_count: Number(paymentDetails?.max_count) || '1',
48
- debug_on: this.debug_on
60
+ max_count: Number(paymentDetails.max_count) || '1',
61
+ debug_on: this.debugOn
49
62
  };
50
63
 
51
- let optionalData = ['email', 'callback_link', 'callback_id'];
52
- for (let data of optionalData) { formData[data] = paymentDetails[data]; }
64
+ const optionalData = ['email', 'callback_link', 'callback_id'];
65
+ for (let data of optionalData) {
66
+ if(paymentDetails[data]) formData[data] = paymentDetails[data];
67
+ }
53
68
 
54
69
  const response = await axios({
55
70
  method: 'POST',
@@ -77,42 +92,157 @@ class PayTR {
77
92
  }
78
93
  } catch (error) {
79
94
  if (error.response) {
80
- // The request was made and the server responded with a status code
81
- // that falls out of the range of 2xx
82
95
  throw new Error(`PayTR API error: ${error.response.data.reason || error.response.statusText}`);
83
- } else if (error.request) {
84
- // The request was made but no response was received
85
- throw new Error('No response received from PayTR API');
86
- } else {
87
- // Something happened in setting up the request that triggered an Error
88
- throw new Error(`Error in PayTR payment creation: ${error.message}`);
89
96
  }
97
+ throw error;
90
98
  }
91
99
  }
92
100
 
93
- async handleCallback(callbackData) {
101
+ async createDirectPayment(params) {
94
102
  try {
95
- const token = callbackData.callback_id + callbackData.merchant_oid + this.merchantSalt + callbackData.status + callbackData.total_amount;
103
+ const userBasket = JSON.stringify(params.userBasket);
104
+ const userIp = params.userIp;
105
+ const merchantOid = params.merchantOid;
106
+ const email = params.email;
107
+ const paymentAmount = params.paymentAmount.toString();
108
+ const currency = params.currency || 'TL';
109
+ const installmentCount = params.installmentCount || '0';
110
+ const paymentType = 'card';
111
+ const non3D = params.non3D ? params.non3D : '0';
112
+
113
+ const rawString = `${this.merchantId}${userIp}${merchantOid}${email}${paymentAmount}${paymentType}${installmentCount}${currency}${this.testMode}${non3D}`;
114
+ const paytrToken = this.generateToken(rawString);
115
+
116
+ const formData = new URLSearchParams();
117
+ formData.append('merchant_id', this.merchantId);
118
+ formData.append('user_ip', userIp);
119
+ formData.append('merchant_oid', merchantOid);
120
+ formData.append('email', email);
121
+ formData.append('payment_amount', paymentAmount);
122
+ formData.append('paytr_token', paytrToken);
123
+ formData.append('user_basket', userBasket);
124
+ formData.append('debug_on', this.debugOn);
125
+ formData.append('test_mode', this.testMode);
126
+ formData.append('payment_type', paymentType);
127
+ formData.append('installment_count', installmentCount);
128
+ formData.append('currency', currency);
129
+ formData.append('non_3d', non3D);
130
+ formData.append('cc_owner', params.cardOwner);
131
+ formData.append('card_number', params.cardNumber);
132
+ formData.append('expiry_month', params.cardExpireMonth);
133
+ formData.append('expiry_year', params.cardExpireYear);
134
+ formData.append('cvc', params.cardCvc);
135
+ formData.append('user_name', params.userName);
136
+ formData.append('user_address', params.userAddress);
137
+ formData.append('user_phone', params.userPhone);
138
+ formData.append('merchant_ok_url', params.merchantOkUrl);
139
+ formData.append('merchant_fail_url', params.merchantFailUrl);
140
+
141
+ const response = await axios({
142
+ method: 'POST',
143
+ url: 'https://www.paytr.com/odeme/api/direct',
144
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
145
+ data: formData
146
+ });
147
+
148
+ const result = response.data;
96
149
 
97
- let paytrToken = this.hashCheck(token, callbackData.hash);
98
- if (!paytrToken) {
99
- throw new Error("PAYTR notification failed: bad hash");
150
+ if (result.status === 'success') {
151
+ return result;
152
+ } else {
153
+ throw new Error(result.reason || 'PayTR Direct API Hatası');
100
154
  }
155
+ } catch (error) {
156
+ if (error.response) throw new Error(`PayTR API Error: ${error.response.data.reason || error.response.statusText}`);
157
+ throw error;
158
+ }
159
+ }
101
160
 
102
- if (callbackData.status === 'success') {
103
- return {
104
- status: 'success',
105
- orderId: callbackData.callback_id,
106
- merchant_oid: callbackData.merchant_oid,
107
- amount: parseFloat(callbackData.total_amount) / 100,
108
- currency: callbackData.currency,
109
- paymentType: callbackData.payment_type
110
- };
161
+ async createIframeToken(params) {
162
+ try {
163
+ const userBasket = JSON.stringify(params.userBasket);
164
+ const userIp = params.userIp;
165
+ const merchantOid = params.merchantOid;
166
+ const email = params.email;
167
+ const paymentAmount = params.paymentAmount.toString();
168
+ const currency = params.currency || 'TL';
169
+ const noInstallment = params.noInstallment ? '1' : '0';
170
+ const maxInstallment = params.maxInstallment || '0';
171
+ const paymentType = params.paymentType || 'card';
172
+
173
+ const rawString = `${this.merchantId}${userIp}${merchantOid}${email}${paymentAmount}${userBasket}${noInstallment}${maxInstallment}${currency}${this.testMode}`;
174
+ const paytrToken = this.generateToken(rawString);
175
+
176
+ const formData = new URLSearchParams();
177
+ formData.append('merchant_id', this.merchantId);
178
+ formData.append('user_ip', userIp);
179
+ formData.append('merchant_oid', merchantOid);
180
+ formData.append('email', email);
181
+ formData.append('payment_amount', paymentAmount);
182
+ formData.append('paytr_token', paytrToken);
183
+ formData.append('user_basket', userBasket);
184
+ formData.append('debug_on', this.debugOn);
185
+ formData.append('no_installment', noInstallment);
186
+ formData.append('max_installment', maxInstallment);
187
+ formData.append('user_name', params.userName);
188
+ formData.append('user_address', params.userAddress);
189
+ formData.append('user_phone', params.userPhone);
190
+ formData.append('merchant_ok_url', params.merchantOkUrl);
191
+ formData.append('merchant_fail_url', params.merchantFailUrl);
192
+ formData.append('timeout_limit', params.timeoutLimit || '30');
193
+ formData.append('currency', currency);
194
+ formData.append('test_mode', this.testMode);
195
+ formData.append('payment_type', paymentType);
196
+
197
+ if (params.bank) formData.append('bank', params.bank);
198
+ if (params.lang) formData.append('lang', params.lang);
199
+
200
+ const response = await axios({
201
+ method: 'POST',
202
+ url: 'https://www.paytr.com/odeme/api/get-token',
203
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
204
+ data: formData
205
+ });
206
+
207
+ const result = response.data;
208
+ if (result.status === 'success') {
209
+ return { status: 'success', token: result.token };
111
210
  } else {
112
- throw new Error("Payment failed");
211
+ throw new Error(result.reason || 'PayTR Token alma hatası');
113
212
  }
114
213
  } catch (error) {
115
- throw new Error(`Error in PayTR callback handling: ${error.message}`);
214
+ if (error.response) throw new Error(`PayTR API Error: ${error.response.data.reason || error.response.statusText}`);
215
+ throw error;
216
+ }
217
+ }
218
+
219
+ handleCallback(callbackData) {
220
+ const { merchant_oid, status, total_amount, hash } = callbackData;
221
+
222
+ if (!hash) throw new Error('Hash param missing');
223
+
224
+ const token = `${merchant_oid}${this.merchantSalt}${status}${total_amount}`;
225
+
226
+ const generatedHash = crypto
227
+ .createHmac('sha256', this.merchantKey)
228
+ .update(token)
229
+ .digest('base64');
230
+
231
+ if (generatedHash !== hash) {
232
+ throw new Error("PAYTR notification failed: bad hash");
233
+ }
234
+
235
+ if (status === 'success') {
236
+ return {
237
+ status: 'success',
238
+ orderId: callbackData.callback_id || merchant_oid,
239
+ merchant_oid: merchant_oid,
240
+ amount: parseFloat(total_amount) / 100,
241
+ currency: callbackData.currency,
242
+ paymentType: callbackData.payment_type
243
+ };
244
+ } else {
245
+ throw new Error("Payment failed");
116
246
  }
117
247
  }
118
248
 
@@ -121,14 +251,6 @@ class PayTR {
121
251
  .update(data + this.merchantSalt)
122
252
  .digest('base64');
123
253
  }
124
-
125
- hashCheck(data, key) {
126
- let shaObj = new jsSHA("SHA-256", "TEXT");
127
- shaObj.setHMACKey(this.merchantKey, "TEXT");
128
- shaObj.update(data);
129
- if (shaObj.getHMAC("B64") === key) return true;
130
- else return false;
131
- }
132
254
  }
133
255
 
134
256
  module.exports = PayTR;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickpos",
3
- "version": "1.0.914",
3
+ "version": "1.0.915",
4
4
  "main": "app.js",
5
5
  "scripts": {
6
6
  "test": "node test.js"
package/lib/paytr_eft.js DELETED
@@ -1,156 +0,0 @@
1
- const crypto = require('crypto');
2
- const axios = require('axios');
3
-
4
- class PayTR {
5
- /**
6
- * PayTR Kurucu Metodu
7
- * @param {Object} config - Yapılandırma ayarları
8
- * @param {string} config.merchantId - Mağaza No
9
- * @param {string} config.merchantKey - Mağaza Parola
10
- * @param {string} config.merchantSalt - Mağaza Gizli Anahtar
11
- * @param {boolean} [config.testMode=false] - Test modu (true/false)
12
- * @param {boolean} [config.debugOn=false] - Hata ayıklama modu
13
- */
14
- constructor(config) {
15
- this.config = config || {};
16
-
17
- // Zorunlu alan kontrolü
18
- const requiredFields = ['merchantId', 'merchantKey', 'merchantSalt'];
19
- for (let field of requiredFields) {
20
- if (!this.config[field]) throw new Error(`Missing required field: ${field}`);
21
- }
22
-
23
- this.merchantId = this.config.merchantId;
24
- this.merchantKey = this.config.merchantKey;
25
- this.merchantSalt = this.config.merchantSalt;
26
- this.testMode = this.config.testMode ? '1' : '0';
27
- this.debugOn = this.config.debugOn ? '1' : '0';
28
-
29
- // iframe namespace'i tanımlama (örnekteki kullanıma uygun olması için)
30
- this.iframe = {
31
- createToken: this.createIframeToken.bind(this)
32
- };
33
- }
34
-
35
- /**
36
- * iFrame Token Oluşturma (EFT ve Kredi Kartı için)
37
- * @param {Object} params - Ödeme parametreleri
38
- */
39
- async createIframeToken(params) {
40
- try {
41
- const userBasket = JSON.stringify(params.userBasket);
42
- const userIp = params.userIp;
43
- const merchantOid = params.merchantOid;
44
- const email = params.email;
45
- const paymentAmount = params.paymentAmount.toString(); // Kuruş cinsinden (Örn: 10.00 TL -> 1000)
46
- const currency = params.currency || 'TL';
47
- const noInstallment = params.noInstallment ? '1' : '0';
48
- const maxInstallment = params.maxInstallment || '0';
49
- const paymentType = params.paymentType || 'card'; // 'eft' veya 'card'
50
-
51
- // PayTR Token Oluşturma Sırası (Dökümantasyona Göre)
52
- // merchant_id + user_ip + merchant_oid + email + payment_amount + user_basket + no_installment + max_installment + currency + test_mode
53
- const rawString = `${this.merchantId}${userIp}${merchantOid}${email}${paymentAmount}${userBasket}${noInstallment}${maxInstallment}${currency}${this.testMode}`;
54
-
55
- const paytrToken = this.generateToken(rawString);
56
-
57
- // API'ye gönderilecek veri
58
- const formData = new URLSearchParams();
59
- formData.append('merchant_id', this.merchantId);
60
- formData.append('user_ip', userIp);
61
- formData.append('merchant_oid', merchantOid);
62
- formData.append('email', email);
63
- formData.append('payment_amount', paymentAmount);
64
- formData.append('paytr_token', paytrToken);
65
- formData.append('user_basket', userBasket);
66
- formData.append('debug_on', this.debugOn);
67
- formData.append('no_installment', noInstallment);
68
- formData.append('max_installment', maxInstallment);
69
- formData.append('user_name', params.userName);
70
- formData.append('user_address', params.userAddress);
71
- formData.append('user_phone', params.userPhone);
72
- formData.append('merchant_ok_url', params.merchantOkUrl);
73
- formData.append('merchant_fail_url', params.merchantFailUrl);
74
- formData.append('timeout_limit', params.timeoutLimit || '30');
75
- formData.append('currency', currency);
76
- formData.append('test_mode', this.testMode);
77
- formData.append('payment_type', paymentType); // 'eft' gönderimi için kritik
78
-
79
- // Opsiyonel banka seçimi (Sadece payment_type='eft' ise işe yarar)
80
- if (params.bank) {
81
- formData.append('bank', params.bank);
82
- }
83
-
84
- // Opsiyonel: Lang
85
- if (params.lang) {
86
- formData.append('lang', params.lang);
87
- }
88
-
89
- const response = await axios({
90
- method: 'POST',
91
- url: 'https://www.paytr.com/odeme/api/get-token',
92
- headers: {
93
- 'Content-Type': 'application/x-www-form-urlencoded'
94
- },
95
- data: formData
96
- });
97
-
98
- const result = response.data;
99
-
100
- if (result.status === 'success') {
101
- return {
102
- status: 'success',
103
- token: result.token
104
- };
105
- } else {
106
- throw new Error(result.reason || 'PayTR Token alma hatası');
107
- }
108
-
109
- } catch (error) {
110
- if (error.response) {
111
- throw new Error(`PayTR API Error: ${error.response.data.reason || error.response.statusText}`);
112
- }
113
- throw error;
114
- }
115
- }
116
-
117
- /**
118
- * Callback (Bildirim) Doğrulama
119
- * PayTR'den gelen POST isteğinin hash'ini doğrular.
120
- * @param {Object} reqBody - Express/Http request body
121
- */
122
- validateCallback(reqBody) {
123
- const { merchant_oid, status, total_amount, hash } = reqBody;
124
-
125
- // Hash Oluşturma Sırası:
126
- // merchant_oid + merchant_salt + status + total_amount
127
- const rawString = `${merchant_oid}${this.merchantSalt}${status}${total_amount}`;
128
- const generatedHash = this.generateToken(rawString);
129
-
130
- if (hash === generatedHash) {
131
- return {
132
- success: true,
133
- merchantOid: merchant_oid,
134
- status: status,
135
- totalAmount: total_amount
136
- };
137
- } else {
138
- return {
139
- success: false,
140
- error: 'Hash mismatch'
141
- };
142
- }
143
- }
144
-
145
- /**
146
- * Helper: HMAC-SHA256 Token Üretici
147
- */
148
- generateToken(data) {
149
- return crypto
150
- .createHmac('sha256', this.merchantKey)
151
- .update(data + this.merchantSalt)
152
- .digest('base64');
153
- }
154
- }
155
-
156
- module.exports = PayTR;