quickpos 1.0.917 → 1.0.918
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/2checkout.js +85 -129
- package/lib/cryptomus.js +1 -1
- package/lib/paratika.js +121 -0
- package/lib/paytr.js +77 -49
- package/package.json +1 -1
package/lib/2checkout.js
CHANGED
|
@@ -1,165 +1,121 @@
|
|
|
1
|
-
const axios = require('axios');
|
|
2
1
|
const crypto = require('crypto');
|
|
3
2
|
|
|
4
3
|
class TwoCheckoutClient {
|
|
5
4
|
constructor(config) {
|
|
6
|
-
const requiredFields = ['merchantCode', '
|
|
5
|
+
const requiredFields = ['merchantCode', 'secretWord'];
|
|
7
6
|
for (let field of requiredFields) {
|
|
8
7
|
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
this.merchantCode = config.merchantCode;
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
this.secretWord = config.secretWord;
|
|
12
|
+
this.sandbox = config.sandbox || false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
generateHash(params, algo = 'md5') {
|
|
16
|
+
let signatureString = '';
|
|
17
|
+
|
|
18
|
+
Object.keys(params).forEach(key => {
|
|
19
|
+
const value = String(params[key]); // Değer string olmalı
|
|
20
|
+
if (value.length > 0) { // Boş değerler bazen hash'e katılmaz
|
|
21
|
+
signatureString += value.length + value;
|
|
21
22
|
}
|
|
22
23
|
});
|
|
23
|
-
}
|
|
24
24
|
|
|
25
|
-
generateSignature(params) {
|
|
26
|
-
const signatureString = Object.keys(params)
|
|
27
|
-
.sort()
|
|
28
|
-
.map(key => params[key].length + params[key])
|
|
29
|
-
.join('');
|
|
30
|
-
|
|
31
25
|
return crypto
|
|
32
|
-
.createHmac(
|
|
26
|
+
.createHmac(algo, this.secretWord)
|
|
33
27
|
.update(signatureString)
|
|
34
28
|
.digest('hex');
|
|
35
29
|
}
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const paymentUrl = `https://secure.2checkout.com/order/checkout.php?${formParams.toString()}`;
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
status: 'success',
|
|
72
|
-
data: {
|
|
73
|
-
url: paymentUrl,
|
|
74
|
-
orderId: orderId,
|
|
75
|
-
params: params
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
} catch (error) {
|
|
79
|
-
throw new Error(`Payment creation error: ${error.message}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
31
|
+
createPaymentUrl(options) {
|
|
32
|
+
const orderId = options.orderId || `ORDER-${Date.now()}`;
|
|
33
|
+
|
|
34
|
+
const params = {
|
|
35
|
+
'merchant': this.merchantCode,
|
|
36
|
+
'dynamic': '1', // Dinamik ürün modu
|
|
37
|
+
'prod-name[]': options.name || 'Payment',
|
|
38
|
+
'prod-type[]': 'GLOBAL_SERVICE', // Ürün tipi
|
|
39
|
+
'prod-price[]': parseFloat(options.amount).toFixed(2),
|
|
40
|
+
'prod-qty[]': '1',
|
|
41
|
+
'currency': options.currency || 'USD',
|
|
42
|
+
'return-type': 'redirect',
|
|
43
|
+
'return-url': options.callbackUrl,
|
|
44
|
+
'expiration': Math.floor(Date.now() / 1000) + 3600, // 1 saat geçerli
|
|
45
|
+
'order-ext-ref': orderId,
|
|
46
|
+
'customer-ref': options.customerId || '',
|
|
47
|
+
'customer-email': options.email || ''
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
let signatureData = '';
|
|
51
|
+
|
|
52
|
+
const keysToSign = [
|
|
53
|
+
'merchant', 'dynamic', 'prod-name[]', 'prod-type[]', 'prod-price[]',
|
|
54
|
+
'prod-qty[]', 'currency', 'return-type', 'return-url', 'expiration',
|
|
55
|
+
'order-ext-ref', 'customer-ref', 'customer-email'
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
keysToSign.forEach(key => {
|
|
59
|
+
const val = String(params[key] || '');
|
|
60
|
+
if(val) signatureData += val.length + val;
|
|
61
|
+
});
|
|
82
62
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const verification = await this.verifyCallback(callbackData);
|
|
86
|
-
|
|
87
|
-
if (!verification.status) {
|
|
88
|
-
throw new Error(verification.error.message);
|
|
89
|
-
}
|
|
63
|
+
const signature = crypto.createHmac('md5', this.secretWord).update(signatureData).digest('hex');
|
|
64
|
+
params['signature'] = signature;
|
|
90
65
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
'PENDING': 'pending',
|
|
97
|
-
'REFUND': 'refunded',
|
|
98
|
-
'REVERSED': 'failed'
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
status: statusMapping[data.order_status] || 'unknown',
|
|
103
|
-
orderId: data['order-ext-ref'] || data.order_number,
|
|
104
|
-
transactionId: data.order_number,
|
|
105
|
-
amount: parseFloat(data.invoice_list_amount || data.order_amount),
|
|
106
|
-
currency: data.list_currency,
|
|
107
|
-
paymentStatus: data.order_status,
|
|
108
|
-
invoiceId: data.invoice_id
|
|
109
|
-
};
|
|
110
|
-
} catch (error) {
|
|
111
|
-
throw new Error(`Error in 2Checkout callback handling: ${error.message}`);
|
|
112
|
-
}
|
|
66
|
+
// URL Parametrelerini oluştur
|
|
67
|
+
const queryParams = new URLSearchParams();
|
|
68
|
+
Object.keys(params).forEach(key => queryParams.append(key, params[key]));
|
|
69
|
+
|
|
70
|
+
return `https://secure.2checkout.com/order/checkout.php?${queryParams.toString()}`;
|
|
113
71
|
}
|
|
114
72
|
|
|
115
|
-
|
|
73
|
+
/**
|
|
74
|
+
* IPN (Callback) Doğrulama
|
|
75
|
+
* Bu kısım, sunucunuza gelen POST isteğini doğrular.
|
|
76
|
+
*/
|
|
77
|
+
verifyCallback(postData) {
|
|
116
78
|
try {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (!
|
|
120
|
-
return {
|
|
121
|
-
status: false,
|
|
122
|
-
error: {
|
|
123
|
-
code: 400,
|
|
124
|
-
message: 'Hash not found in callback data'
|
|
125
|
-
}
|
|
126
|
-
};
|
|
79
|
+
// Gelen veriden HASH'i ayıralım
|
|
80
|
+
const receivedHash = postData['HASH'];
|
|
81
|
+
if (!receivedHash) {
|
|
82
|
+
return { status: false, message: 'No hash found' };
|
|
127
83
|
}
|
|
128
84
|
|
|
129
|
-
|
|
130
|
-
const params = { ...data };
|
|
131
|
-
delete params.hash;
|
|
132
|
-
delete params.HASH;
|
|
85
|
+
let hashString = '';
|
|
133
86
|
|
|
87
|
+
// 2Checkout, HASH parametresi hariç tüm parametreleri gönderdiği sırayla kullanır.
|
|
88
|
+
for (let key in postData) {
|
|
89
|
+
if (key !== 'HASH') {
|
|
90
|
+
const val = String(postData[key]);
|
|
91
|
+
hashString += val.length + val;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
134
95
|
const calculatedHash = crypto
|
|
135
|
-
.createHmac('md5', this.
|
|
136
|
-
.update(
|
|
96
|
+
.createHmac('md5', this.secretWord)
|
|
97
|
+
.update(hashString)
|
|
137
98
|
.digest('hex');
|
|
138
99
|
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
100
|
+
if (calculatedHash === receivedHash) {
|
|
101
|
+
const date = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
|
102
|
+
const responseHash = crypto.createHmac('md5', this.secretWord).update(postData.IPN_PID[0].length + postData.IPN_PID[0] + postData.IPN_PNAME[0].length + postData.IPN_PNAME[0] + postData.IPN_DATE.length + postData.IPN_DATE + date.length + date).digest('hex');
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
status: true,
|
|
106
|
+
transactionId: postData.REFNO,
|
|
107
|
+
orderStatus: postData.ORDERSTATUS,
|
|
108
|
+
raw: postData
|
|
146
109
|
};
|
|
110
|
+
} else {
|
|
111
|
+
console.error("Hash Mismatch. Calculated:", calculatedHash, "Received:", receivedHash);
|
|
112
|
+
return { status: false, message: 'Invalid hash signature' };
|
|
147
113
|
}
|
|
148
114
|
|
|
149
|
-
return {
|
|
150
|
-
status: true,
|
|
151
|
-
data: data
|
|
152
|
-
};
|
|
153
115
|
} catch (error) {
|
|
154
|
-
return {
|
|
155
|
-
status: false,
|
|
156
|
-
error: {
|
|
157
|
-
code: 500,
|
|
158
|
-
message: error.message
|
|
159
|
-
}
|
|
160
|
-
};
|
|
116
|
+
return { status: false, message: error.message };
|
|
161
117
|
}
|
|
162
118
|
}
|
|
163
119
|
}
|
|
164
120
|
|
|
165
|
-
module.exports = TwoCheckoutClient;
|
|
121
|
+
module.exports = TwoCheckoutClient;
|
package/lib/cryptomus.js
CHANGED
|
@@ -98,7 +98,7 @@ class Cryptomus {
|
|
|
98
98
|
throw new Error("Cryptomus notification failed: invalid signature");
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
if (callbackData.status === 'paid') {
|
|
101
|
+
if (callbackData.status === 'paid' || callbackData.status === 'paid_over') {
|
|
102
102
|
return {
|
|
103
103
|
status: 'success',
|
|
104
104
|
orderId: callbackData.order_id,
|
package/lib/paratika.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
|
|
3
|
+
class TwoCheckoutClient {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
const requiredFields = ['merchantCode', 'secretWord'];
|
|
6
|
+
for (let field of requiredFields) {
|
|
7
|
+
if (!config[field]) throw new Error(`Missing required field: ${field}`);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
this.merchantCode = config.merchantCode;
|
|
11
|
+
this.secretWord = config.secretWord;
|
|
12
|
+
this.sandbox = config.sandbox || false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
generateHash(params, algo = 'md5') {
|
|
16
|
+
let signatureString = '';
|
|
17
|
+
|
|
18
|
+
Object.keys(params).forEach(key => {
|
|
19
|
+
const value = String(params[key]); // Değer string olmalı
|
|
20
|
+
if (value.length > 0) { // Boş değerler bazen hash'e katılmaz
|
|
21
|
+
signatureString += value.length + value;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return crypto
|
|
26
|
+
.createHmac(algo, this.secretWord)
|
|
27
|
+
.update(signatureString)
|
|
28
|
+
.digest('hex');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
createPaymentUrl(options) {
|
|
32
|
+
const orderId = options.orderId || `ORDER-${Date.now()}`;
|
|
33
|
+
|
|
34
|
+
const params = {
|
|
35
|
+
'merchant': this.merchantCode,
|
|
36
|
+
'dynamic': '1', // Dinamik ürün modu
|
|
37
|
+
'prod-name[]': options.name || 'Payment',
|
|
38
|
+
'prod-type[]': 'GLOBAL_SERVICE', // Ürün tipi
|
|
39
|
+
'prod-price[]': parseFloat(options.amount).toFixed(2),
|
|
40
|
+
'prod-qty[]': '1',
|
|
41
|
+
'currency': options.currency || 'USD',
|
|
42
|
+
'return-type': 'redirect',
|
|
43
|
+
'return-url': options.callbackUrl,
|
|
44
|
+
'expiration': Math.floor(Date.now() / 1000) + 3600, // 1 saat geçerli
|
|
45
|
+
'order-ext-ref': orderId,
|
|
46
|
+
'customer-ref': options.customerId || '',
|
|
47
|
+
'customer-email': options.email || ''
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
let signatureData = '';
|
|
51
|
+
|
|
52
|
+
const keysToSign = [
|
|
53
|
+
'merchant', 'dynamic', 'prod-name[]', 'prod-type[]', 'prod-price[]',
|
|
54
|
+
'prod-qty[]', 'currency', 'return-type', 'return-url', 'expiration',
|
|
55
|
+
'order-ext-ref', 'customer-ref', 'customer-email'
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
keysToSign.forEach(key => {
|
|
59
|
+
const val = String(params[key] || '');
|
|
60
|
+
if(val) signatureData += val.length + val;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const signature = crypto.createHmac('md5', this.secretWord).update(signatureData).digest('hex');
|
|
64
|
+
params['signature'] = signature;
|
|
65
|
+
|
|
66
|
+
// URL Parametrelerini oluştur
|
|
67
|
+
const queryParams = new URLSearchParams();
|
|
68
|
+
Object.keys(params).forEach(key => queryParams.append(key, params[key]));
|
|
69
|
+
|
|
70
|
+
return `https://secure.2checkout.com/order/checkout.php?${queryParams.toString()}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* IPN (Callback) Doğrulama
|
|
75
|
+
* Bu kısım, sunucunuza gelen POST isteğini doğrular.
|
|
76
|
+
*/
|
|
77
|
+
verifyCallback(postData) {
|
|
78
|
+
try {
|
|
79
|
+
// Gelen veriden HASH'i ayıralım
|
|
80
|
+
const receivedHash = postData['HASH'];
|
|
81
|
+
if (!receivedHash) {
|
|
82
|
+
return { status: false, message: 'No hash found' };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let hashString = '';
|
|
86
|
+
|
|
87
|
+
// 2Checkout, HASH parametresi hariç tüm parametreleri gönderdiği sırayla kullanır.
|
|
88
|
+
for (let key in postData) {
|
|
89
|
+
if (key !== 'HASH') {
|
|
90
|
+
const val = String(postData[key]);
|
|
91
|
+
hashString += val.length + val;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const calculatedHash = crypto
|
|
96
|
+
.createHmac('md5', this.secretWord)
|
|
97
|
+
.update(hashString)
|
|
98
|
+
.digest('hex');
|
|
99
|
+
|
|
100
|
+
if (calculatedHash === receivedHash) {
|
|
101
|
+
const date = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
|
102
|
+
const responseHash = crypto.createHmac('md5', this.secretWord).update(postData.IPN_PID[0].length + postData.IPN_PID[0] + postData.IPN_PNAME[0].length + postData.IPN_PNAME[0] + postData.IPN_DATE.length + postData.IPN_DATE + date.length + date).digest('hex');
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
status: true,
|
|
106
|
+
transactionId: postData.REFNO,
|
|
107
|
+
orderStatus: postData.ORDERSTATUS,
|
|
108
|
+
raw: postData
|
|
109
|
+
};
|
|
110
|
+
} else {
|
|
111
|
+
console.error("Hash Mismatch. Calculated:", calculatedHash, "Received:", receivedHash);
|
|
112
|
+
return { status: false, message: 'Invalid hash signature' };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return { status: false, message: error.message };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = TwoCheckoutClient;
|
package/lib/paytr.js
CHANGED
|
@@ -98,63 +98,91 @@ class PayTR {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
// Direkt API için Otomatik Submit Eden HTML Formu Üretir
|
|
102
|
+
createDirectPayment(params) {
|
|
102
103
|
try {
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
const
|
|
104
|
+
// 1. Gerekli Parametrelerin Hazırlanması
|
|
105
|
+
const merchant_id = this.merchantId;
|
|
106
|
+
const user_ip = params.userIp;
|
|
107
|
+
const merchant_oid = params.merchantOid;
|
|
106
108
|
const email = params.email;
|
|
107
|
-
const
|
|
109
|
+
const payment_amount = params.paymentAmount.toString();
|
|
110
|
+
const payment_type = 'card';
|
|
111
|
+
const installment_count = params.installmentCount || '0';
|
|
108
112
|
const currency = params.currency || 'TL';
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
113
|
+
const test_mode = this.testMode;
|
|
114
|
+
const non_3d = params.non3D || '0';
|
|
115
|
+
|
|
116
|
+
// Sepet verisi JSON string olmalı
|
|
117
|
+
const user_basket = JSON.stringify(params.userBasket);
|
|
118
|
+
|
|
119
|
+
// 2. Token Oluşturma (Sıralama: merchant_id + user_ip + merchant_oid + email + payment_amount + payment_type + installment_count + currency + test_mode + non_3d)
|
|
120
|
+
const rawString = `${merchant_id}${user_ip}${merchant_oid}${email}${payment_amount}${payment_type}${installment_count}${currency}${test_mode}${non_3d}`;
|
|
121
|
+
const paytr_token = this.generateToken(rawString);
|
|
122
|
+
|
|
123
|
+
// 3. Form Verilerinin Hazırlanması
|
|
124
|
+
const formFields = {
|
|
125
|
+
merchant_id,
|
|
126
|
+
user_ip,
|
|
127
|
+
merchant_oid,
|
|
128
|
+
email,
|
|
129
|
+
payment_type,
|
|
130
|
+
payment_amount: Number(payment_amount),
|
|
131
|
+
currency,
|
|
132
|
+
test_mode,
|
|
133
|
+
non_3d,
|
|
134
|
+
merchant_ok_url: params.merchantOkUrl,
|
|
135
|
+
merchant_fail_url: params.merchantFailUrl,
|
|
136
|
+
user_name: params.userName,
|
|
137
|
+
user_address: params.userAddress,
|
|
138
|
+
user_phone: params.userPhone,
|
|
139
|
+
user_basket,
|
|
140
|
+
debug_on: this.debugOn,
|
|
141
|
+
client_lang: params.clientLang || 'tr',
|
|
142
|
+
paytr_token,
|
|
143
|
+
installment_count: installment_count,
|
|
144
|
+
card_type: params.cardType,
|
|
145
|
+
non3d_test_failed: params.non3dTestFailed || '0',
|
|
146
|
+
no_installment: params.noInstallment || '0',
|
|
147
|
+
max_installment: params.maxInstallment || '0',
|
|
148
|
+
lang: params.lang || 'tr',
|
|
149
|
+
// Kart Bilgileri (Form otomatik post edileceği için buraya eklenmeli)
|
|
150
|
+
cc_owner: params.cardOwner,
|
|
151
|
+
card_number: params.cardNumber,
|
|
152
|
+
expiry_month: params.cardExpireMonth,
|
|
153
|
+
expiry_year: params.cardExpireYear,
|
|
154
|
+
cvv: params.cardCvc
|
|
155
|
+
};
|
|
115
156
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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);
|
|
157
|
+
// 4. HTML Formunun Oluşturulması
|
|
158
|
+
// Form oluşturulur, inputlar gizlenir ve script ile otomatik submit edilir.
|
|
159
|
+
let html = `
|
|
160
|
+
<!DOCTYPE html>
|
|
161
|
+
<html>
|
|
162
|
+
<head><title>Redirecting to Payment...</title></head>
|
|
163
|
+
<body>
|
|
164
|
+
<form id="paytr_auto_form" action="https://www.paytr.com/odeme" method="post">
|
|
165
|
+
`;
|
|
166
|
+
|
|
167
|
+
for (const [key, value] of Object.entries(formFields)) {
|
|
168
|
+
// Değer undefined veya null ise boş string gönderelim, güvenlik için escape yapalım
|
|
169
|
+
const safeValue = value ? String(value).replace(/"/g, '"') : '';
|
|
170
|
+
html += `<input type="hidden" name="${key}" value="${safeValue}">\n`;
|
|
171
|
+
}
|
|
140
172
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
173
|
+
html += `
|
|
174
|
+
</form>
|
|
175
|
+
<script>
|
|
176
|
+
document.getElementById("paytr_auto_form").submit();
|
|
177
|
+
</script>
|
|
178
|
+
</body>
|
|
179
|
+
</html>
|
|
180
|
+
`;
|
|
147
181
|
|
|
148
|
-
|
|
182
|
+
return html;
|
|
149
183
|
|
|
150
|
-
if (result.status === 'success') {
|
|
151
|
-
return result;
|
|
152
|
-
} else {
|
|
153
|
-
throw new Error(result.reason || 'PayTR Direct API Hatası');
|
|
154
|
-
}
|
|
155
184
|
} catch (error) {
|
|
156
|
-
|
|
157
|
-
throw error;
|
|
185
|
+
throw new Error(`PayTR HTML oluşturma hatası: ${error.message}`);
|
|
158
186
|
}
|
|
159
187
|
}
|
|
160
188
|
|