playttm 0.0.5 → 0.0.7
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/dist/lib.d.ts +10 -1
- package/dist/lib.js +234 -26
- package/package.json +1 -1
- package/src/lib.ts +239 -23
package/dist/lib.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare const isBrowserEnvironment: () => boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Extract transaction amount from EMVCo / ThaiQR payload (Tag 54)
|
|
4
|
+
*/
|
|
5
|
+
export declare const parseThaiQRAmount: (qrCode?: string) => string | null;
|
|
2
6
|
export interface TTMConfig {
|
|
3
7
|
cookies?: string;
|
|
4
8
|
headers?: Record<string, string>;
|
|
@@ -81,12 +85,17 @@ export declare class ThaiTicketMajor {
|
|
|
81
85
|
inBrowser: boolean;
|
|
82
86
|
private rawCookies?;
|
|
83
87
|
constructor(config?: TTMConfig);
|
|
88
|
+
static readonly BOT_PROTECTION_COOKIES: Set<string>;
|
|
84
89
|
/**
|
|
85
90
|
* Synchronize a cookie string into Chrome Extension's cookie store (chrome.cookies API).
|
|
91
|
+
* Automatically ignores bot protection cookies (Akamai _abck, bm_*, WAF) to prevent Access Denied (403) bans.
|
|
86
92
|
*/
|
|
87
93
|
static syncCookiesToChrome(cookieString: string, domainUrl?: string): Promise<void>;
|
|
88
94
|
/**
|
|
89
|
-
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer
|
|
95
|
+
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer header for API requests only.
|
|
96
|
+
*/
|
|
97
|
+
/**
|
|
98
|
+
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer headers accurately for each endpoint.
|
|
90
99
|
*/
|
|
91
100
|
static setupExtensionRules(): Promise<void>;
|
|
92
101
|
syncCookies(domainUrl?: string): Promise<void>;
|
package/dist/lib.js
CHANGED
|
@@ -45,7 +45,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
45
45
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
46
|
};
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.displayQRCode = exports.ThaiTicketMajor = exports.isBrowserEnvironment = void 0;
|
|
48
|
+
exports.displayQRCode = exports.ThaiTicketMajor = exports.parseThaiQRAmount = exports.isBrowserEnvironment = void 0;
|
|
49
49
|
const axios_1 = __importDefault(require("axios"));
|
|
50
50
|
const cheerio = __importStar(require("cheerio"));
|
|
51
51
|
const axios_cookiejar_support_1 = require("axios-cookiejar-support");
|
|
@@ -64,6 +64,23 @@ const isBrowserEnvironment = () => {
|
|
|
64
64
|
return false;
|
|
65
65
|
};
|
|
66
66
|
exports.isBrowserEnvironment = isBrowserEnvironment;
|
|
67
|
+
/**
|
|
68
|
+
* Extract transaction amount from EMVCo / ThaiQR payload (Tag 54)
|
|
69
|
+
*/
|
|
70
|
+
const parseThaiQRAmount = (qrCode) => {
|
|
71
|
+
if (!qrCode)
|
|
72
|
+
return null;
|
|
73
|
+
const match = qrCode.match(/(?:^|[^0-9])54(\d{2})([0-9.]+)/);
|
|
74
|
+
if (match) {
|
|
75
|
+
const len = parseInt(match[1], 10);
|
|
76
|
+
const amountStr = match[2].substring(0, len);
|
|
77
|
+
if (!isNaN(parseFloat(amountStr))) {
|
|
78
|
+
return amountStr;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
};
|
|
83
|
+
exports.parseThaiQRAmount = parseThaiQRAmount;
|
|
67
84
|
// ==========================================
|
|
68
85
|
// Main Library Class
|
|
69
86
|
// ==========================================
|
|
@@ -109,6 +126,7 @@ class ThaiTicketMajor {
|
|
|
109
126
|
}
|
|
110
127
|
/**
|
|
111
128
|
* Synchronize a cookie string into Chrome Extension's cookie store (chrome.cookies API).
|
|
129
|
+
* Automatically ignores bot protection cookies (Akamai _abck, bm_*, WAF) to prevent Access Denied (403) bans.
|
|
112
130
|
*/
|
|
113
131
|
static syncCookiesToChrome(cookieString_1) {
|
|
114
132
|
return __awaiter(this, arguments, void 0, function* (cookieString, domainUrl = "https://booking.thaiticketmajor.com") {
|
|
@@ -128,6 +146,11 @@ class ThaiTicketMajor {
|
|
|
128
146
|
const value = trimmed.substring(eqIndex + 1).trim();
|
|
129
147
|
if (!name)
|
|
130
148
|
continue;
|
|
149
|
+
// DO NOT overwrite Akamai / WAF bot tokens!
|
|
150
|
+
// Writing stale _abck or bm_* triggers Akamai Bot Protection -> Access Denied.
|
|
151
|
+
if (ThaiTicketMajor.BOT_PROTECTION_COOKIES.has(name.toLowerCase())) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
131
154
|
try {
|
|
132
155
|
yield chrome.cookies.set({
|
|
133
156
|
url: domainUrl,
|
|
@@ -152,55 +175,171 @@ class ThaiTicketMajor {
|
|
|
152
175
|
});
|
|
153
176
|
}
|
|
154
177
|
/**
|
|
155
|
-
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer
|
|
178
|
+
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer header for API requests only.
|
|
179
|
+
*/
|
|
180
|
+
/**
|
|
181
|
+
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer headers accurately for each endpoint.
|
|
156
182
|
*/
|
|
157
183
|
static setupExtensionRules() {
|
|
158
184
|
return __awaiter(this, void 0, void 0, function* () {
|
|
159
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
185
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
|
|
160
186
|
if (typeof chrome === "undefined" || !((_a = chrome === null || chrome === void 0 ? void 0 : chrome.declarativeNetRequest) === null || _a === void 0 ? void 0 : _a.updateSessionRules)) {
|
|
161
187
|
return;
|
|
162
188
|
}
|
|
163
189
|
try {
|
|
190
|
+
const ruleIdsToRemove = [1001, 1002, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019];
|
|
164
191
|
yield chrome.declarativeNetRequest.updateSessionRules({
|
|
165
|
-
removeRuleIds:
|
|
192
|
+
removeRuleIds: ruleIdsToRemove,
|
|
166
193
|
addRules: [
|
|
167
194
|
{
|
|
168
|
-
id:
|
|
169
|
-
priority:
|
|
195
|
+
id: 1010,
|
|
196
|
+
priority: 20,
|
|
170
197
|
action: {
|
|
171
198
|
type: ((_b = chrome.declarativeNetRequest.RuleActionType) === null || _b === void 0 ? void 0 : _b.MODIFY_HEADERS) || "modifyHeaders",
|
|
172
199
|
requestHeaders: [
|
|
173
200
|
{
|
|
174
201
|
header: "Referer",
|
|
175
202
|
operation: ((_c = chrome.declarativeNetRequest.HeaderOperation) === null || _c === void 0 ? void 0 : _c.SET) || "set",
|
|
176
|
-
value: "https://booking.thaiticketmajor.com",
|
|
203
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/orderenc_kbankqr.php",
|
|
177
204
|
},
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
condition: {
|
|
208
|
+
urlFilter: "getkbankqr.php",
|
|
209
|
+
resourceTypes: [
|
|
210
|
+
((_d = chrome.declarativeNetRequest.ResourceType) === null || _d === void 0 ? void 0 : _d.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: 1011,
|
|
216
|
+
priority: 20,
|
|
217
|
+
action: {
|
|
218
|
+
type: ((_e = chrome.declarativeNetRequest.RuleActionType) === null || _e === void 0 ? void 0 : _e.MODIFY_HEADERS) || "modifyHeaders",
|
|
219
|
+
requestHeaders: [
|
|
178
220
|
{
|
|
179
|
-
header: "
|
|
180
|
-
operation: ((
|
|
181
|
-
value: "https://booking.thaiticketmajor.com",
|
|
221
|
+
header: "Referer",
|
|
222
|
+
operation: ((_f = chrome.declarativeNetRequest.HeaderOperation) === null || _f === void 0 ? void 0 : _f.SET) || "set",
|
|
223
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/orderenc_kbankqr.php",
|
|
182
224
|
},
|
|
183
225
|
],
|
|
184
226
|
},
|
|
185
227
|
condition: {
|
|
186
|
-
urlFilter: "
|
|
228
|
+
urlFilter: "payment_kbankqr.php",
|
|
229
|
+
resourceTypes: [
|
|
230
|
+
((_g = chrome.declarativeNetRequest.ResourceType) === null || _g === void 0 ? void 0 : _g.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
id: 1012,
|
|
236
|
+
priority: 20,
|
|
237
|
+
action: {
|
|
238
|
+
type: ((_h = chrome.declarativeNetRequest.RuleActionType) === null || _h === void 0 ? void 0 : _h.MODIFY_HEADERS) || "modifyHeaders",
|
|
239
|
+
requestHeaders: [
|
|
240
|
+
{
|
|
241
|
+
header: "Referer",
|
|
242
|
+
operation: ((_j = chrome.declarativeNetRequest.HeaderOperation) === null || _j === void 0 ? void 0 : _j.SET) || "set",
|
|
243
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/paycfmall.php",
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
condition: {
|
|
248
|
+
urlFilter: "orderenc_kbankqr.php",
|
|
249
|
+
resourceTypes: [
|
|
250
|
+
((_k = chrome.declarativeNetRequest.ResourceType) === null || _k === void 0 ? void 0 : _k.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: 1013,
|
|
256
|
+
priority: 20,
|
|
257
|
+
action: {
|
|
258
|
+
type: ((_l = chrome.declarativeNetRequest.RuleActionType) === null || _l === void 0 ? void 0 : _l.MODIFY_HEADERS) || "modifyHeaders",
|
|
259
|
+
requestHeaders: [
|
|
260
|
+
{
|
|
261
|
+
header: "Referer",
|
|
262
|
+
operation: ((_m = chrome.declarativeNetRequest.HeaderOperation) === null || _m === void 0 ? void 0 : _m.SET) || "set",
|
|
263
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/paymentall.php",
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
condition: {
|
|
268
|
+
urlFilter: "paycfmall.php",
|
|
269
|
+
resourceTypes: [
|
|
270
|
+
((_o = chrome.declarativeNetRequest.ResourceType) === null || _o === void 0 ? void 0 : _o.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
id: 1014,
|
|
276
|
+
priority: 20,
|
|
277
|
+
action: {
|
|
278
|
+
type: ((_p = chrome.declarativeNetRequest.RuleActionType) === null || _p === void 0 ? void 0 : _p.MODIFY_HEADERS) || "modifyHeaders",
|
|
279
|
+
requestHeaders: [
|
|
280
|
+
{
|
|
281
|
+
header: "Referer",
|
|
282
|
+
operation: ((_q = chrome.declarativeNetRequest.HeaderOperation) === null || _q === void 0 ? void 0 : _q.SET) || "set",
|
|
283
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/fixed.php",
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
},
|
|
287
|
+
condition: {
|
|
288
|
+
urlFilter: "paymentall.php",
|
|
187
289
|
resourceTypes: [
|
|
188
|
-
((
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
290
|
+
((_r = chrome.declarativeNetRequest.ResourceType) === null || _r === void 0 ? void 0 : _r.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: 1015,
|
|
296
|
+
priority: 20,
|
|
297
|
+
action: {
|
|
298
|
+
type: ((_s = chrome.declarativeNetRequest.RuleActionType) === null || _s === void 0 ? void 0 : _s.MODIFY_HEADERS) || "modifyHeaders",
|
|
299
|
+
requestHeaders: [
|
|
300
|
+
{
|
|
301
|
+
header: "Referer",
|
|
302
|
+
operation: ((_t = chrome.declarativeNetRequest.HeaderOperation) === null || _t === void 0 ? void 0 : _t.SET) || "set",
|
|
303
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/fixed.php",
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
},
|
|
307
|
+
condition: {
|
|
308
|
+
urlFilter: "enroll",
|
|
309
|
+
resourceTypes: [
|
|
310
|
+
((_u = chrome.declarativeNetRequest.ResourceType) === null || _u === void 0 ? void 0 : _u.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
id: 1018,
|
|
316
|
+
priority: 20,
|
|
317
|
+
action: {
|
|
318
|
+
type: ((_v = chrome.declarativeNetRequest.RuleActionType) === null || _v === void 0 ? void 0 : _v.MODIFY_HEADERS) || "modifyHeaders",
|
|
319
|
+
requestHeaders: [
|
|
320
|
+
{
|
|
321
|
+
header: "Referer",
|
|
322
|
+
operation: ((_w = chrome.declarativeNetRequest.HeaderOperation) === null || _w === void 0 ? void 0 : _w.SET) || "set",
|
|
323
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/zones.php",
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
},
|
|
327
|
+
condition: {
|
|
328
|
+
urlFilter: "zonesavail.php",
|
|
329
|
+
resourceTypes: [
|
|
330
|
+
((_x = chrome.declarativeNetRequest.ResourceType) === null || _x === void 0 ? void 0 : _x.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
192
331
|
],
|
|
193
332
|
},
|
|
194
333
|
},
|
|
195
334
|
{
|
|
196
335
|
id: 1002,
|
|
197
|
-
priority:
|
|
336
|
+
priority: 20,
|
|
198
337
|
action: {
|
|
199
|
-
type: ((
|
|
338
|
+
type: ((_y = chrome.declarativeNetRequest.RuleActionType) === null || _y === void 0 ? void 0 : _y.MODIFY_HEADERS) || "modifyHeaders",
|
|
200
339
|
requestHeaders: [
|
|
201
340
|
{
|
|
202
341
|
header: "Referer",
|
|
203
|
-
operation: ((
|
|
342
|
+
operation: ((_z = chrome.declarativeNetRequest.HeaderOperation) === null || _z === void 0 ? void 0 : _z.SET) || "set",
|
|
204
343
|
value: "https://kpaymentgateway.kasikornbank.com/",
|
|
205
344
|
},
|
|
206
345
|
],
|
|
@@ -208,8 +347,27 @@ class ThaiTicketMajor {
|
|
|
208
347
|
condition: {
|
|
209
348
|
urlFilter: "kasikornbank.com",
|
|
210
349
|
resourceTypes: [
|
|
211
|
-
((
|
|
212
|
-
|
|
350
|
+
((_0 = chrome.declarativeNetRequest.ResourceType) === null || _0 === void 0 ? void 0 : _0.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
351
|
+
],
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
id: 1001,
|
|
356
|
+
priority: 1,
|
|
357
|
+
action: {
|
|
358
|
+
type: ((_1 = chrome.declarativeNetRequest.RuleActionType) === null || _1 === void 0 ? void 0 : _1.MODIFY_HEADERS) || "modifyHeaders",
|
|
359
|
+
requestHeaders: [
|
|
360
|
+
{
|
|
361
|
+
header: "Referer",
|
|
362
|
+
operation: ((_2 = chrome.declarativeNetRequest.HeaderOperation) === null || _2 === void 0 ? void 0 : _2.SET) || "set",
|
|
363
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/",
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
condition: {
|
|
368
|
+
urlFilter: "thaiticketmajor.com",
|
|
369
|
+
resourceTypes: [
|
|
370
|
+
((_3 = chrome.declarativeNetRequest.ResourceType) === null || _3 === void 0 ? void 0 : _3.XMLHTTPREQUEST) || "xmlhttprequest",
|
|
213
371
|
],
|
|
214
372
|
},
|
|
215
373
|
},
|
|
@@ -724,6 +882,12 @@ class ThaiTicketMajor {
|
|
|
724
882
|
const response = yield this.client.post(`${this.endpoint}/orderenc_kbankqr.php`, formData.toString(), {
|
|
725
883
|
headers: Object.assign(Object.assign({}, this.defaultHeaders), { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", "x-requested-with": "XMLHttpRequest", referer: `${this.endpoint}/paycfmall.php?k=${k}` }),
|
|
726
884
|
});
|
|
885
|
+
this.emitProgress("ORDER_ENC_KBANK_RES", `Received orderenc_kbankqr.php response`, {
|
|
886
|
+
url: `${this.endpoint}/orderenc_kbankqr.php`,
|
|
887
|
+
requestPayload: payCfmData,
|
|
888
|
+
responseStatus: response.status,
|
|
889
|
+
responseData: response.data,
|
|
890
|
+
});
|
|
727
891
|
const $ = cheerio.load(response.data);
|
|
728
892
|
const kbankqrData = {};
|
|
729
893
|
$("#kbankqr input[type='hidden']").each((_, el) => {
|
|
@@ -747,6 +911,12 @@ class ThaiTicketMajor {
|
|
|
747
911
|
const response = yield this.client.post(`${this.endpoint}/getkbankqr.php`, formData.toString(), {
|
|
748
912
|
headers: Object.assign(Object.assign({}, this.defaultHeaders), { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", "x-requested-with": "XMLHttpRequest", referer: `${this.endpoint}/orderenc_kbankqr.php` }),
|
|
749
913
|
});
|
|
914
|
+
this.emitProgress("GET_KBANK_QR_RES", `Received getkbankqr.php response`, {
|
|
915
|
+
url: `${this.endpoint}/getkbankqr.php`,
|
|
916
|
+
requestPayload: orderEncData,
|
|
917
|
+
responseStatus: response.status,
|
|
918
|
+
responseData: response.data,
|
|
919
|
+
});
|
|
750
920
|
return response.data;
|
|
751
921
|
});
|
|
752
922
|
}
|
|
@@ -757,11 +927,17 @@ class ThaiTicketMajor {
|
|
|
757
927
|
return __awaiter(this, void 0, void 0, function* () {
|
|
758
928
|
var _a, _b;
|
|
759
929
|
this.emitProgress("PAYMENT_KBANK_QR", `Extracting KBank OrderID and API Key`);
|
|
760
|
-
const preparePayload = Object.assign(Object.assign({}, orderEncData), { reasoncode: kbankPayload.reasoncode, eventname: kbankPayload.eventname, rounddetail: kbankPayload.rounddetail, totalamount: kbankPayload.totalamount, orderstatus: kbankPayload.orderstatus, kbankqr_txExpiry: kbankPayload.kbankqr_txExpiry });
|
|
930
|
+
const preparePayload = Object.assign(Object.assign({}, orderEncData), { reasoncode: kbankPayload === null || kbankPayload === void 0 ? void 0 : kbankPayload.reasoncode, eventname: kbankPayload === null || kbankPayload === void 0 ? void 0 : kbankPayload.eventname, rounddetail: kbankPayload === null || kbankPayload === void 0 ? void 0 : kbankPayload.rounddetail, totalamount: kbankPayload === null || kbankPayload === void 0 ? void 0 : kbankPayload.totalamount, orderstatus: kbankPayload === null || kbankPayload === void 0 ? void 0 : kbankPayload.orderstatus, kbankqr_txExpiry: kbankPayload === null || kbankPayload === void 0 ? void 0 : kbankPayload.kbankqr_txExpiry });
|
|
761
931
|
const formData = new URLSearchParams(preparePayload);
|
|
762
932
|
const response = yield this.client.post(`${this.endpoint}/payment_kbankqr.php`, formData.toString(), {
|
|
763
933
|
headers: Object.assign(Object.assign({}, this.defaultHeaders), { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", "x-requested-with": "XMLHttpRequest", referer: `${this.endpoint}/orderenc_kbankqr.php` }),
|
|
764
934
|
});
|
|
935
|
+
this.emitProgress("PAYMENT_KBANK_QR_RES", `Received payment_kbankqr.php response`, {
|
|
936
|
+
url: `${this.endpoint}/payment_kbankqr.php`,
|
|
937
|
+
requestPayload: preparePayload,
|
|
938
|
+
responseStatus: response.status,
|
|
939
|
+
responseData: response.data,
|
|
940
|
+
});
|
|
765
941
|
const $ = cheerio.load(response.data);
|
|
766
942
|
const script = $("#kbankpost script[data-order-id]");
|
|
767
943
|
const orderId = (_a = script.attr("data-order-id")) !== null && _a !== void 0 ? _a : "";
|
|
@@ -799,7 +975,7 @@ class ThaiTicketMajor {
|
|
|
799
975
|
*/
|
|
800
976
|
quickBook(options) {
|
|
801
977
|
return __awaiter(this, void 0, void 0, function* () {
|
|
802
|
-
var _a, _b, _c, _d;
|
|
978
|
+
var _a, _b, _c, _d, _e;
|
|
803
979
|
const { eventUrl, roundIndex = 0, roundId, zoneId, ticketCount = 1, seatSelection = "random", attendees = [], deliveryType = "1", payType = "KBQR", paymentDelayMs = 1500, } = options;
|
|
804
980
|
if (options.onProgress) {
|
|
805
981
|
this.onProgressCallback = options.onProgress;
|
|
@@ -928,7 +1104,14 @@ class ThaiTicketMajor {
|
|
|
928
1104
|
const orderEncData = yield this.orderEncKBankQR(zoneData.k, payCfmData);
|
|
929
1105
|
const kbankInfo = yield this.getKBankQR(orderEncData);
|
|
930
1106
|
const kbankAuth = yield this.paymentKBankQR(orderEncData, kbankInfo);
|
|
931
|
-
const
|
|
1107
|
+
const targetAmount = orderEncData.transactionamount ||
|
|
1108
|
+
orderEncData.totalamount ||
|
|
1109
|
+
orderEncData.amount ||
|
|
1110
|
+
payCfmData.amount ||
|
|
1111
|
+
kbankInfo.totalamount ||
|
|
1112
|
+
paymentAllData["cal_totalamount"] ||
|
|
1113
|
+
"0";
|
|
1114
|
+
const qrResult = yield this.generateThaiQR(kbankAuth.orderId, kbankAuth.apiKey, targetAmount);
|
|
932
1115
|
const qrRawCode = (qrResult === null || qrResult === void 0 ? void 0 : qrResult.paint_text) ||
|
|
933
1116
|
(qrResult === null || qrResult === void 0 ? void 0 : qrResult.raw_qr_code) ||
|
|
934
1117
|
(qrResult === null || qrResult === void 0 ? void 0 : qrResult.qr_code) ||
|
|
@@ -936,8 +1119,14 @@ class ThaiTicketMajor {
|
|
|
936
1119
|
((_c = qrResult === null || qrResult === void 0 ? void 0 : qrResult.data) === null || _c === void 0 ? void 0 : _c.qr_code) ||
|
|
937
1120
|
((_d = qrResult === null || qrResult === void 0 ? void 0 : qrResult.data) === null || _d === void 0 ? void 0 : _d.raw_qr_code) ||
|
|
938
1121
|
(typeof qrResult === "string" ? qrResult : "");
|
|
1122
|
+
const qrAmount = (0, exports.parseThaiQRAmount)(qrRawCode);
|
|
1123
|
+
const finalAmount = qrAmount ||
|
|
1124
|
+
(targetAmount && targetAmount !== "0" ? targetAmount : null) ||
|
|
1125
|
+
(qrResult === null || qrResult === void 0 ? void 0 : qrResult.amount) ||
|
|
1126
|
+
((_e = qrResult === null || qrResult === void 0 ? void 0 : qrResult.data) === null || _e === void 0 ? void 0 : _e.amount) ||
|
|
1127
|
+
"0";
|
|
939
1128
|
const displayQR = (customTitle) => {
|
|
940
|
-
const title = customTitle || `ThaiQR Payment (KBank) - ยอดชำระ: ${
|
|
1129
|
+
const title = customTitle || `ThaiQR Payment (KBank) - ยอดชำระ: ${finalAmount} บาท`;
|
|
941
1130
|
ThaiTicketMajor.displayQRCode(qrRawCode, title);
|
|
942
1131
|
};
|
|
943
1132
|
if (options.printQR !== false && qrRawCode) {
|
|
@@ -946,7 +1135,7 @@ class ThaiTicketMajor {
|
|
|
946
1135
|
return {
|
|
947
1136
|
success: true,
|
|
948
1137
|
orderId: kbankAuth.orderId,
|
|
949
|
-
amount:
|
|
1138
|
+
amount: String(finalAmount),
|
|
950
1139
|
qrRawCode,
|
|
951
1140
|
qrData: qrResult,
|
|
952
1141
|
displayQR,
|
|
@@ -957,7 +1146,7 @@ class ThaiTicketMajor {
|
|
|
957
1146
|
venue: paymentAllData["venue"],
|
|
958
1147
|
zone: targetZone.value,
|
|
959
1148
|
ticketCount,
|
|
960
|
-
totalAmount:
|
|
1149
|
+
totalAmount: String(finalAmount),
|
|
961
1150
|
seats: summarySeats.length > 0 ? summarySeats : undefined,
|
|
962
1151
|
},
|
|
963
1152
|
rawPayload: {
|
|
@@ -989,5 +1178,24 @@ class ThaiTicketMajor {
|
|
|
989
1178
|
}
|
|
990
1179
|
}
|
|
991
1180
|
exports.ThaiTicketMajor = ThaiTicketMajor;
|
|
1181
|
+
ThaiTicketMajor.BOT_PROTECTION_COOKIES = new Set([
|
|
1182
|
+
"_abck",
|
|
1183
|
+
"bm_sz",
|
|
1184
|
+
"ak_bmsc",
|
|
1185
|
+
"bm_sv",
|
|
1186
|
+
"bm_mi",
|
|
1187
|
+
"hwwafsesid",
|
|
1188
|
+
"hwwafsestime",
|
|
1189
|
+
"__cf_bm",
|
|
1190
|
+
"cf_clearance",
|
|
1191
|
+
"_ga",
|
|
1192
|
+
"_gid",
|
|
1193
|
+
"_gcl_au",
|
|
1194
|
+
"_fbp",
|
|
1195
|
+
"_clck",
|
|
1196
|
+
"_clsk",
|
|
1197
|
+
"_ttp",
|
|
1198
|
+
"_twpid",
|
|
1199
|
+
]);
|
|
992
1200
|
exports.displayQRCode = ThaiTicketMajor.displayQRCode;
|
|
993
1201
|
exports.default = ThaiTicketMajor;
|
package/package.json
CHANGED
package/src/lib.ts
CHANGED
|
@@ -18,6 +18,22 @@ export const isBrowserEnvironment = (): boolean => {
|
|
|
18
18
|
return false;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Extract transaction amount from EMVCo / ThaiQR payload (Tag 54)
|
|
23
|
+
*/
|
|
24
|
+
export const parseThaiQRAmount = (qrCode?: string): string | null => {
|
|
25
|
+
if (!qrCode) return null;
|
|
26
|
+
const match = qrCode.match(/(?:^|[^0-9])54(\d{2})([0-9.]+)/);
|
|
27
|
+
if (match) {
|
|
28
|
+
const len = parseInt(match[1], 10);
|
|
29
|
+
const amountStr = match[2].substring(0, len);
|
|
30
|
+
if (!isNaN(parseFloat(amountStr))) {
|
|
31
|
+
return amountStr;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
};
|
|
36
|
+
|
|
21
37
|
// ==========================================
|
|
22
38
|
// Interfaces & Types
|
|
23
39
|
// ==========================================
|
|
@@ -175,8 +191,29 @@ export class ThaiTicketMajor {
|
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
|
|
194
|
+
public static readonly BOT_PROTECTION_COOKIES = new Set([
|
|
195
|
+
"_abck",
|
|
196
|
+
"bm_sz",
|
|
197
|
+
"ak_bmsc",
|
|
198
|
+
"bm_sv",
|
|
199
|
+
"bm_mi",
|
|
200
|
+
"hwwafsesid",
|
|
201
|
+
"hwwafsestime",
|
|
202
|
+
"__cf_bm",
|
|
203
|
+
"cf_clearance",
|
|
204
|
+
"_ga",
|
|
205
|
+
"_gid",
|
|
206
|
+
"_gcl_au",
|
|
207
|
+
"_fbp",
|
|
208
|
+
"_clck",
|
|
209
|
+
"_clsk",
|
|
210
|
+
"_ttp",
|
|
211
|
+
"_twpid",
|
|
212
|
+
]);
|
|
213
|
+
|
|
178
214
|
/**
|
|
179
215
|
* Synchronize a cookie string into Chrome Extension's cookie store (chrome.cookies API).
|
|
216
|
+
* Automatically ignores bot protection cookies (Akamai _abck, bm_*, WAF) to prevent Access Denied (403) bans.
|
|
180
217
|
*/
|
|
181
218
|
public static async syncCookiesToChrome(cookieString: string, domainUrl: string = "https://booking.thaiticketmajor.com"): Promise<void> {
|
|
182
219
|
if (typeof chrome === "undefined" || !chrome?.cookies?.set) {
|
|
@@ -194,6 +231,12 @@ export class ThaiTicketMajor {
|
|
|
194
231
|
const value = trimmed.substring(eqIndex + 1).trim();
|
|
195
232
|
if (!name) continue;
|
|
196
233
|
|
|
234
|
+
// DO NOT overwrite Akamai / WAF bot tokens!
|
|
235
|
+
// Writing stale _abck or bm_* triggers Akamai Bot Protection -> Access Denied.
|
|
236
|
+
if (ThaiTicketMajor.BOT_PROTECTION_COOKIES.has(name.toLowerCase())) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
|
|
197
240
|
try {
|
|
198
241
|
await chrome.cookies.set({
|
|
199
242
|
url: domainUrl,
|
|
@@ -216,7 +259,10 @@ export class ThaiTicketMajor {
|
|
|
216
259
|
}
|
|
217
260
|
|
|
218
261
|
/**
|
|
219
|
-
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer
|
|
262
|
+
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer header for API requests only.
|
|
263
|
+
*/
|
|
264
|
+
/**
|
|
265
|
+
* Setup declarativeNetRequest session rules in Chrome Extension to set Referer headers accurately for each endpoint.
|
|
220
266
|
*/
|
|
221
267
|
public static async setupExtensionRules(): Promise<void> {
|
|
222
268
|
if (typeof chrome === "undefined" || !chrome?.declarativeNetRequest?.updateSessionRules) {
|
|
@@ -224,40 +270,153 @@ export class ThaiTicketMajor {
|
|
|
224
270
|
}
|
|
225
271
|
|
|
226
272
|
try {
|
|
273
|
+
const ruleIdsToRemove = [1001, 1002, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019];
|
|
227
274
|
await chrome.declarativeNetRequest.updateSessionRules({
|
|
228
|
-
removeRuleIds:
|
|
275
|
+
removeRuleIds: ruleIdsToRemove,
|
|
229
276
|
addRules: [
|
|
230
277
|
{
|
|
231
|
-
id:
|
|
232
|
-
priority:
|
|
278
|
+
id: 1010,
|
|
279
|
+
priority: 20,
|
|
233
280
|
action: {
|
|
234
281
|
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
235
282
|
requestHeaders: [
|
|
236
283
|
{
|
|
237
284
|
header: "Referer",
|
|
238
285
|
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
239
|
-
value: "https://booking.thaiticketmajor.com",
|
|
286
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/orderenc_kbankqr.php",
|
|
240
287
|
},
|
|
288
|
+
],
|
|
289
|
+
},
|
|
290
|
+
condition: {
|
|
291
|
+
urlFilter: "getkbankqr.php",
|
|
292
|
+
resourceTypes: [
|
|
293
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
id: 1011,
|
|
299
|
+
priority: 20,
|
|
300
|
+
action: {
|
|
301
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
302
|
+
requestHeaders: [
|
|
241
303
|
{
|
|
242
|
-
header: "
|
|
304
|
+
header: "Referer",
|
|
243
305
|
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
244
|
-
value: "https://booking.thaiticketmajor.com",
|
|
306
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/orderenc_kbankqr.php",
|
|
245
307
|
},
|
|
246
308
|
],
|
|
247
309
|
},
|
|
248
310
|
condition: {
|
|
249
|
-
urlFilter: "
|
|
311
|
+
urlFilter: "payment_kbankqr.php",
|
|
312
|
+
resourceTypes: [
|
|
313
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
id: 1012,
|
|
319
|
+
priority: 20,
|
|
320
|
+
action: {
|
|
321
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
322
|
+
requestHeaders: [
|
|
323
|
+
{
|
|
324
|
+
header: "Referer",
|
|
325
|
+
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
326
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/paycfmall.php",
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
condition: {
|
|
331
|
+
urlFilter: "orderenc_kbankqr.php",
|
|
332
|
+
resourceTypes: [
|
|
333
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: 1013,
|
|
339
|
+
priority: 20,
|
|
340
|
+
action: {
|
|
341
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
342
|
+
requestHeaders: [
|
|
343
|
+
{
|
|
344
|
+
header: "Referer",
|
|
345
|
+
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
346
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/paymentall.php",
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
},
|
|
350
|
+
condition: {
|
|
351
|
+
urlFilter: "paycfmall.php",
|
|
352
|
+
resourceTypes: [
|
|
353
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
354
|
+
],
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
id: 1014,
|
|
359
|
+
priority: 20,
|
|
360
|
+
action: {
|
|
361
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
362
|
+
requestHeaders: [
|
|
363
|
+
{
|
|
364
|
+
header: "Referer",
|
|
365
|
+
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
366
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/fixed.php",
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
},
|
|
370
|
+
condition: {
|
|
371
|
+
urlFilter: "paymentall.php",
|
|
372
|
+
resourceTypes: [
|
|
373
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
374
|
+
],
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
id: 1015,
|
|
379
|
+
priority: 20,
|
|
380
|
+
action: {
|
|
381
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
382
|
+
requestHeaders: [
|
|
383
|
+
{
|
|
384
|
+
header: "Referer",
|
|
385
|
+
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
386
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/fixed.php",
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
condition: {
|
|
391
|
+
urlFilter: "enroll",
|
|
392
|
+
resourceTypes: [
|
|
393
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
394
|
+
],
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
id: 1018,
|
|
399
|
+
priority: 20,
|
|
400
|
+
action: {
|
|
401
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
402
|
+
requestHeaders: [
|
|
403
|
+
{
|
|
404
|
+
header: "Referer",
|
|
405
|
+
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
406
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/zones.php",
|
|
407
|
+
},
|
|
408
|
+
],
|
|
409
|
+
},
|
|
410
|
+
condition: {
|
|
411
|
+
urlFilter: "zonesavail.php",
|
|
250
412
|
resourceTypes: [
|
|
251
413
|
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
252
|
-
chrome.declarativeNetRequest.ResourceType?.SUB_FRAME || "sub_frame",
|
|
253
|
-
chrome.declarativeNetRequest.ResourceType?.MAIN_FRAME || "main_frame",
|
|
254
|
-
chrome.declarativeNetRequest.ResourceType?.OTHER || "other",
|
|
255
414
|
],
|
|
256
415
|
},
|
|
257
416
|
},
|
|
258
417
|
{
|
|
259
418
|
id: 1002,
|
|
260
|
-
priority:
|
|
419
|
+
priority: 20,
|
|
261
420
|
action: {
|
|
262
421
|
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
263
422
|
requestHeaders: [
|
|
@@ -272,7 +431,26 @@ export class ThaiTicketMajor {
|
|
|
272
431
|
urlFilter: "kasikornbank.com",
|
|
273
432
|
resourceTypes: [
|
|
274
433
|
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
275
|
-
|
|
434
|
+
],
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 1001,
|
|
439
|
+
priority: 1,
|
|
440
|
+
action: {
|
|
441
|
+
type: chrome.declarativeNetRequest.RuleActionType?.MODIFY_HEADERS || "modifyHeaders",
|
|
442
|
+
requestHeaders: [
|
|
443
|
+
{
|
|
444
|
+
header: "Referer",
|
|
445
|
+
operation: chrome.declarativeNetRequest.HeaderOperation?.SET || "set",
|
|
446
|
+
value: "https://booking.thaiticketmajor.com/booking/3m/",
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
},
|
|
450
|
+
condition: {
|
|
451
|
+
urlFilter: "thaiticketmajor.com",
|
|
452
|
+
resourceTypes: [
|
|
453
|
+
chrome.declarativeNetRequest.ResourceType?.XMLHTTPREQUEST || "xmlhttprequest",
|
|
276
454
|
],
|
|
277
455
|
},
|
|
278
456
|
},
|
|
@@ -964,6 +1142,13 @@ export class ThaiTicketMajor {
|
|
|
964
1142
|
},
|
|
965
1143
|
});
|
|
966
1144
|
|
|
1145
|
+
this.emitProgress("ORDER_ENC_KBANK_RES", `Received orderenc_kbankqr.php response`, {
|
|
1146
|
+
url: `${this.endpoint}/orderenc_kbankqr.php`,
|
|
1147
|
+
requestPayload: payCfmData,
|
|
1148
|
+
responseStatus: response.status,
|
|
1149
|
+
responseData: response.data,
|
|
1150
|
+
});
|
|
1151
|
+
|
|
967
1152
|
const $ = cheerio.load(response.data);
|
|
968
1153
|
const kbankqrData: Record<string, string> = {};
|
|
969
1154
|
|
|
@@ -995,6 +1180,13 @@ export class ThaiTicketMajor {
|
|
|
995
1180
|
},
|
|
996
1181
|
});
|
|
997
1182
|
|
|
1183
|
+
this.emitProgress("GET_KBANK_QR_RES", `Received getkbankqr.php response`, {
|
|
1184
|
+
url: `${this.endpoint}/getkbankqr.php`,
|
|
1185
|
+
requestPayload: orderEncData,
|
|
1186
|
+
responseStatus: response.status,
|
|
1187
|
+
responseData: response.data,
|
|
1188
|
+
});
|
|
1189
|
+
|
|
998
1190
|
return response.data;
|
|
999
1191
|
}
|
|
1000
1192
|
|
|
@@ -1009,12 +1201,12 @@ export class ThaiTicketMajor {
|
|
|
1009
1201
|
|
|
1010
1202
|
const preparePayload = {
|
|
1011
1203
|
...orderEncData,
|
|
1012
|
-
reasoncode: kbankPayload
|
|
1013
|
-
eventname: kbankPayload
|
|
1014
|
-
rounddetail: kbankPayload
|
|
1015
|
-
totalamount: kbankPayload
|
|
1016
|
-
orderstatus: kbankPayload
|
|
1017
|
-
kbankqr_txExpiry: kbankPayload
|
|
1204
|
+
reasoncode: kbankPayload?.reasoncode,
|
|
1205
|
+
eventname: kbankPayload?.eventname,
|
|
1206
|
+
rounddetail: kbankPayload?.rounddetail,
|
|
1207
|
+
totalamount: kbankPayload?.totalamount,
|
|
1208
|
+
orderstatus: kbankPayload?.orderstatus,
|
|
1209
|
+
kbankqr_txExpiry: kbankPayload?.kbankqr_txExpiry,
|
|
1018
1210
|
};
|
|
1019
1211
|
|
|
1020
1212
|
const formData = new URLSearchParams(preparePayload);
|
|
@@ -1028,6 +1220,13 @@ export class ThaiTicketMajor {
|
|
|
1028
1220
|
},
|
|
1029
1221
|
});
|
|
1030
1222
|
|
|
1223
|
+
this.emitProgress("PAYMENT_KBANK_QR_RES", `Received payment_kbankqr.php response`, {
|
|
1224
|
+
url: `${this.endpoint}/payment_kbankqr.php`,
|
|
1225
|
+
requestPayload: preparePayload,
|
|
1226
|
+
responseStatus: response.status,
|
|
1227
|
+
responseData: response.data,
|
|
1228
|
+
});
|
|
1229
|
+
|
|
1031
1230
|
const $ = cheerio.load(response.data);
|
|
1032
1231
|
const script = $("#kbankpost script[data-order-id]");
|
|
1033
1232
|
|
|
@@ -1234,7 +1433,16 @@ export class ThaiTicketMajor {
|
|
|
1234
1433
|
const kbankInfo = await this.getKBankQR(orderEncData);
|
|
1235
1434
|
const kbankAuth = await this.paymentKBankQR(orderEncData, kbankInfo);
|
|
1236
1435
|
|
|
1237
|
-
const
|
|
1436
|
+
const targetAmount =
|
|
1437
|
+
orderEncData.transactionamount ||
|
|
1438
|
+
orderEncData.totalamount ||
|
|
1439
|
+
orderEncData.amount ||
|
|
1440
|
+
payCfmData.amount ||
|
|
1441
|
+
kbankInfo.totalamount ||
|
|
1442
|
+
paymentAllData["cal_totalamount"] ||
|
|
1443
|
+
"0";
|
|
1444
|
+
|
|
1445
|
+
const qrResult = await this.generateThaiQR(kbankAuth.orderId, kbankAuth.apiKey, targetAmount);
|
|
1238
1446
|
|
|
1239
1447
|
const qrRawCode =
|
|
1240
1448
|
qrResult?.paint_text ||
|
|
@@ -1245,8 +1453,16 @@ export class ThaiTicketMajor {
|
|
|
1245
1453
|
qrResult?.data?.raw_qr_code ||
|
|
1246
1454
|
(typeof qrResult === "string" ? qrResult : "");
|
|
1247
1455
|
|
|
1456
|
+
const qrAmount = parseThaiQRAmount(qrRawCode);
|
|
1457
|
+
const finalAmount =
|
|
1458
|
+
qrAmount ||
|
|
1459
|
+
(targetAmount && targetAmount !== "0" ? targetAmount : null) ||
|
|
1460
|
+
qrResult?.amount ||
|
|
1461
|
+
qrResult?.data?.amount ||
|
|
1462
|
+
"0";
|
|
1463
|
+
|
|
1248
1464
|
const displayQR = (customTitle?: string) => {
|
|
1249
|
-
const title = customTitle || `ThaiQR Payment (KBank) - ยอดชำระ: ${
|
|
1465
|
+
const title = customTitle || `ThaiQR Payment (KBank) - ยอดชำระ: ${finalAmount} บาท`;
|
|
1250
1466
|
ThaiTicketMajor.displayQRCode(qrRawCode, title);
|
|
1251
1467
|
};
|
|
1252
1468
|
|
|
@@ -1257,7 +1473,7 @@ export class ThaiTicketMajor {
|
|
|
1257
1473
|
return {
|
|
1258
1474
|
success: true,
|
|
1259
1475
|
orderId: kbankAuth.orderId,
|
|
1260
|
-
amount:
|
|
1476
|
+
amount: String(finalAmount),
|
|
1261
1477
|
qrRawCode,
|
|
1262
1478
|
qrData: qrResult,
|
|
1263
1479
|
displayQR,
|
|
@@ -1268,7 +1484,7 @@ export class ThaiTicketMajor {
|
|
|
1268
1484
|
venue: paymentAllData["venue"],
|
|
1269
1485
|
zone: targetZone.value,
|
|
1270
1486
|
ticketCount,
|
|
1271
|
-
totalAmount:
|
|
1487
|
+
totalAmount: String(finalAmount),
|
|
1272
1488
|
seats: summarySeats.length > 0 ? summarySeats : undefined,
|
|
1273
1489
|
},
|
|
1274
1490
|
rawPayload: {
|