playttm 0.0.1
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 +192 -0
- package/dist/lib.js +830 -0
- package/mine_backup/example.ts +60 -0
- package/mine_backup/index.ts +1209 -0
- package/package.json +29 -0
- package/src/lib.ts +1138 -0
- package/src/type.d.ts +303 -0
- package/tsconfig.json +108 -0
|
@@ -0,0 +1,1209 @@
|
|
|
1
|
+
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import * as cheerio from "cheerio";
|
|
4
|
+
//@ts-ignore
|
|
5
|
+
import fs from 'fs'
|
|
6
|
+
import { wrapper } from "axios-cookiejar-support";
|
|
7
|
+
import { CookieJar } from "tough-cookie";
|
|
8
|
+
|
|
9
|
+
const jar = new CookieJar();
|
|
10
|
+
|
|
11
|
+
const client = wrapper(
|
|
12
|
+
axios.create({
|
|
13
|
+
jar,
|
|
14
|
+
withCredentials: true,
|
|
15
|
+
})
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
let endpoint = `https://booking.thaiticketmajor.com/booking/3m`
|
|
19
|
+
|
|
20
|
+
// Convert Curl Select Node.js not python
|
|
21
|
+
export class PlayTTM {
|
|
22
|
+
|
|
23
|
+
headers_cookies: any
|
|
24
|
+
|
|
25
|
+
constructor(headers_cookies: any) {
|
|
26
|
+
this.headers_cookies = {
|
|
27
|
+
...headers_cookies,
|
|
28
|
+
'referer': 'https://booking.thaiticketmajor.com'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Response
|
|
34
|
+
* Step 1
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* [
|
|
38
|
+
* {
|
|
39
|
+
* url: "https://booking.thaiticketmajor.com/booking/3m/zones.php?query=954",
|
|
40
|
+
* time: "19:50",
|
|
41
|
+
* date: "วันอาทิตย์ที่ 11 ตุลาคม 2569"
|
|
42
|
+
* }
|
|
43
|
+
* {
|
|
44
|
+
* url: "https://booking.thaiticketmajor.com/booking/3m/zones.php?query=954",
|
|
45
|
+
* time: "19:50",
|
|
46
|
+
* date: "วันจันทร์ที่ 12 ตุลาคม 2569"
|
|
47
|
+
* }
|
|
48
|
+
* ]
|
|
49
|
+
*/
|
|
50
|
+
public getRounds = async (url: string): Promise<getRoundsResponse[]> => {
|
|
51
|
+
|
|
52
|
+
let html = await client.get(url, { headers: this.headers_cookies })
|
|
53
|
+
|
|
54
|
+
const $ = cheerio.load(html.data);
|
|
55
|
+
|
|
56
|
+
const result: getRoundsResponse[] = $("a[data-button]")
|
|
57
|
+
.map((_, el) => {
|
|
58
|
+
const link = $(el);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
url: link.attr("href") ?? "",
|
|
62
|
+
time: link.find(".item-show").text().trim(),
|
|
63
|
+
date: link.closest(".row").find(".date").text().trim(),
|
|
64
|
+
};
|
|
65
|
+
})
|
|
66
|
+
.get();
|
|
67
|
+
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Step 2
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* {"result":true,"message":"","query":954}
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
public verify_checkcondition = async (query: string): Promise<verify_checkconditionResponse> => {
|
|
79
|
+
const response = await client.post(
|
|
80
|
+
`${endpoint}/verify_checkcondition.php`,
|
|
81
|
+
new URLSearchParams({
|
|
82
|
+
'rdagree': '1',
|
|
83
|
+
'rdId': '',
|
|
84
|
+
'autopopup': '',
|
|
85
|
+
'query': query
|
|
86
|
+
}),
|
|
87
|
+
{ headers: this.headers_cookies }
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
return response.data
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Response
|
|
95
|
+
* Step 3
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* {
|
|
99
|
+
* k: 'b3be0e5932b8baa2c9dd9c33206c31b95f78be2f',
|
|
100
|
+
* tk: '2bf55fccc2bb727f39066dd042f0de0fdb7c1be7fdc477ce322b8cafb658abbb',
|
|
101
|
+
* query: '954',
|
|
102
|
+
* rounds: [
|
|
103
|
+
* { id: '81674', label: 'Sun 11 Oct 2026 19:50' },
|
|
104
|
+
* { id: '81697', label: 'Mon 12 Oct 2026 19:50' },
|
|
105
|
+
* { id: '81728', label: 'Tue 13 Oct 2026 19:50' }
|
|
106
|
+
* ]
|
|
107
|
+
* }
|
|
108
|
+
*/
|
|
109
|
+
public getZone = async (query: string): Promise<GetRoundsPerformResponse> => {
|
|
110
|
+
const response = await client.get(
|
|
111
|
+
`${endpoint}/zones.php?query=${query}`,
|
|
112
|
+
{ headers: this.headers_cookies }
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
//ต้องเปลี่ยน ไม่งั้นดึงข้อมูลไม่ได้
|
|
117
|
+
// referer = `${endpoint}/zones.php?query=${query}`
|
|
118
|
+
|
|
119
|
+
const $ = cheerio.load(response.data);
|
|
120
|
+
|
|
121
|
+
const data: any = {};
|
|
122
|
+
|
|
123
|
+
// Hidden inputs
|
|
124
|
+
$("#frm input[type='hidden']").each((_, el) => {
|
|
125
|
+
const name = $(el).attr("name");
|
|
126
|
+
const value = $(el).attr("value") ?? "";
|
|
127
|
+
|
|
128
|
+
if (name) {
|
|
129
|
+
data[name] = value;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Rounds
|
|
134
|
+
const rounds = $("#rdId option")
|
|
135
|
+
.filter((_, el) => !!$(el).attr("value"))
|
|
136
|
+
.map((_, el) => {
|
|
137
|
+
const option = $(el);
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
id: option.attr("value") ?? "",
|
|
141
|
+
label: option.text().trim(),
|
|
142
|
+
};
|
|
143
|
+
})
|
|
144
|
+
.get();
|
|
145
|
+
|
|
146
|
+
// รวม rounds เข้าไป
|
|
147
|
+
data.rounds = rounds;
|
|
148
|
+
|
|
149
|
+
return data;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
* Step 4
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* [
|
|
158
|
+
* { id: 'E1E', value: 'E1E', available: 0, page: 'fixed.php' },
|
|
159
|
+
* { id: 'E1F', value: 'E1F', available: 0, page: 'fixed.php' },
|
|
160
|
+
* { id: 'E1G', value: 'E1G', available: 0, page: 'fixed.php' },
|
|
161
|
+
* { id: 'E1H', value: 'E1H', available: 27, page: 'fixed.php' },
|
|
162
|
+
* { id: 'E1I', value: 'E1I', available: 0, page: 'festival.php' }, โซนยืน
|
|
163
|
+
* { id: 'E1J', value: 'E1J', available: 0, page: 'fixed.php' },
|
|
164
|
+
* ]
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
public getZoneAvail = async (round: string, tk: string, k: string, query: string): Promise<Zone[]> => {
|
|
168
|
+
|
|
169
|
+
console.log("ZONE AVAIL : ", `https://booking.thaiticketmajor.com/booking/3m/zones.php?rdId=${round}&k=${k}&tk=${tk}&query=${query}`)
|
|
170
|
+
|
|
171
|
+
const response = await client.get(
|
|
172
|
+
`${endpoint}/zonesavail.php?round=${round}&tk=${tk}`,
|
|
173
|
+
{
|
|
174
|
+
headers: {
|
|
175
|
+
...this.headers_cookies,
|
|
176
|
+
referer: `${endpoint}/zones.php?query=${query}`,
|
|
177
|
+
},
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
const $ = cheerio.load(response.data);
|
|
181
|
+
|
|
182
|
+
const zones = $(".table tbody tr")
|
|
183
|
+
.map((_, el) => {
|
|
184
|
+
const row = $(el);
|
|
185
|
+
|
|
186
|
+
const zoneId = row
|
|
187
|
+
.find("td:nth-child(1) a")
|
|
188
|
+
.attr("id") ?? "";
|
|
189
|
+
|
|
190
|
+
const onclick = row.attr("onclick") ?? "";
|
|
191
|
+
|
|
192
|
+
const match = onclick.match(
|
|
193
|
+
/gonextstep\('([^']+)','([^']+)'/
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const page = match?.[1] ?? "";
|
|
197
|
+
const zoneValue = match?.[2] ?? "";
|
|
198
|
+
|
|
199
|
+
const available = row.find("td:nth-child(2) a").text().trim() == "Available" ? 1 : Number.isNaN(Number(row.find("td:nth-child(2) a").text().trim())) ? 0 : Number(row.find("td:nth-child(2) a").text().trim())
|
|
200
|
+
|
|
201
|
+
console.log("AVAIL TEST : ", available)
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
id: zoneId,
|
|
205
|
+
value: zoneValue,
|
|
206
|
+
available,
|
|
207
|
+
page,
|
|
208
|
+
};
|
|
209
|
+
})
|
|
210
|
+
.get();
|
|
211
|
+
|
|
212
|
+
return zones
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
*
|
|
217
|
+
* Step 5
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* seats: [
|
|
221
|
+
* * {
|
|
222
|
+
* id: 'checkseat-AV-03',
|
|
223
|
+
* seat: 'AV-03-P*5335',
|
|
224
|
+
* seatk: 'abc62800881d8df5e782f4accd862376'
|
|
225
|
+
* },
|
|
226
|
+
* {
|
|
227
|
+
* id: 'checkseat-AV-02',
|
|
228
|
+
* seat: 'AV-02-P*5335',
|
|
229
|
+
* seatk: '79f89972db1e57bd3513440402487466'
|
|
230
|
+
* },
|
|
231
|
+
* {
|
|
232
|
+
* id: 'checkseat-AV-01',
|
|
233
|
+
* seat: 'AV-01-P*5335',
|
|
234
|
+
* seatk: '34ff19f7c31e7b61dfae3e6a0ebd4c82'
|
|
235
|
+
* }
|
|
236
|
+
* ],
|
|
237
|
+
*
|
|
238
|
+
*
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* form: {
|
|
242
|
+
* ehId: '954',
|
|
243
|
+
* curentdate: '2026,09,19,02,16',
|
|
244
|
+
* max_payment: '6',
|
|
245
|
+
* payment_cnt: '0',
|
|
246
|
+
* paytype: 'BOAI',
|
|
247
|
+
* performance: 'The Weeknd : After Hours Til Dawn Tour',
|
|
248
|
+
* pricelist: '',
|
|
249
|
+
* rdId: '81728',
|
|
250
|
+
* seatlist: '',
|
|
251
|
+
* showdate: '13 Oct 2026',
|
|
252
|
+
* showtime: '19:50',
|
|
253
|
+
* venue: 'Rajamangala National Stadium, Bangkok',
|
|
254
|
+
* zone: 'N2A',
|
|
255
|
+
* zoneDesc: 'N2A',
|
|
256
|
+
* travelChild1: '',
|
|
257
|
+
* travelChild2: '',
|
|
258
|
+
* enroll_val: '2',
|
|
259
|
+
* dval: '9343a84c9e564dda211a2c421551cbb2',
|
|
260
|
+
* companyid: '1627',
|
|
261
|
+
* ks: '',
|
|
262
|
+
* inclvat: ''
|
|
263
|
+
* }
|
|
264
|
+
*/
|
|
265
|
+
|
|
266
|
+
public getFixed = async (k: string, zone: string, round: string): Promise<FixedResponse> => {
|
|
267
|
+
const response = await client.get(
|
|
268
|
+
`${endpoint}/fixed.php?k=${k}&zone=${zone}&round=${round}`,
|
|
269
|
+
{ headers: this.headers_cookies }
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
// referer = `${endpoint}/fixed.php?k=${k}&zone=${zone}&round=${round}`
|
|
273
|
+
|
|
274
|
+
const $ = cheerio.load(response.data);
|
|
275
|
+
|
|
276
|
+
const seats = $("#tableseats .seatuncheck")
|
|
277
|
+
.map((_, el) => {
|
|
278
|
+
const seat = $(el);
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
id: seat.attr("id") ?? "",
|
|
282
|
+
seat: seat.attr("data-seat") ?? "",
|
|
283
|
+
seatk: seat.attr("data-seatk") ?? "",
|
|
284
|
+
};
|
|
285
|
+
})
|
|
286
|
+
.get();
|
|
287
|
+
|
|
288
|
+
let form: any = {}
|
|
289
|
+
|
|
290
|
+
$("#frmPayment input").each((_, el) => {
|
|
291
|
+
const name = $(el).attr("name");
|
|
292
|
+
|
|
293
|
+
if (name) {
|
|
294
|
+
form[name] = $(el).attr("value") ?? "";
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
seats,
|
|
300
|
+
form,
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
*
|
|
307
|
+
* Step 6
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* {"result":true,"status":0,"message":""}
|
|
311
|
+
*
|
|
312
|
+
*/
|
|
313
|
+
//zw = zone
|
|
314
|
+
//Remark You have to validate eqaul with the seats you choose if choose 2 seats that means you have to send 2 request
|
|
315
|
+
public validateSeatFix = async (
|
|
316
|
+
k: string,
|
|
317
|
+
zw: string,
|
|
318
|
+
payload: Record<string, any>,
|
|
319
|
+
chkSeats: any,
|
|
320
|
+
book_type: string = "fix"
|
|
321
|
+
): Promise<ValidateFixedResponse> => {
|
|
322
|
+
let lastResponse: any = null;
|
|
323
|
+
const accumulatedSeats: string[] = [];
|
|
324
|
+
|
|
325
|
+
// Loop through each seat to simulate sequential seat selection
|
|
326
|
+
for (let i = 0; i < chkSeats.length; i++) {
|
|
327
|
+
const currentSeat = chkSeats[i];
|
|
328
|
+
|
|
329
|
+
// Format value as SEAT*PRICE (e.g. UX-07-P*5335)
|
|
330
|
+
const priceVal = currentSeat.price || "5335";
|
|
331
|
+
const seatEntry = `${currentSeat.seat}*${priceVal}`;
|
|
332
|
+
|
|
333
|
+
// Insert newest selected seat at the front of chkSeats[] (index 0)
|
|
334
|
+
accumulatedSeats.unshift(seatEntry);
|
|
335
|
+
|
|
336
|
+
const formData = new URLSearchParams();
|
|
337
|
+
|
|
338
|
+
// 1. chkSeats[] must come first
|
|
339
|
+
for (const seat of accumulatedSeats) {
|
|
340
|
+
formData.append("chkSeats[]", seat);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// 2. Base payload
|
|
344
|
+
formData.append("ehId", payload.ehId ?? "");
|
|
345
|
+
formData.append("curentdate", payload.curentdate ?? "");
|
|
346
|
+
formData.append("max_payment", payload.max_payment ?? "6");
|
|
347
|
+
formData.append("payment_cnt", payload.payment_cnt ?? "0");
|
|
348
|
+
formData.append("paytype", payload.paytype ?? "BOAI");
|
|
349
|
+
formData.append("performance", payload.performance ?? "");
|
|
350
|
+
formData.append("pricelist", ""); // Curl uses empty string
|
|
351
|
+
formData.append("rdId", payload.rdId ?? "");
|
|
352
|
+
formData.append("seatlist", ""); // Curl uses empty string
|
|
353
|
+
formData.append("showdate", payload.showdate ?? "");
|
|
354
|
+
formData.append("showtime", payload.showtime ?? "");
|
|
355
|
+
formData.append("venue", payload.venue ?? "");
|
|
356
|
+
formData.append("zone", payload.zone ?? "");
|
|
357
|
+
formData.append("zoneDesc", payload.zoneDesc ?? "");
|
|
358
|
+
|
|
359
|
+
formData.append("travelChild1", "");
|
|
360
|
+
formData.append("travelChild2", "");
|
|
361
|
+
formData.append("travelChild2", "");
|
|
362
|
+
|
|
363
|
+
formData.append("enroll_val", payload.enroll_val ?? "");
|
|
364
|
+
formData.append("dval", payload.dval ?? "");
|
|
365
|
+
formData.append("companyid", payload.companyid ?? "");
|
|
366
|
+
formData.append("ks", payload.ks ?? "");
|
|
367
|
+
formData.append("inclvat", "");
|
|
368
|
+
|
|
369
|
+
// 3. Current seat being added
|
|
370
|
+
const seatParts = currentSeat.seat.split("-");
|
|
371
|
+
const row = seatParts[0]; // UX
|
|
372
|
+
const seatNo = seatParts[1]; // 07 or 08
|
|
373
|
+
|
|
374
|
+
formData.append("row", row);
|
|
375
|
+
formData.append("seat", seatNo);
|
|
376
|
+
formData.append("book_type", book_type);
|
|
377
|
+
|
|
378
|
+
// 4. Send request
|
|
379
|
+
const response = await client.post(
|
|
380
|
+
`${endpoint}/validateseat.php?k=${k}&zw=${zw}`,
|
|
381
|
+
formData.toString(),
|
|
382
|
+
{
|
|
383
|
+
headers: {
|
|
384
|
+
...this.headers_cookies,
|
|
385
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
386
|
+
"x-requested-with": "XMLHttpRequest",
|
|
387
|
+
"referer": `${endpoint}/fixed.php?k=${k}&zone=${payload.zone}&round=${payload.rdId}`
|
|
388
|
+
},
|
|
389
|
+
}
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
console.log(`#${i} Validate ${seatNo}`)
|
|
393
|
+
|
|
394
|
+
lastResponse = response.data;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return lastResponse;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Step 7
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
*
|
|
406
|
+
*/
|
|
407
|
+
public bookingSeats = async (
|
|
408
|
+
k: string,
|
|
409
|
+
payload: BookingForm,
|
|
410
|
+
seats: Seats[]
|
|
411
|
+
): Promise<BookingSeatsResponse> => {
|
|
412
|
+
let pricelistvalue = "";
|
|
413
|
+
let seatlistvalue = "";
|
|
414
|
+
let seatklistvalue = "";
|
|
415
|
+
|
|
416
|
+
seats.forEach((s) => {
|
|
417
|
+
const parts = s.seat.split("*");
|
|
418
|
+
pricelistvalue += `${parts[1] || ""},`;
|
|
419
|
+
seatlistvalue += `${parts[0]},`;
|
|
420
|
+
seatklistvalue += `${s.seatk},`;
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
// คัดลอกและเรียง Key ให้ตรงตาม curl ของจริงเป๊ะๆ
|
|
424
|
+
const bodyParams = new URLSearchParams();
|
|
425
|
+
|
|
426
|
+
bodyParams.set("ehId", payload.ehId || "");
|
|
427
|
+
bodyParams.set("curentdate", payload.curentdate || "");
|
|
428
|
+
bodyParams.set("max_payment", payload.max_payment || "6");
|
|
429
|
+
bodyParams.set("payment_cnt", payload.payment_cnt || "0");
|
|
430
|
+
bodyParams.set("paytype", payload.paytype || "BOAI");
|
|
431
|
+
bodyParams.set("performance", payload.performance || "");
|
|
432
|
+
bodyParams.set("pricelist", pricelistvalue);
|
|
433
|
+
bodyParams.set("rdId", payload.rdId || "");
|
|
434
|
+
bodyParams.set("seatlist", seatlistvalue);
|
|
435
|
+
bodyParams.set("showdate", payload.showdate || "");
|
|
436
|
+
bodyParams.set("showtime", payload.showtime || "");
|
|
437
|
+
bodyParams.set("venue", payload.venue || "");
|
|
438
|
+
bodyParams.set("zone", payload.zone || "");
|
|
439
|
+
bodyParams.set("zoneDesc", payload.zoneDesc || "");
|
|
440
|
+
bodyParams.set("travelChild1", "");
|
|
441
|
+
bodyParams.set("travelChild2", "");
|
|
442
|
+
bodyParams.append("travelChild2", ""); // ใส่ซ้ำ 2 ครั้งตาม curl
|
|
443
|
+
bodyParams.set("enroll_val", payload.enroll_val); // จำนวนบัตรต้องตรงกับจำนวนที่นั่งใน array
|
|
444
|
+
bodyParams.set("dval", payload.dval || "");
|
|
445
|
+
bodyParams.set("companyid", payload.companyid || "");
|
|
446
|
+
bodyParams.set("ks", "");
|
|
447
|
+
bodyParams.set("inclvat", "");
|
|
448
|
+
bodyParams.set("seatklist", seatklistvalue);
|
|
449
|
+
|
|
450
|
+
const response = await client.post(
|
|
451
|
+
`${endpoint}/bookingseats.php?k=${k}`,
|
|
452
|
+
bodyParams.toString(),
|
|
453
|
+
{
|
|
454
|
+
headers: {
|
|
455
|
+
...this.headers_cookies,
|
|
456
|
+
"accept": "application/json, text/javascript, */*; q=0.01",
|
|
457
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
458
|
+
"x-requested-with": "XMLHttpRequest",
|
|
459
|
+
"referer": `https://booking.thaiticketmajor.com/booking/3m/fixed.php?k=${k}&zone=${payload.zone}&round=${payload.rdId}`,
|
|
460
|
+
"origin": "https://booking.thaiticketmajor.com",
|
|
461
|
+
},
|
|
462
|
+
}
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
data: response.data,
|
|
467
|
+
nextPayload: bodyParams
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Optional Step Watch enroll_val
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
*
|
|
476
|
+
*/
|
|
477
|
+
|
|
478
|
+
public enroll = async (k: string, zone: string, rdId: string, payload: any): Promise<EnrollResponse> => {
|
|
479
|
+
const response = await client.post(`${endpoint}/enroll.php?k=${k}&zone=${zone}&round=${rdId}`,
|
|
480
|
+
payload,
|
|
481
|
+
{
|
|
482
|
+
headers: {
|
|
483
|
+
...this.headers_cookies,
|
|
484
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/fixed.php?k=${k}&zone=${zone}&round=${rdId}`
|
|
485
|
+
},
|
|
486
|
+
}
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
const allowedFields = [
|
|
490
|
+
"txt_fullname[]",
|
|
491
|
+
"txt_email[]",
|
|
492
|
+
"txt_firstname[]",
|
|
493
|
+
"txt_lastname[]",
|
|
494
|
+
"txt_phone[]",
|
|
495
|
+
"sel_options[]",
|
|
496
|
+
"zones[]",
|
|
497
|
+
"ehId",
|
|
498
|
+
"enroll_val",
|
|
499
|
+
"canDuplicate",
|
|
500
|
+
"hasPolicy",
|
|
501
|
+
"isSplitName",
|
|
502
|
+
"festival",
|
|
503
|
+
"debit",
|
|
504
|
+
"zone",
|
|
505
|
+
"zoneDesc",
|
|
506
|
+
"rdId",
|
|
507
|
+
"price",
|
|
508
|
+
"seatklist",
|
|
509
|
+
"mpur",
|
|
510
|
+
"paytype",
|
|
511
|
+
"companyid",
|
|
512
|
+
"rounddate",
|
|
513
|
+
"book_cnt",
|
|
514
|
+
"isThaiOnly",
|
|
515
|
+
"isEngOnly",
|
|
516
|
+
"hasSelect",
|
|
517
|
+
"showEmailFlag",
|
|
518
|
+
"showFullnameFlag",
|
|
519
|
+
"showSplitNameFlag",
|
|
520
|
+
"hasCheckbox",
|
|
521
|
+
"hasPhone",
|
|
522
|
+
"enroll_cnt",
|
|
523
|
+
];
|
|
524
|
+
|
|
525
|
+
const $ = cheerio.load(response.data);
|
|
526
|
+
|
|
527
|
+
const formData: any = {};
|
|
528
|
+
|
|
529
|
+
$("#form input, #form select").each((_, el) => {
|
|
530
|
+
const name = $(el).attr("name");
|
|
531
|
+
|
|
532
|
+
if (!name || !allowedFields.includes(name)) return;
|
|
533
|
+
|
|
534
|
+
formData[name] =
|
|
535
|
+
$(el).attr("value") ??
|
|
536
|
+
$(el).find("option:selected").attr("value") ??
|
|
537
|
+
"";
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
return formData
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
*
|
|
547
|
+
* Optional Step Watch enroll_val
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* { result: true, message: '', query: 954 }
|
|
551
|
+
*
|
|
552
|
+
*/
|
|
553
|
+
public enroll_process = async (
|
|
554
|
+
k: string,
|
|
555
|
+
payload: Record<string, any>,
|
|
556
|
+
users: any[]
|
|
557
|
+
) => {
|
|
558
|
+
const formData = new URLSearchParams();
|
|
559
|
+
|
|
560
|
+
// 1. Append the repeated attendee field blocks at the top
|
|
561
|
+
for (const user of users) {
|
|
562
|
+
const isString = typeof user === "string";
|
|
563
|
+
const fullname = isString ? user : user.fullname;
|
|
564
|
+
const email = isString ? "" : (user.email ?? "");
|
|
565
|
+
const firstname = isString ? "" : (user.firstname ?? "");
|
|
566
|
+
const lastname = isString ? "" : (user.lastname ?? "");
|
|
567
|
+
const phone = isString ? "" : (user.phone ?? "");
|
|
568
|
+
const options = isString ? "" : (user.options ?? "");
|
|
569
|
+
|
|
570
|
+
formData.append("txt_fullname[]", fullname);
|
|
571
|
+
formData.append("txt_email[]", email);
|
|
572
|
+
formData.append("txt_firstname[]", firstname);
|
|
573
|
+
formData.append("txt_lastname[]", lastname);
|
|
574
|
+
formData.append("txt_phone[]", phone);
|
|
575
|
+
formData.append("sel_options[]", options);
|
|
576
|
+
formData.append("zones[]", payload.zone ?? "");
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// 2. Keys that were already added as repeated arrays (exclude them from base payload)
|
|
580
|
+
const excludedKeys = new Set([
|
|
581
|
+
"txt_fullname[]",
|
|
582
|
+
"txt_email[]",
|
|
583
|
+
"txt_firstname[]",
|
|
584
|
+
"txt_lastname[]",
|
|
585
|
+
"txt_phone[]",
|
|
586
|
+
"sel_options[]",
|
|
587
|
+
"zones[]",
|
|
588
|
+
]);
|
|
589
|
+
|
|
590
|
+
// 3. Append remaining metadata keys from the payload
|
|
591
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
592
|
+
if (!excludedKeys.has(key)) {
|
|
593
|
+
formData.append(key, value !== undefined && value !== null ? String(value) : "");
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// console.log("BEFORE SEND ENROLL PROCESS : ", formData)
|
|
598
|
+
|
|
599
|
+
const response = await client.post(
|
|
600
|
+
`${endpoint}/enroll_process.php?k=${k}`,
|
|
601
|
+
formData.toString(),
|
|
602
|
+
{
|
|
603
|
+
headers: {
|
|
604
|
+
...this.headers_cookies,
|
|
605
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
606
|
+
"x-requested-with": "XMLHttpRequest",
|
|
607
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/enroll.php?k=${k}&zone=${payload.zone}&round=${payload.rdId}`,
|
|
608
|
+
},
|
|
609
|
+
}
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
return {
|
|
613
|
+
data: response.data,
|
|
614
|
+
nextPayload: formData
|
|
615
|
+
};
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
public getPaymentAll = async (
|
|
619
|
+
k: string,
|
|
620
|
+
formData: any,
|
|
621
|
+
zone: string,
|
|
622
|
+
rdId: string,
|
|
623
|
+
msDelay: number
|
|
624
|
+
): Promise<PaymentAllResponse> => {
|
|
625
|
+
const response = await client.post(
|
|
626
|
+
`${endpoint}/paymentall.php?k=${k}`,
|
|
627
|
+
formData.toString(),
|
|
628
|
+
{
|
|
629
|
+
headers: {
|
|
630
|
+
...this.headers_cookies,
|
|
631
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
632
|
+
"x-requested-with": "XMLHttpRequest",
|
|
633
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/enroll.php?k=${k}&zone=${zone}&round=${rdId}`,
|
|
634
|
+
},
|
|
635
|
+
}
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
const $ = cheerio.load(response.data);
|
|
639
|
+
const hiddenInputs: any = {};
|
|
640
|
+
|
|
641
|
+
// 1. ดึง input ทั้งหมดจาก #frm-confirm (ทั้ง name และ id)
|
|
642
|
+
$("#frm-confirm input").each((_, el) => {
|
|
643
|
+
const key = $(el).attr("name") ?? $(el).attr("id");
|
|
644
|
+
if (key) {
|
|
645
|
+
hiddenInputs[key] = $(el).val()?.toString() ?? "";
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// 2. สกัดข้อมูลที่อยู่จัดส่งจาก #frm-address
|
|
650
|
+
const addressForm = $("#frm-address");
|
|
651
|
+
if (addressForm.length > 0) {
|
|
652
|
+
const fname = addressForm.find("input[name='c_fname_m']").val()?.toString() ?? "";
|
|
653
|
+
const lname = addressForm.find("input[name='c_lname_m']").val()?.toString() ?? "";
|
|
654
|
+
const address = addressForm.find("textarea[name='c_address_m']").val()?.toString() ?? "";
|
|
655
|
+
|
|
656
|
+
// ดึงค่า value จาก dropdown option ที่ถูก selected
|
|
657
|
+
const ctId = addressForm.find("select[name='c_ctCode'] option:selected").val()?.toString() ?? "";
|
|
658
|
+
const pvId = addressForm.find("select[name='c_pvId'] option:selected").val()?.toString() ?? "";
|
|
659
|
+
const amId = addressForm.find("select[name='c_amId'] option:selected").val()?.toString() ?? "";
|
|
660
|
+
|
|
661
|
+
const zipcode = addressForm.find("input[name='c_PostCode']").val()?.toString() ?? "";
|
|
662
|
+
|
|
663
|
+
// จัดการเบอร์โทรศัพท์ (ถ้าติดรหัสประเทศ 66 ข้างหน้า ให้ตัดออกเพื่อให้ตรงกับ format 95 697 5152)
|
|
664
|
+
let rawPhone = addressForm.find("input[name='c_ContactRecipient']").val()?.toString() ?? "";
|
|
665
|
+
if (rawPhone.startsWith("66")) {
|
|
666
|
+
rawPhone = rawPhone.slice(2);
|
|
667
|
+
}
|
|
668
|
+
// จัด format เว้นวรรคตามตัวอย่าง '95 697 5152' ถ้าต้องการ หรือเก็บเป็นตัวเลขล้วน
|
|
669
|
+
const phoneArea = addressForm.find("input[name='telephoneArea']").val()?.toString() ?? "66";
|
|
670
|
+
|
|
671
|
+
// 3. Map เข้าฟิลด์ adr_* สำหรับ payload ชำระเงิน
|
|
672
|
+
hiddenInputs["adr_fname"] = fname;
|
|
673
|
+
hiddenInputs["adr_lname"] = lname;
|
|
674
|
+
hiddenInputs["adr_address"] = address;
|
|
675
|
+
hiddenInputs["adr_ctId"] = ctId;
|
|
676
|
+
hiddenInputs["adr_pvId"] = pvId;
|
|
677
|
+
hiddenInputs["adr_amId"] = amId;
|
|
678
|
+
hiddenInputs["adr_zipcode"] = zipcode;
|
|
679
|
+
hiddenInputs["adr_mobile"] = rawPhone.replace(/(\d{2})(\d{3})(\d{4})/, "$1 $2 $3");
|
|
680
|
+
hiddenInputs["adr_mobilearea"] = phoneArea;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
console.log(`Waiting PayCfmall Page loading... ${msDelay} ms`)
|
|
684
|
+
|
|
685
|
+
await new Promise(resolve => setTimeout(resolve, msDelay));
|
|
686
|
+
|
|
687
|
+
// console.log("getPaymentALL : ", hiddenInputs);
|
|
688
|
+
return hiddenInputs;
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* @example response
|
|
695
|
+
* {
|
|
696
|
+
* ehId: '954',
|
|
697
|
+
* ordernumber: '27016032010849868',
|
|
698
|
+
* amount: '11052',
|
|
699
|
+
* tk: 'f6fe8889391291e5a9a7864ffa9d7f4ba8ba3dae4982573053043ccadb493661'
|
|
700
|
+
* }
|
|
701
|
+
*/
|
|
702
|
+
|
|
703
|
+
public getPayCfmall = async (
|
|
704
|
+
k: string,
|
|
705
|
+
payload: PaymentAllResponse,
|
|
706
|
+
deliver: string = "1",
|
|
707
|
+
paytype: string = "KBQR"
|
|
708
|
+
): Promise<PayCfMallResponse> => {
|
|
709
|
+
// 1. ดึงตัวเลขจาก payload มาคำนวณค่าธรรมเนียมและยอดรวม
|
|
710
|
+
const cntTicket = parseInt(payload.cal_cntticket || "0", 10);
|
|
711
|
+
const amountCode = parseFloat(payload.amountcode || "0");
|
|
712
|
+
const deliverFee = parseFloat(payload.cal_deliverfee || payload.val_deliverfee || "80");
|
|
713
|
+
const addCharge = parseFloat(payload.cal_addcharge || "0");
|
|
714
|
+
const discount = parseFloat(payload.cal_discount || "0");
|
|
715
|
+
const voucher = parseFloat(payload.cal_voucher || "0");
|
|
716
|
+
|
|
717
|
+
// ค่าบริการออกบัตร (Ticket Fee = 191 THB ต่อใบ)
|
|
718
|
+
const ticketFee = cntTicket * 191;
|
|
719
|
+
|
|
720
|
+
// ยอดรวมสุทธิ
|
|
721
|
+
const totalAmount = amountCode + deliverFee + ticketFee + addCharge - discount - voucher;
|
|
722
|
+
|
|
723
|
+
// 2. Clone payload พร้อม override ค่าที่ต้องคำนวณและตั้งค่า
|
|
724
|
+
const computedPayload: Record<string, string> = {
|
|
725
|
+
...payload,
|
|
726
|
+
paytype: paytype,
|
|
727
|
+
deliver: deliver,
|
|
728
|
+
cal_ticketfee: ticketFee.toString(),
|
|
729
|
+
cal_totalamount: Math.round(totalAmount).toString(),
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
// 3. ประกอบ URLSearchParams ตามลำดับ (ตัด 'check-protect' ออก)
|
|
733
|
+
const formData = new URLSearchParams();
|
|
734
|
+
for (const [key, value] of Object.entries(computedPayload)) {
|
|
735
|
+
if (key !== "check-protect") {
|
|
736
|
+
formData.append(key, value !== undefined && value !== null ? String(value) : "");
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// 4. ส่ง Request
|
|
741
|
+
const response = await client.post(
|
|
742
|
+
`${endpoint}/paycfmall.php?k=${k}`,
|
|
743
|
+
formData.toString(),
|
|
744
|
+
{
|
|
745
|
+
headers: {
|
|
746
|
+
...this.headers_cookies,
|
|
747
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
748
|
+
"x-requested-with": "XMLHttpRequest",
|
|
749
|
+
referer: `${endpoint}/paymentall.php?k=${k}`,
|
|
750
|
+
},
|
|
751
|
+
}
|
|
752
|
+
);
|
|
753
|
+
|
|
754
|
+
const $ = cheerio.load(response.data);
|
|
755
|
+
|
|
756
|
+
// console.log(response.data)
|
|
757
|
+
|
|
758
|
+
const nextJsonData: any = {};
|
|
759
|
+
|
|
760
|
+
$("#payallfrm input[type='hidden']").each((_, el) => {
|
|
761
|
+
const name = $(el).attr("name");
|
|
762
|
+
const value = $(el).attr("value") ?? "";
|
|
763
|
+
|
|
764
|
+
if (name) {
|
|
765
|
+
nextJsonData[name] = value;
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
return nextJsonData;
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
*
|
|
775
|
+
* @param k
|
|
776
|
+
* @param payload_json
|
|
777
|
+
* @returns
|
|
778
|
+
*
|
|
779
|
+
*/
|
|
780
|
+
|
|
781
|
+
public orderenc_kbankqr = async (k: string, payload_json: any): Promise<OrderEncResponse> => {
|
|
782
|
+
|
|
783
|
+
const formData = new URLSearchParams(payload_json);
|
|
784
|
+
|
|
785
|
+
const response = await client.post(
|
|
786
|
+
`${endpoint}/orderenc_kbankqr.php`,
|
|
787
|
+
formData.toString(),
|
|
788
|
+
{
|
|
789
|
+
headers: {
|
|
790
|
+
...this.headers_cookies,
|
|
791
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
792
|
+
"x-requested-with": "XMLHttpRequest",
|
|
793
|
+
referer: `${endpoint}/paycfmall.php?k=${k}`,
|
|
794
|
+
},
|
|
795
|
+
}
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
const $ = cheerio.load(response.data);
|
|
799
|
+
|
|
800
|
+
const kbankqrData: any = {};
|
|
801
|
+
|
|
802
|
+
$("#kbankqr input[type='hidden']").each((_, el) => {
|
|
803
|
+
const name = $(el).attr("name");
|
|
804
|
+
const value = $(el).attr("value") ?? "";
|
|
805
|
+
|
|
806
|
+
if (name) {
|
|
807
|
+
kbankqrData[name] = value;
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
return kbankqrData
|
|
812
|
+
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
public getkbankqr = async (payload_json: any): Promise<GetKBankQrResponse> => {
|
|
816
|
+
|
|
817
|
+
let formData = new URLSearchParams(payload_json)
|
|
818
|
+
|
|
819
|
+
const response = await client.post(
|
|
820
|
+
`${endpoint}/getkbankqr.php`,
|
|
821
|
+
formData.toString(),
|
|
822
|
+
{
|
|
823
|
+
headers: {
|
|
824
|
+
...this.headers_cookies,
|
|
825
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
826
|
+
"x-requested-with": "XMLHttpRequest",
|
|
827
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/orderenc_kbankqr.php`,
|
|
828
|
+
},
|
|
829
|
+
}
|
|
830
|
+
);
|
|
831
|
+
|
|
832
|
+
return response.data
|
|
833
|
+
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
public payment_kbankqr = async (orderenc_json: any, kbank_payload_json: any): Promise<PaymentKbankQrResponse> => {
|
|
837
|
+
|
|
838
|
+
let prepare_payload = {
|
|
839
|
+
...orderenc_json,
|
|
840
|
+
'reasoncode': kbank_payload_json.reasoncode,
|
|
841
|
+
'eventname': kbank_payload_json.eventname,
|
|
842
|
+
'rounddetail': kbank_payload_json.rounddetail,
|
|
843
|
+
'totalamount': kbank_payload_json.totalamount,
|
|
844
|
+
'orderstatus': kbank_payload_json.orderstatus,
|
|
845
|
+
'kbankqr_txExpiry': kbank_payload_json.kbankqr_txExpiry
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
let formData = new URLSearchParams(prepare_payload)
|
|
849
|
+
|
|
850
|
+
const response = await client.post(
|
|
851
|
+
`${endpoint}/payment_kbankqr.php`,
|
|
852
|
+
formData.toString(),
|
|
853
|
+
{
|
|
854
|
+
headers: {
|
|
855
|
+
...this.headers_cookies,
|
|
856
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
857
|
+
"x-requested-with": "XMLHttpRequest",
|
|
858
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/orderenc_kbankqr.php`,
|
|
859
|
+
},
|
|
860
|
+
}
|
|
861
|
+
);
|
|
862
|
+
|
|
863
|
+
const $ = cheerio.load(response.data);
|
|
864
|
+
|
|
865
|
+
const script = $("#kbankpost script[data-order-id]");
|
|
866
|
+
|
|
867
|
+
const orderId = script.attr("data-order-id") ?? "";
|
|
868
|
+
const apiKey = script.attr("data-apikey") ?? "";
|
|
869
|
+
|
|
870
|
+
return {
|
|
871
|
+
orderId,
|
|
872
|
+
apiKey,
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
public QR = async (order_id: string, api_key: string, orderenc_json: any): Promise<QRResponse> => {
|
|
877
|
+
|
|
878
|
+
let prepayload = {
|
|
879
|
+
amount: orderenc_json.amount,
|
|
880
|
+
currency: 'THB', //Don't hard code Next,
|
|
881
|
+
metadata: [],
|
|
882
|
+
order_id: order_id,
|
|
883
|
+
sof: "ThaiQR" //Don't hard code Next,
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
const response = await client.post(
|
|
887
|
+
`https://kpaymentgateway-services.kasikornbank.com/qr/v2/qr`,
|
|
888
|
+
prepayload,
|
|
889
|
+
{
|
|
890
|
+
headers: {
|
|
891
|
+
...this.headers_cookies,
|
|
892
|
+
referer: `https://kpaymentgateway.kasikornbank.com/`,
|
|
893
|
+
"x-api-key": api_key
|
|
894
|
+
},
|
|
895
|
+
}
|
|
896
|
+
);
|
|
897
|
+
|
|
898
|
+
return response.data
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
//Festival Way
|
|
903
|
+
|
|
904
|
+
public Festival = async (k: string, tk: string, query: string, zone: string, round: string): Promise<FestivalResponse> => {
|
|
905
|
+
|
|
906
|
+
const response = await client.get(
|
|
907
|
+
`${endpoint}/festival.php?k=${k}&zone=${zone}&round=${round}`,
|
|
908
|
+
{
|
|
909
|
+
headers: {
|
|
910
|
+
...this.headers_cookies,
|
|
911
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
912
|
+
"x-requested-with": "XMLHttpRequest",
|
|
913
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/zones.php?rdId=${round}&k=${k}&tk=${tk}&query=${query}`,
|
|
914
|
+
},
|
|
915
|
+
}
|
|
916
|
+
);
|
|
917
|
+
|
|
918
|
+
const $ = cheerio.load(response.data);
|
|
919
|
+
|
|
920
|
+
const formData: any = {};
|
|
921
|
+
|
|
922
|
+
$("#frm input").each((_, el) => {
|
|
923
|
+
const name = $(el).attr("name");
|
|
924
|
+
|
|
925
|
+
if (name) {
|
|
926
|
+
formData[name] = $(el).attr("value") ?? "";
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
return formData
|
|
931
|
+
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
public validateSeatFestival = async (k: string, payload_json: any, book_cnt: string) => {
|
|
935
|
+
|
|
936
|
+
let prepare_payload = {
|
|
937
|
+
...payload_json,
|
|
938
|
+
'book_cnt': book_cnt,
|
|
939
|
+
'book_type': 'fest'
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
let formData = new URLSearchParams(prepare_payload)
|
|
943
|
+
|
|
944
|
+
console.log("TEST JA : ", formData)
|
|
945
|
+
|
|
946
|
+
const response = await client.post(
|
|
947
|
+
`${endpoint}/validateseat.php?k=${k}&zw=${payload_json.zone}`,
|
|
948
|
+
formData.toString(),
|
|
949
|
+
{
|
|
950
|
+
headers: {
|
|
951
|
+
...this.headers_cookies,
|
|
952
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
953
|
+
"x-requested-with": "XMLHttpRequest",
|
|
954
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/festival.php?k=${k}&zone=${payload_json.zone}&round=${payload_json.rdId}`,
|
|
955
|
+
},
|
|
956
|
+
}
|
|
957
|
+
);
|
|
958
|
+
|
|
959
|
+
return response.data
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
public BookingFestival = async (k: string, payload: any, book_cnt: string) => {
|
|
963
|
+
|
|
964
|
+
let prepayload = {
|
|
965
|
+
...payload,
|
|
966
|
+
'book_cnt': book_cnt
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
let formData = new URLSearchParams(prepayload)
|
|
970
|
+
|
|
971
|
+
const response = await client.post(
|
|
972
|
+
`${endpoint}/bookingfestival.php?k=${k}`,
|
|
973
|
+
formData.toString(),
|
|
974
|
+
{
|
|
975
|
+
headers: {
|
|
976
|
+
...this.headers_cookies,
|
|
977
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
978
|
+
"x-requested-with": "XMLHttpRequest",
|
|
979
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/festival.php?k=${k}&zone=${payload.zone}&round=${payload.rdId}`,
|
|
980
|
+
},
|
|
981
|
+
}
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
return response.data
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
public enrollFestival = async (k: string, payload: any, book_cnt: string) => {
|
|
988
|
+
|
|
989
|
+
let prepayload = {
|
|
990
|
+
...payload,
|
|
991
|
+
'book_cnt': book_cnt
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
let formData = new URLSearchParams(prepayload)
|
|
995
|
+
|
|
996
|
+
const response = await client.post(
|
|
997
|
+
`${endpoint}/enroll.php?k=${k}`,
|
|
998
|
+
formData.toString(),
|
|
999
|
+
{
|
|
1000
|
+
headers: {
|
|
1001
|
+
...this.headers_cookies,
|
|
1002
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
1003
|
+
"x-requested-with": "XMLHttpRequest",
|
|
1004
|
+
referer: `https://booking.thaiticketmajor.com/booking/3m/festival.php?k=${k}&zone=${payload.zone}&round=${payload.rdId}`,
|
|
1005
|
+
},
|
|
1006
|
+
}
|
|
1007
|
+
);
|
|
1008
|
+
|
|
1009
|
+
return response.data
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
// การที่เราไม่ได้ zone เพราะเราไม่เปลี่ยน referer ที่ headers ให้พึงจารณาอันอื่นด้วย
|
|
1018
|
+
// 418 คนยิง serverr มันเยอะมันเลยให้รอแปป
|
|
1019
|
+
|
|
1020
|
+
let my_headers_cookies = {
|
|
1021
|
+
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
|
1022
|
+
'accept-language': 'en',
|
|
1023
|
+
'cache-control': 'no-cache',
|
|
1024
|
+
'pragma': 'no-cache',
|
|
1025
|
+
'priority': 'u=0, i',
|
|
1026
|
+
'referer': 'https://www.thaiticketmajor.com/all-event/',
|
|
1027
|
+
'sec-ch-ua': '"Google Chrome";v="153", "Not_A Brand";v="8", "Chromium";v="153"',
|
|
1028
|
+
'sec-ch-ua-mobile': '?0',
|
|
1029
|
+
'sec-ch-ua-platform': '"macOS"',
|
|
1030
|
+
'sec-fetch-dest': 'document',
|
|
1031
|
+
'sec-fetch-mode': 'navigate',
|
|
1032
|
+
'sec-fetch-site': 'same-origin',
|
|
1033
|
+
'sec-fetch-user': '?1',
|
|
1034
|
+
'upgrade-insecure-requests': '1',
|
|
1035
|
+
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36',
|
|
1036
|
+
'cookie': '__lt__cid=49c63195-5801-44a8-b1e1-b8e8cffe5d88; _tt_enable_cookie=1; _fbp=fb.1.1781174050563.711676052978077861.AQYAAQIB; _ga=GA1.1.599117093.1781174051; _gcl_au=1.1.157871639.1788961562.-.-.1789480295.1055093031.1789573314.1789573314; _ttp=01M0DEAF6B6EP986BDT9E6AZN6_.tt.1; ttkname=%E0%B8%A3%E0%B8%B1%E0%B8%90%E0%B8%99%E0%B8%99%E0%B8%97%E0%B9%8C+%E0%B8%9A%E0%B8%B8%E0%B8%8D%E0%B8%A1%E0%B8%B2%E0%B8%95%E0%B8%B2; tixid=play21947%40gmail.com; tixu=9343a84c9e564dda211a2c421551cbb2; __la=th; _twpid=tw.1789882087962.364890005864940170; ttmfw=7FAF39CA6BD3E694A4EBE7949C719; __PrivacyPolicy=1; _clck=xi2wac%5E2%5Eg9n%5E0%5E2353; HWWAFSESID=06a7f73fc89cbee20c; HWWAFSESTIME=1789973220265; PHPSESSID=db578307a0d52d2efe1b08b5f899a8c5; cdnname=%E0%B8%A3%E0%B8%B1%E0%B8%90%E0%B8%99%E0%B8%99%E0%B8%97%E0%B9%8C+%E0%B8%9A%E0%B8%B8%E0%B8%8D%E0%B8%A1%E0%B8%B2%E0%B8%95%E0%B8%B2; ttkemail=play21947%40gmail.com; _abck=D02884B6241B15884076C3E83B0FAA86~0~YAAQdhGkboPAvpGgAQAAQYmlwxBdca6zpViMmyhsjcciMHER7JC2fwjndIM4xrL3Qcp8gQ6CRSbIQHOqKMHvMXojwsYvF2R4Cix6NuwIl0TkhiYmrvF6INCYZfBUMRaiFfQEw/GdnkrFw6CfiZpUBFxG5FjaG151p5tJ+tJ9ILaiBwK2jIYMcxvGpej5fjCW6AWmRpX69Mu7IM6abo5MnEXm6xrlbJIpKhcQj2gMaDJgV/INcFvpSPcf89U/GUgg9vyufhgDAspzIyxZsvo1BZyEdagq8NB7N13lqvMibsC3ZXRaSUpXC2N4vcGhn2hLVWKGGt+payQZbuITaB7GwPX5thbfI7kScVZhMS4tTOpQyyhDNMNSfbRvL6ukrgK3I2ZmESwpPzjSeieyWYO/KXff9zCUpJ8Hb5lxxnGgsuRkgRaDHShCX55LhFkK0lInsmRVDlOSB+wt9m+o30/QgIWbyT32iXbGNFNSXFB3oz3bUqICZKsm/4gDh5KXcS0XYLIFVeHcoYGKY9jVNt64fUkeptCdzYaKacNqYUvaCJlZndJ5nekJpXk64LTJGpeTp3mZ/9Y2d0OrhTPxkAWxE1XekxM2l+1IBqLWQ0AtvaZNQG2yEURAInyPYmgr4Js0laEWzbPnTB6TbD+CS+Ky1fP4oW771RfcSRoW1iOrD7niAtDk6XJl9cGDAeMpMuxq+QmQwrxNu9XbAuOi9xGopqVvWU0KqmzYcg0N/Pm42alML9tSw5rUMmZqAqi5r/cGHyYUjrrKob4wQXZ6Nc7qj3ihxyVaBEVUFUhfOiDk1pfqm5mWhG5zOMMRC7GY9F4XDvR9qqlUh3mGVlhKDwCPmPofZuFX3CZwDIRQ8jZgIZlG1C+tFQhe7UW924gnoo7t6hROz3pH4hIi84t9Xc6RUHorDY4xCDSVCiwt7H7WZ6PDVQ0Ux7HV9t1FlKiTZoCqgUUzInysYcEZll5hvZqunnzQ/w4yzpqdg5Gt~-1~-1~-1~AAQAAAAG%2f%2f%2f%2f%2f23nAjEK47lsD7yjkP2d9OS8%2f85mZpQRG96ovYkkmAIUxP0cx84t5g3IP28wTkYQuKLHQ5Tw237oOJ7nJUeRPmemaqqvg3+8KH6+3we+jwBogPVEc49kjaQ6l1%2fCi%2fh6vPcNvIrcYbA4QktqkNaaaTdo2qVLVEGHpyhOgWdEaA%3d%3d~-1; bm_sz=5ECA00B535387B6C022507F802FA7670~YAAQdhGkbovAvpGgAQAAqomlwwELcASTBZN49Ty8fQ1X3RvoHTJZZ3VTVgvj3ALJvJwxDcesuQTwxaXZlVN5ZfyjitfRc5UH4SaIgmD+21Q3qFhS0wmnWvcSckqsCmUbqgGYl9ZqR24EqZU6Gv9mVXz1f5MC6imxItRBkYs/a+WPOEjIY8e8TlYpqeyQaqCNHwqV1+U6Kahu4nYGRPRH+ToQabpl1WdtNjauJcNSNNfhpnkFehUM9NpRQfDVLVolRlQlg4Ne70V21yfVtWFLQDonNRgxvilO1lZd5BdDthtS3X4BZzoOUuJE95VZ63kC/DRh1SK532Xbhsn6XwWxXC+PT4IU0Ezl+rV4iZtX5lIR+WsbowMeWO1PK75w5q6E5AgDklhpSIngGNFNhAIisQQZLrxH6YdsoiEc9NjO7Jm0+YuARM9+eurkQyjTEG4+QhRVmiZMXFcg+F6Ns8oygE1Yn5k=~4403252~3621189; ttm_suggestion=1; bm_mi=43C783C2B5DE6317A17EE483DE6D0468~YAAQXKwwF0wbXIygAQAAij8OxAHGgePK0ZpanpcXTRmLowG7zNqltTZUHQAzk4snXfLlZq/ZRcf0WmEt6RokD334bj9SQ5LunQnphg2KkhI8vzLyJjSncAw6laDsf32aavEJ+90YJjr/28IrwR2jRDooWKfbDOD5TdJ1HJd5WGbCvBl+Hy0kQ2SrVXqPMdxbZrIlZ9521MbSx/kOZQcmrwc/KmpuJy6fvITxY+T0iOhQDvksjPq04L+ckyK/01SZiogiQtqRC1+CXtFR0MF3AU+WHx193AIE9dIPxv/XcEue72NFx70yrLdVjWYqJYu0jnoRWfDJV5x7QCMCB8RuXu+jYLt/Y3rBueMK4cX6t/hGcNXnroNdmEL3~1; ak_bmsc=71C843AD61CBEDFD62CECF0C066AE241~000000000000000000000000000000~YAAQXKwwF1QcXIygAQAA3E8OxAF6wKa+zrv5dVedozGE8QyoIPzRAYyi2XkJvztUqwr/yyE0d38zgnzNdUqysnUQ9sl6GBn/pYZ8lJBukLhzWNk6hYSduyyTaE0yOZwv5Kk9cIJSwMar6vGAYOJ1iaMpZ8qp2tHuKoKmGMN+nscsN+4/AC705b4Ru8m99acWQI/zDxzRtIR9FikDCwgdTLEKt2iLqw9jzVMSXu47IoyMYU1z8eSap0heSZXLZegynmI2c18v2j+r1rTzhEuET9rn7w8LEGYHgNEitqQXwUdQzipJlNxW+keWSemvdcRwtpkqzRzjhs8MgyF8bFdWc55OcCsiSIdQQFar7s5RxqHHpiRROkDXHsYO5ScFoe+YIDXefU9bS0LIyxSFhynTgQZmaHpQH4ShNuqG5YzMt9k8Uv/jtpDjz5FMqvFa4mkIyNMnCjrc/oZA1yFnBFQVI3vXCM96o3xuJVaQqf4BeKL1LO9bxDw6Fr6QcVTRsMrZy+Q+q6I=; __gads=ID=94ef2d83d2bb23a9:T=1781174055:RT=1789995673:S=ALNI_MZ8RCfCUCtQaB28kmDimupEsVEnvQ; __gpi=UID=0000144d69861fd3:T=1781174055:RT=1789995673:S=ALNI_MbOsDngY3tU-hJpwRkuS05kPXEXoA; __eoi=ID=6c3d5d2434eb9d89:T=1781174055:RT=1789995673:S=AA-Afja7LnpYJ9UxD_spf4vaUVZ0; __lt__sid=933cffc9-f78f10e9; _ga_VQH8622D4L=GS2.1.s1789987856$o25$g1$t1789995687$j34$l0$h0; _clsk=38ugh9%5E1789995687893%5E18%5E0%5Ej.clarity.ms%2Fcollect; bm_sv=0CC67DCBAF790A199E373058DB6F039A~YAAQ+TQ+F8pO9b+gAQAAwZ8OxAFnrqSfvBmb/sLhhDWBH1NS/444m9yqG5Rlnrgzmohrdqur0mvtqN96ACb6I/1yYipz5cRS5XVz7gnP95NN0QtPXlLQzT/N9H8wJKhTix/sXu/3PgMDqVYc4sltpKl0ePxFMoU0NFg4wV8ET88BvyUOdoYE2g290HOah/z7gn3EBVf31wpEd/D/rxM9DzfQrAAmHebyQbv27YrikxFi2BS16XE5W3pVGL3bpx51cY515PunbwJIgDCdeOX+r6TE~1; ttcsid_D66LMBBC77U5LKV8L9P0=1789993014192::Mwj_C1Zy68qUGm1fqI9i.44.1789995688608.1; ttcsid=1789993014192::htJfx0ykTxT72jhrpR8d.16.1789995688608.0::1.2671102.2674212::2657054.18.372.44::2680075.6.1087; _twsid=1789993007008-949907337.37.1789995697056'
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
const main = async () => {
|
|
1041
|
+
let pttm = new PlayTTM(my_headers_cookies)
|
|
1042
|
+
|
|
1043
|
+
let user_pick = 0
|
|
1044
|
+
let tickets = 1
|
|
1045
|
+
let my_zone = "PL1"
|
|
1046
|
+
let users = [
|
|
1047
|
+
{
|
|
1048
|
+
fullname: "SDFXZCVXZASDF",
|
|
1049
|
+
email: "play2@gmail.com",
|
|
1050
|
+
phone: "0956975152",
|
|
1051
|
+
options: "1254783532123"
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
fullname: "ZXCZXCSADj",
|
|
1055
|
+
email: "gg@gmail.com",
|
|
1056
|
+
phone: "0956975152",
|
|
1057
|
+
options: "1123457543216"
|
|
1058
|
+
}
|
|
1059
|
+
]
|
|
1060
|
+
|
|
1061
|
+
let round_json = await pttm.getRounds("https://www.thaiticketmajor.com/concert/joji-solaris-tour-2026.html")
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
console.log("ROUND_JSON : ", round_json)
|
|
1065
|
+
|
|
1066
|
+
console.log("HERE :", round_json[user_pick].url.split("=")[1])
|
|
1067
|
+
|
|
1068
|
+
let check_res = await pttm.verify_checkcondition(round_json[user_pick].url.split("=")[1])
|
|
1069
|
+
|
|
1070
|
+
console.log("CHECK_RES : ", check_res)
|
|
1071
|
+
|
|
1072
|
+
let zone_json = await pttm.getZone(round_json[user_pick].url.split("=")[1])
|
|
1073
|
+
|
|
1074
|
+
console.log("ZONE_JSON : ", zone_json)
|
|
1075
|
+
|
|
1076
|
+
let pick_date = Number(round_json[user_pick].date.split(" ")[1])
|
|
1077
|
+
|
|
1078
|
+
const pick_rdId = zone_json.rounds.find((item: any) => {
|
|
1079
|
+
return Number(item.label.split(" ")[1]) === Number(pick_date);
|
|
1080
|
+
});
|
|
1081
|
+
|
|
1082
|
+
console.log("USER PICK : ", round_json[user_pick].date.split(" ")[1])
|
|
1083
|
+
console.log("PICK RDID : ", pick_rdId)
|
|
1084
|
+
|
|
1085
|
+
if (!pick_rdId) {
|
|
1086
|
+
throw new Error("Round not found");
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
let zone_avail = await pttm.getZoneAvail(pick_rdId.id, zone_json.tk, zone_json.k, round_json[user_pick].url.split("=")[1])
|
|
1090
|
+
|
|
1091
|
+
let type_perform: any = zone_avail.filter((item: any) => {
|
|
1092
|
+
return item.id == my_zone ? item : null
|
|
1093
|
+
})
|
|
1094
|
+
|
|
1095
|
+
console.log("ZONE_AVAIL : ", zone_avail)
|
|
1096
|
+
console.log("CHECK TYPE PERFORM USER PICK : ", type_perform)
|
|
1097
|
+
|
|
1098
|
+
if (type_perform.length == 0) {
|
|
1099
|
+
console.log("ไม่พบโซนที่เลือก")
|
|
1100
|
+
return
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
if (type_perform[0].page == 'fixed.php') {
|
|
1104
|
+
let all_seats_in_zone = await pttm.getFixed(zone_json.k, my_zone, pick_rdId.id)
|
|
1105
|
+
|
|
1106
|
+
let seats = all_seats_in_zone.seats
|
|
1107
|
+
let seats_json = all_seats_in_zone.form
|
|
1108
|
+
|
|
1109
|
+
let total_seats = []
|
|
1110
|
+
|
|
1111
|
+
for (let i = 0; i < tickets; i++) {
|
|
1112
|
+
const randomIndex = Math.floor(Math.random() * seats.length);
|
|
1113
|
+
let seat_pick = seats[randomIndex]
|
|
1114
|
+
total_seats.push(seat_pick)
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
let seat_valid = await pttm.validateSeatFix(zone_json.k, my_zone, seats_json, total_seats, 'fix')
|
|
1118
|
+
|
|
1119
|
+
if (seat_valid.result == true && seat_valid.status == 0) {
|
|
1120
|
+
let booking_res = await pttm.bookingSeats(zone_json.k, seats_json, total_seats)
|
|
1121
|
+
|
|
1122
|
+
const enrollVal = booking_res.nextPayload.get("enroll_val");
|
|
1123
|
+
|
|
1124
|
+
if (enrollVal == '0') {
|
|
1125
|
+
let paymentall_json = await pttm.getPaymentAll(zone_json.k, booking_res, my_zone, seats_json.rdId, 2000)
|
|
1126
|
+
|
|
1127
|
+
console.log("PaymentAllJSON : ", paymentall_json)
|
|
1128
|
+
|
|
1129
|
+
let paycfmall = await pttm.getPayCfmall(zone_json.k, paymentall_json, '1', 'KBQR')
|
|
1130
|
+
|
|
1131
|
+
console.log("PayCFMALL : ", paycfmall)
|
|
1132
|
+
let orderenc_json = await pttm.orderenc_kbankqr(zone_json.k, paycfmall)
|
|
1133
|
+
console.log("ORDERENC_JSON : ", orderenc_json)
|
|
1134
|
+
let kbank_json = await pttm.getkbankqr(orderenc_json)
|
|
1135
|
+
console.log("KBANK_JSON : ", kbank_json)
|
|
1136
|
+
let data = await pttm.payment_kbankqr(orderenc_json, kbank_json)
|
|
1137
|
+
console.log("PAYMENT_KBANKQR : ", data)
|
|
1138
|
+
let result = await pttm.QR(data.orderId, data.apiKey, orderenc_json)
|
|
1139
|
+
console.log("RESULT : ", data)
|
|
1140
|
+
|
|
1141
|
+
console.log(result)
|
|
1142
|
+
} else {
|
|
1143
|
+
let enroll_json = await pttm.enroll(zone_json.k, my_zone, seats_json.rdId, booking_res.nextPayload)
|
|
1144
|
+
console.log("ENROLL_JSON : ", enroll_json)
|
|
1145
|
+
let enroll_process_status = await pttm.enroll_process(zone_json.k, enroll_json, users)
|
|
1146
|
+
console.log("ENROLL_PROCESS_STATUS : ", enroll_process_status)
|
|
1147
|
+
let paymentall_json = await pttm.getPaymentAll(zone_json.k, enroll_process_status.nextPayload, my_zone, seats_json.rdId, 2000)
|
|
1148
|
+
console.log("PaymentAllJSON : ", paymentall_json)
|
|
1149
|
+
let paycfmall = await pttm.getPayCfmall(zone_json.k, paymentall_json, '1', 'KBQR')
|
|
1150
|
+
console.log("PayCFMALL : ", paycfmall)
|
|
1151
|
+
let orderenc_json = await pttm.orderenc_kbankqr(zone_json.k, paycfmall)
|
|
1152
|
+
console.log("ORDERENC_JSON : ", orderenc_json)
|
|
1153
|
+
let kbank_json = await pttm.getkbankqr(orderenc_json)
|
|
1154
|
+
console.log("KBANK_JSON : ", kbank_json)
|
|
1155
|
+
let data = await pttm.payment_kbankqr(orderenc_json, kbank_json)
|
|
1156
|
+
console.log("PAYMENT_KBANKQR : ", data)
|
|
1157
|
+
let result = await pttm.QR(data.orderId, data.apiKey, orderenc_json)
|
|
1158
|
+
console.log(result)
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
} else {
|
|
1162
|
+
console.log("This Perform is under development")
|
|
1163
|
+
|
|
1164
|
+
let festival = await pttm.Festival(zone_json.k, zone_json.tk, zone_json.query, my_zone, pick_rdId.id)
|
|
1165
|
+
|
|
1166
|
+
console.log("FESTIVAL TEST : ", festival)
|
|
1167
|
+
|
|
1168
|
+
let validate_seat_festival = await pttm.validateSeatFestival(zone_json.k, festival, tickets.toString())
|
|
1169
|
+
|
|
1170
|
+
console.log("VALIDATE SEAT FESTIVAL : ", validate_seat_festival)
|
|
1171
|
+
|
|
1172
|
+
if (festival.enroll_val != '0') {
|
|
1173
|
+
let bookingfestival_response = await pttm.BookingFestival(zone_json.k, festival, tickets.toString())
|
|
1174
|
+
|
|
1175
|
+
let enroll_process_test = await pttm.enroll_process(zone_json.k, festival, users)
|
|
1176
|
+
|
|
1177
|
+
let paymentallFesitval = await pttm.getPaymentAll(zone_json.k, bookingfestival_response, festival.zone, festival.rdId, 2000)
|
|
1178
|
+
|
|
1179
|
+
let cf = await pttm.getPayCfmall(zone_json.k, paymentallFesitval, '1', 'KBQR')
|
|
1180
|
+
|
|
1181
|
+
let orderenc_json = await pttm.orderenc_kbankqr(zone_json.k, cf)
|
|
1182
|
+
let kbank_json = await pttm.getkbankqr(orderenc_json)
|
|
1183
|
+
|
|
1184
|
+
let data = await pttm.payment_kbankqr(orderenc_json, kbank_json)
|
|
1185
|
+
|
|
1186
|
+
let result = await pttm.QR(data.orderId, data.apiKey, orderenc_json)
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
console.log("Booking Festival Response : ", bookingfestival_response)
|
|
1190
|
+
|
|
1191
|
+
console.log("ENROLL PROCESS TEST", enroll_process_test)
|
|
1192
|
+
|
|
1193
|
+
console.log("PaymentallFestival", paymentallFesitval)
|
|
1194
|
+
|
|
1195
|
+
console.log("PAYCFMALL : ", cf)
|
|
1196
|
+
|
|
1197
|
+
console.log("ORDERENC_JSON : ", orderenc_json)
|
|
1198
|
+
|
|
1199
|
+
console.log("KBANK_JSON : ", kbank_json)
|
|
1200
|
+
|
|
1201
|
+
console.log("PAYMENT_KBANKQR : ", data)
|
|
1202
|
+
|
|
1203
|
+
console.log(result)
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
main()
|