myxl-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +15 -0
  2. package/dist/@types/payment.d.ts +10 -0
  3. package/dist/auth.d.ts +20 -0
  4. package/dist/auth.js +157 -0
  5. package/dist/ciam.d.ts +259 -0
  6. package/dist/ciam.js +351 -0
  7. package/dist/client.d.ts +56 -0
  8. package/dist/client.js +276 -0
  9. package/dist/config.d.ts +14 -0
  10. package/dist/config.js +70 -0
  11. package/dist/device.d.ts +23 -0
  12. package/dist/device.js +107 -0
  13. package/dist/encrypt.d.ts +37 -0
  14. package/dist/encrypt.js +259 -0
  15. package/dist/family-plan.d.ts +28 -0
  16. package/dist/family-plan.js +325 -0
  17. package/dist/family.d.ts +146 -0
  18. package/dist/family.js +365 -0
  19. package/dist/index.d.ts +19 -0
  20. package/dist/index.js +1487 -0
  21. package/dist/lib/decoy.d.ts +17 -0
  22. package/dist/lib/decoy.js +117 -0
  23. package/dist/lib/encrypt-helper.d.ts +71 -0
  24. package/dist/lib/encrypt-helper.js +166 -0
  25. package/dist/lib/payment.d.ts +116 -0
  26. package/dist/lib/payment.js +271 -0
  27. package/dist/lib/utils.d.ts +15 -0
  28. package/dist/lib/utils.js +290 -0
  29. package/dist/notification.d.ts +28 -0
  30. package/dist/notification.js +275 -0
  31. package/dist/package.d.ts +259 -0
  32. package/dist/package.js +387 -0
  33. package/dist/payments/balance.d.ts +2 -0
  34. package/dist/payments/balance.js +408 -0
  35. package/dist/payments/decoy.d.ts +1 -0
  36. package/dist/payments/decoy.js +6 -0
  37. package/dist/payments/ewallet.d.ts +11 -0
  38. package/dist/payments/ewallet.js +373 -0
  39. package/dist/payments/index.d.ts +3 -0
  40. package/dist/payments/index.js +632 -0
  41. package/dist/payments/qris.d.ts +2 -0
  42. package/dist/payments/qris.js +378 -0
  43. package/dist/profile.d.ts +1 -0
  44. package/dist/profile.js +266 -0
  45. package/dist/verification.d.ts +2 -0
  46. package/dist/verification.js +279 -0
  47. package/package.json +116 -0
package/dist/index.js ADDED
@@ -0,0 +1,1487 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ function __accessProp(key) {
7
+ return this[key];
8
+ }
9
+ var __toCommonJS = (from) => {
10
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
11
+ if (entry)
12
+ return entry;
13
+ entry = __defProp({}, "__esModule", { value: true });
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (var key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(entry, key))
17
+ __defProp(entry, key, {
18
+ get: __accessProp.bind(from, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ __moduleCache.set(from, entry);
23
+ return entry;
24
+ };
25
+ var __moduleCache;
26
+ var __returnValue = (v) => v;
27
+ function __exportSetter(name, newValue) {
28
+ this[name] = __returnValue.bind(null, newValue);
29
+ }
30
+ var __export = (target, all) => {
31
+ for (var name in all)
32
+ __defProp(target, name, {
33
+ get: all[name],
34
+ enumerable: true,
35
+ configurable: true,
36
+ set: __exportSetter.bind(all, name)
37
+ });
38
+ };
39
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
40
+
41
+ // src/lib/encrypt-helper.ts
42
+ var exports_encrypt_helper = {};
43
+ __export(exports_encrypt_helper, {
44
+ makeXSignaturePayment: () => makeXSignaturePayment,
45
+ makeXSignatureLoyalty: () => makeXSignatureLoyalty,
46
+ makeXSignatureBountyAllotment: () => makeXSignatureBountyAllotment,
47
+ makeXSignatureBounty: () => makeXSignatureBounty,
48
+ makeXSignatureBasic: () => makeXSignatureBasic,
49
+ makeXSignature: () => makeXSignature,
50
+ makeAxApiSignature: () => makeAxApiSignature,
51
+ encryptXData: () => encryptXData,
52
+ encryptEncryptedField: () => encryptEncryptedField,
53
+ decryptXData: () => decryptXData,
54
+ decryptEncryptedField: () => decryptEncryptedField
55
+ });
56
+ import crypto from "crypto";
57
+ function pkcs7Pad(buf, blockSize = 16) {
58
+ const pad = blockSize - buf.length % blockSize;
59
+ const padBuf = Buffer.alloc(pad, pad);
60
+ return Buffer.concat([buf, padBuf]);
61
+ }
62
+ function pkcs7Unpad(buf) {
63
+ const pad = buf[buf.length - 1] ?? 16;
64
+ if (pad < 1 || pad > 16)
65
+ throw new Error("Invalid PKCS7 padding");
66
+ return buf.slice(0, buf.length - pad);
67
+ }
68
+ function deriveIv(xtimeMs) {
69
+ const sha = crypto.createHash("sha256").update(String(xtimeMs)).digest("hex");
70
+ return Buffer.from(sha.slice(0, 16), "ascii");
71
+ }
72
+ function urlsafeB64Encode(buf) {
73
+ return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_");
74
+ }
75
+ function urlsafeB64Decode(s) {
76
+ const b64 = s.replace(/-/g, "+").replace(/_/g, "/");
77
+ const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
78
+ return Buffer.from(padded, "base64");
79
+ }
80
+ function encryptXData(plaintext, xtimeMs) {
81
+ const key = Buffer.from(XDATA_KEY, "ascii");
82
+ const iv = deriveIv(xtimeMs);
83
+ const padded = pkcs7Pad(Buffer.from(plaintext, "utf-8"));
84
+ const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
85
+ cipher.setAutoPadding(false);
86
+ const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
87
+ return urlsafeB64Encode(ct);
88
+ }
89
+ function decryptXData(xdata, xtimeMs) {
90
+ const key = Buffer.from(XDATA_KEY, "ascii");
91
+ const iv = deriveIv(xtimeMs);
92
+ const ct = urlsafeB64Decode(xdata);
93
+ const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
94
+ decipher.setAutoPadding(false);
95
+ const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
96
+ return pkcs7Unpad(pt).toString("utf-8");
97
+ }
98
+ function makeXSignature(idToken, method, path, sigTimeSec) {
99
+ const keyStr = `${X_API_BASE_SECRET};${idToken};${method};${path};${sigTimeSec}`;
100
+ const msg = `${idToken};${sigTimeSec};`;
101
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
102
+ }
103
+ function makeXSignaturePayment(accessToken, sigTimeSec, packageCode, tokenPayment, paymentMethod, paymentFor, path) {
104
+ const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
105
+ const msg = `${accessToken};${tokenPayment};${sigTimeSec};${paymentFor};${paymentMethod};${packageCode};`;
106
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
107
+ }
108
+ function makeXSignatureBounty(accessToken, sigTimeSec, packageCode, tokenPayment) {
109
+ const path = "api/v8/personalization/bounties-exchange";
110
+ const keyStr = `${X_API_BASE_SECRET};${accessToken};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
111
+ const msg = `${accessToken};${tokenPayment};${sigTimeSec};${packageCode};`;
112
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
113
+ }
114
+ function makeXSignatureLoyalty(sigTimeSec, packageCode, tokenConfirmation, path) {
115
+ const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
116
+ const msg = `${tokenConfirmation};${sigTimeSec};${packageCode};`;
117
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
118
+ }
119
+ function makeXSignatureBountyAllotment(sigTimeSec, packageCode, tokenConfirmation, path, destinationMsisdn) {
120
+ const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;${destinationMsisdn};POST;${path};${sigTimeSec}`;
121
+ const msg = `${tokenConfirmation};${sigTimeSec};${destinationMsisdn};${packageCode};`;
122
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
123
+ }
124
+ function makeXSignatureBasic(method, path, sigTimeSec) {
125
+ const keyStr = `${X_API_BASE_SECRET};${method};${path};${sigTimeSec}`;
126
+ const msg = `${sigTimeSec};en;`;
127
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
128
+ }
129
+ function makeAxApiSignature(tsForSign, contact, code, contactType) {
130
+ const preimage = `${tsForSign}password${contactType}${contact}${code}openid`;
131
+ const digest = crypto.createHmac("sha256", Buffer.from(AX_API_SIG_KEY, "ascii")).update(preimage).digest();
132
+ return digest.toString("base64");
133
+ }
134
+ function decryptEncryptedField(encryptedB64) {
135
+ const ivAscii = encryptedB64.slice(-16);
136
+ const b64Part = encryptedB64.slice(0, -16);
137
+ const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
138
+ const iv = Buffer.from(ivAscii, "ascii");
139
+ const ct = urlsafeB64Decode(b64Part);
140
+ const decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);
141
+ decipher.setAutoPadding(false);
142
+ const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
143
+ return pkcs7Unpad(pt).toString("utf-8");
144
+ }
145
+ function encryptEncryptedField(plaintext) {
146
+ const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
147
+ const ivHex = crypto.randomBytes(8).toString("hex");
148
+ const iv = Buffer.from(ivHex, "ascii");
149
+ const padded = pkcs7Pad(Buffer.from(plaintext, "utf-8"));
150
+ const cipher = crypto.createCipheriv("aes-128-cbc", key, iv);
151
+ cipher.setAutoPadding(false);
152
+ const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
153
+ return urlsafeB64Encode(ct) + ivHex;
154
+ }
155
+ var init_encrypt_helper = __esm(() => {
156
+ init_config();
157
+ });
158
+
159
+ // src/encrypt.ts
160
+ var exports_encrypt = {};
161
+ __export(exports_encrypt, {
162
+ makeXSignaturePayment: () => makeXSignaturePayment,
163
+ makeXSignatureLoyalty: () => makeXSignatureLoyalty,
164
+ makeXSignatureBountyAllotment: () => makeXSignatureBountyAllotment,
165
+ makeXSignatureBounty: () => makeXSignatureBounty,
166
+ makeXSignatureBasic: () => makeXSignatureBasic,
167
+ makeAxApiSignature: () => makeAxApiSignature,
168
+ encryptSignXData: () => encryptSignXData,
169
+ encryptEncryptedField: () => encryptEncryptedField,
170
+ decryptXDataSync: () => decryptXDataSync,
171
+ decryptXData: () => decryptXData2,
172
+ decryptEncryptedField: () => decryptEncryptedField,
173
+ buildEncryptedField: () => buildEncryptedField
174
+ });
175
+ import crypto2 from "crypto";
176
+ function encryptSignXData(method, path, idToken, payload) {
177
+ const plainBody = JSON.stringify(payload);
178
+ const xtime = Date.now();
179
+ const xdata = encryptXData(plainBody, xtime);
180
+ const sigTimeSec = Math.floor(xtime / 1000);
181
+ const xSignature = makeXSignature(idToken, method, path, sigTimeSec);
182
+ return {
183
+ x_signature: xSignature,
184
+ encrypted_body: { xdata, xtime }
185
+ };
186
+ }
187
+ function decryptXDataSync(xdata, xtimeMs) {
188
+ const { decryptXData: decryptXData2 } = (init_encrypt_helper(), __toCommonJS(exports_encrypt_helper));
189
+ const plaintext = decryptXData2(xdata, xtimeMs);
190
+ return JSON.parse(plaintext);
191
+ }
192
+ async function decryptXData2(xdata, xtimeMs) {
193
+ const { decryptXData: _decrypt } = (init_encrypt_helper(), __toCommonJS(exports_encrypt_helper));
194
+ return JSON.parse(_decrypt(xdata, xtimeMs));
195
+ }
196
+ function randomIvHex16() {
197
+ return crypto2.randomBytes(8).toString("hex");
198
+ }
199
+ function b64(data, urlsafe) {
200
+ const b64str = data.toString("base64");
201
+ if (urlsafe) {
202
+ return b64str.replace(/\+/g, "-").replace(/\//g, "_");
203
+ }
204
+ return b64str;
205
+ }
206
+ function buildEncryptedField(ivHex16 = null, urlsafeB64 = false) {
207
+ const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
208
+ const ivHex = ivHex16 ?? randomIvHex16();
209
+ const iv = Buffer.from(ivHex, "ascii");
210
+ const pt = Buffer.alloc(16, 16);
211
+ const cipher = crypto2.createCipheriv("aes-128-cbc", key, iv);
212
+ cipher.setAutoPadding(false);
213
+ const ct = Buffer.concat([cipher.update(pt), cipher.final()]);
214
+ return b64(ct, urlsafeB64) + ivHex;
215
+ }
216
+ var init_encrypt = __esm(() => {
217
+ init_config();
218
+ init_encrypt_helper();
219
+ init_encrypt_helper();
220
+ });
221
+
222
+ // src/lib/utils.ts
223
+ var exports_utils = {};
224
+ __export(exports_utils, {
225
+ unseal: () => unseal,
226
+ tsGmt7WithoutColon: () => tsGmt7WithoutColon,
227
+ sendApiRequest: () => sendApiRequest,
228
+ javaLikeTimestamp: () => javaLikeTimestamp,
229
+ interceptPage: () => interceptPage,
230
+ base64Encode: () => base64Encode
231
+ });
232
+ import axios from "axios";
233
+ import { v4 as uuidv4 } from "uuid";
234
+ import { DateTime } from "luxon";
235
+ function javaLikeTimestamp(dt = DateTime.now()) {
236
+ return dt.toMillis().toString();
237
+ }
238
+ async function sendApiRequest(path, payloadDict, idToken, method = "POST") {
239
+ const encryptedPayload = encryptSignXData(method, path, idToken, payloadDict);
240
+ const xtime = Number(encryptedPayload.encrypted_body.xtime);
241
+ const sigTimeSec = Math.floor(xtime / 1000);
242
+ const body = encryptedPayload.encrypted_body;
243
+ const x_sig = encryptedPayload.x_signature;
244
+ const headers = {
245
+ host: BASE_API_URL.replace(/^https?:\/\//, ""),
246
+ "content-type": "application/json; charset=utf-8",
247
+ "user-agent": UA,
248
+ "x-api-key": API_KEY,
249
+ authorization: `Bearer ${idToken}`,
250
+ "x-hv": "v3",
251
+ "x-signature-time": String(sigTimeSec),
252
+ "x-signature": x_sig,
253
+ "x-request-id": uuidv4(),
254
+ "x-request-at": javaLikeTimestamp(),
255
+ "x-version-app": X_APP_VERSION
256
+ };
257
+ const url = `${BASE_API_URL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
258
+ const resp = await axios.post(url, body, {
259
+ headers,
260
+ timeout: 30000
261
+ });
262
+ const respData = resp.data;
263
+ const decryptedXData = await decryptXData2(respData.xdata, respData.xtime);
264
+ if (decryptedXData.status === "FAILED") {
265
+ throw new Error(JSON.stringify(decryptedXData));
266
+ }
267
+ return decryptedXData;
268
+ }
269
+ function base64Encode(str) {
270
+ return Buffer.from(str, "utf-8").toString("base64");
271
+ }
272
+ function tsGmt7WithoutColon(date) {
273
+ let formatted = date.toFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
274
+ if (formatted.endsWith("+07:00")) {
275
+ formatted = formatted.replace("+07:00", "+0700");
276
+ }
277
+ return formatted;
278
+ }
279
+ async function interceptPage(idToken, optionCode, isEnterprise = false) {
280
+ const path = "misc/api/v8/utility/intercept-page";
281
+ const rawPayload = {
282
+ is_enterprise: isEnterprise,
283
+ lang: "en",
284
+ package_option_code: optionCode
285
+ };
286
+ console.log("Fetching intercept page...");
287
+ try {
288
+ const res = await sendApiRequest(path, rawPayload, idToken, "POST");
289
+ if ("status" in res) {
290
+ console.log(`Intercept status: ${res["status"]}`);
291
+ } else {
292
+ console.log("Intercept error");
293
+ }
294
+ } catch (err) {
295
+ console.log("Intercept error", err);
296
+ }
297
+ }
298
+ function unseal(getter, fallback) {
299
+ try {
300
+ const hex = getter();
301
+ if (!hex || typeof __SEED__ === "undefined")
302
+ return fallback;
303
+ const seed = Buffer.from(__SEED__, "hex");
304
+ const data = Buffer.from(hex, "hex");
305
+ return Buffer.from(data.map((b, i) => b ^ seed[i % seed.length])).toString("utf8");
306
+ } catch {
307
+ return fallback;
308
+ }
309
+ }
310
+ var init_utils = __esm(() => {
311
+ init_config();
312
+ init_encrypt();
313
+ });
314
+
315
+ // src/config.ts
316
+ var exports_config = {};
317
+ __export(exports_config, {
318
+ X_APP_VERSION: () => X_APP_VERSION,
319
+ X_API_BASE_SECRET: () => X_API_BASE_SECRET,
320
+ XDATA_KEY: () => XDATA_KEY,
321
+ UA: () => UA,
322
+ ENCRYPTED_FIELD_KEY: () => ENCRYPTED_FIELD_KEY,
323
+ DEFAULT_AX_FP: () => DEFAULT_AX_FP,
324
+ DEFAULT_AX_DEVICE_ID: () => DEFAULT_AX_DEVICE_ID,
325
+ CIRCLE_MSISDN_KEY: () => CIRCLE_MSISDN_KEY,
326
+ BASIC_AUTH: () => BASIC_AUTH,
327
+ BASE_CIAM_URL: () => BASE_CIAM_URL,
328
+ BASE_API_URL: () => BASE_API_URL,
329
+ AX_FP_KEY: () => AX_FP_KEY,
330
+ AX_API_SIG_KEY: () => AX_API_SIG_KEY,
331
+ API_KEY: () => API_KEY
332
+ });
333
+ var BASE_API_URL, BASE_CIAM_URL, BASIC_AUTH, AX_FP_KEY, UA, API_KEY, ENCRYPTED_FIELD_KEY, XDATA_KEY, AX_API_SIG_KEY, X_API_BASE_SECRET, CIRCLE_MSISDN_KEY, DEFAULT_AX_DEVICE_ID = "a9698fc65ed122e1b0efb2b7e9d93728", DEFAULT_AX_FP = "LDMGk/l1xEViBHOOsQb/CtVyh6FI0QvxXGfsoizEhr7ms1SBTYN07kcmSY3CWDlkG39iSV4p0AuafPoIL+pyoI+1StGif01C7Z/3Lprtkn+WHS3QAKHuAb8LQGe9/2pn", X_APP_VERSION = "8.9.0";
334
+ var init_config = __esm(() => {
335
+ init_utils();
336
+ BASE_API_URL = unseal(() => __E_BASE_API_URL__, "https://api.myxl.xlaxiata.co.id");
337
+ BASE_CIAM_URL = unseal(() => __E_BASE_CIAM_URL__, "https://gede.ciam.xlaxiata.co.id");
338
+ BASIC_AUTH = unseal(() => __E_BASIC_AUTH__, "OWZjOTdlZDEtNmEzMC00OGQ1LTk1MTYtNjBjNTNjZTNhMTM1OllEV21GNExKajlYSUt3UW56eTJlMmxiMHRKUWIyOW8z");
339
+ AX_FP_KEY = unseal(() => __E_AX_FP_KEY__, "18b4d589826af50241177961590e6693");
340
+ UA = unseal(() => __E_UA__, "myXL / 8.9.0(1202); com.android.vending; (samsung; SM-N935F; SDK 33; Android 13)");
341
+ API_KEY = unseal(() => __E_API_KEY__, "vT8tINqHaOxXbGE7eOWAhA==");
342
+ ENCRYPTED_FIELD_KEY = unseal(() => __E_ENCRYPTED_FIELD_KEY__, "5dccbf08920a5527");
343
+ XDATA_KEY = unseal(() => __E_XDATA_KEY__, "5dccbf08920a5527b99e222789c34bb7");
344
+ AX_API_SIG_KEY = unseal(() => __E_AX_API_SIG_KEY__, "18b4d589826af50241177961590e6693");
345
+ X_API_BASE_SECRET = unseal(() => __E_X_API_BASE_SECRET__, "mU1Y4n1vBjf3M7tMnRkFU08mVyUJHed8B5En3EAniu1mXLixeuASmBmKnkyzVziOye7rG5nIekMdthensbQMcOJ6SLnrkGyfXALD7mrBC6vuWv6G01pmD3XlU5rT7Tzx");
346
+ CIRCLE_MSISDN_KEY = unseal(() => __E_CIRCLE_MSISDN_KEY__, "5dccbf08920a5527");
347
+ });
348
+
349
+ // src/auth.ts
350
+ init_config();
351
+ init_utils();
352
+ init_encrypt();
353
+ var exports_auth = {};
354
+ __export(exports_auth, {
355
+ submitSmsOtp: () => submitSmsOtp,
356
+ submitOtp: () => submitOtp,
357
+ getOtp: () => getOtp
358
+ });
359
+ import axios2 from "axios";
360
+ import { v4 as uuidv42 } from "uuid";
361
+ import { DateTime as DateTime2, FixedOffsetZone } from "luxon";
362
+ import * as crypto3 from "crypto";
363
+ async function getOtp(contact, axDeviceId, axFingerprint) {
364
+ const url = BASE_CIAM_URL + "/realms/xl-ciam/auth/otp";
365
+ const querystring = {
366
+ contact,
367
+ contactType: "SMS",
368
+ alternateContact: "false"
369
+ };
370
+ const gmt7Zone = FixedOffsetZone.instance(420);
371
+ const now = DateTime2.now().setZone(gmt7Zone);
372
+ const ax_request_at = javaLikeTimestamp(now);
373
+ const ax_request_id = uuidv42();
374
+ const headers = {
375
+ "Accept-Encoding": "gzip, deflate, br",
376
+ Authorization: `Basic ${BASIC_AUTH}`,
377
+ "Ax-Device-Id": axDeviceId,
378
+ "Ax-Fingerprint": axFingerprint,
379
+ "Ax-Request-At": ax_request_at,
380
+ "Ax-Request-Device": "samsung",
381
+ "Ax-Request-Device-Model": "SM-N935F",
382
+ "Ax-Request-Id": ax_request_id,
383
+ "Ax-Substype": "PREPAID",
384
+ "Content-Type": "application/json",
385
+ Host: BASE_CIAM_URL.replace(/^https?:\/\//, ""),
386
+ "User-Agent": UA
387
+ };
388
+ const { data } = await axios2.get(url, {
389
+ headers,
390
+ params: querystring,
391
+ timeout: 30000
392
+ });
393
+ return data;
394
+ }
395
+ async function submitOtp(contactType, contact, code, axDeviceId, axFingerprint) {
396
+ let finalContact = "";
397
+ let finalCode = "";
398
+ if (contactType === "SMS") {
399
+ finalContact = contact;
400
+ finalCode = code;
401
+ } else if (contactType === "DEVICEID") {
402
+ finalContact = base64Encode(contact);
403
+ finalCode = code;
404
+ }
405
+ const url = BASE_CIAM_URL + "/realms/xl-ciam/protocol/openid-connect/token";
406
+ const now = DateTime2.now().setZone("Asia/Jakarta");
407
+ const ts_for_sign = tsGmt7WithoutColon(now);
408
+ const ts_header = tsGmt7WithoutColon(now.minus({ minutes: 5 }));
409
+ const signature = await makeAxApiSignature(ts_for_sign, finalContact, code, contactType);
410
+ const payload = `contactType=${encodeURIComponent(contactType)}&code=${encodeURIComponent(finalCode)}&grant_type=password&contact=${encodeURIComponent(finalContact)}&scope=openid`;
411
+ const axRequestId = crypto3.randomUUID();
412
+ const headers = {
413
+ "Accept-Encoding": "gzip, deflate, br",
414
+ Authorization: `Basic ${BASIC_AUTH}`,
415
+ "Ax-Api-Signature": signature,
416
+ "Ax-Device-Id": axDeviceId,
417
+ "Ax-Fingerprint": axFingerprint,
418
+ "Ax-Request-At": ts_header,
419
+ "Ax-Request-Device": "samsung",
420
+ "Ax-Request-Device-Model": "SM-N935F",
421
+ "Ax-Request-Id": axRequestId,
422
+ "Ax-Substype": "PREPAID",
423
+ "Content-Type": "application/x-www-form-urlencoded",
424
+ "User-Agent": UA
425
+ };
426
+ const response = await axios2.post(url, payload, {
427
+ headers,
428
+ timeout: 30000
429
+ });
430
+ return response.data;
431
+ }
432
+ async function submitSmsOtp(contact, code, axDeviceId, axFingerprint) {
433
+ return submitOtp("SMS", contact, code, axDeviceId, axFingerprint);
434
+ }
435
+ // src/ciam.ts
436
+ init_config();
437
+ init_utils();
438
+ var exports_ciam = {};
439
+ __export(exports_ciam, {
440
+ getTieringInfo: () => getTieringInfo,
441
+ getRedeemables: () => getRedeemables,
442
+ getProfile: () => getProfile,
443
+ getNewToken: () => getNewToken,
444
+ getBalance: () => getBalance,
445
+ fetchMyPackages: () => fetchMyPackages,
446
+ checkQuota: () => checkQuota
447
+ });
448
+ import axios3 from "axios";
449
+ import { DateTime as DateTime3, FixedOffsetZone as FixedOffsetZone2 } from "luxon";
450
+ import { v4 as uuidv43 } from "uuid";
451
+ async function getNewToken(refreshToken, axDeviceId, axFingerprint) {
452
+ try {
453
+ const url = `${BASE_CIAM_URL}/realms/xl-ciam/protocol/openid-connect/token`;
454
+ const gmt7Zone = FixedOffsetZone2.instance(420);
455
+ const now = DateTime3.now().setZone(gmt7Zone);
456
+ const ax_request_at = now.toFormat("yyyy-MM-dd'T'HH:mm:ss.SSS") + "+0700";
457
+ const ax_request_id = uuidv43();
458
+ const headers = {
459
+ Host: BASE_CIAM_URL.replace("https://", ""),
460
+ "ax-request-at": ax_request_at,
461
+ "ax-device-id": axDeviceId,
462
+ "ax-request-id": ax_request_id,
463
+ "ax-request-device": "samsung",
464
+ "ax-request-device-model": "SM-N935F",
465
+ "ax-fingerprint": axFingerprint,
466
+ authorization: `Basic ${BASIC_AUTH}`,
467
+ "user-agent": UA,
468
+ "ax-substype": "PREPAID",
469
+ "content-type": "application/x-www-form-urlencoded"
470
+ };
471
+ const data = new URLSearchParams({
472
+ grant_type: "refresh_token",
473
+ refresh_token: refreshToken
474
+ });
475
+ const resp = await axios3.post(url, data.toString(), {
476
+ headers,
477
+ timeout: 30000
478
+ });
479
+ return resp.data;
480
+ } catch (error) {
481
+ console.error("Refresh token tidak valid:", error);
482
+ throw new Error("Refresh token tidak valid.");
483
+ }
484
+ }
485
+ async function getProfile(accessToken, idToken) {
486
+ const path = "api/v8/profile";
487
+ const rawPayload = {
488
+ access_token: accessToken,
489
+ app_version: X_APP_VERSION,
490
+ is_enterprise: false,
491
+ lang: "en"
492
+ };
493
+ const res = await sendApiRequest(path, rawPayload, idToken, "POST");
494
+ return res.data.profile;
495
+ }
496
+ async function getBalance(idToken) {
497
+ const path = "api/v8/packages/balance-and-credit";
498
+ const rawPayload = {
499
+ is_enterprise: false,
500
+ lang: "en"
501
+ };
502
+ return await sendApiRequest(path, rawPayload, idToken, "POST");
503
+ }
504
+ async function getTieringInfo(idToken) {
505
+ const path = "gamification/api/v8/loyalties/tiering/info";
506
+ const rawPayload = {
507
+ is_enterprise: false,
508
+ lang: "en"
509
+ };
510
+ return await sendApiRequest(path, rawPayload, idToken, "POST");
511
+ }
512
+ async function getRedeemables({ idToken, isEnterprise }) {
513
+ const path = "api/v8/personalization/redeemables";
514
+ const rawPayload = {
515
+ is_enterprise: isEnterprise,
516
+ lang: "en"
517
+ };
518
+ return await sendApiRequest(path, rawPayload, idToken, "POST");
519
+ }
520
+ async function checkQuota(msisdn) {
521
+ const url = `https://xl-ku.my.id/end.php?check=package&number=${msisdn}&version=2`;
522
+ console.log(`Fetching quota for ${msisdn} from external API...`);
523
+ const response = await axios3.get(url);
524
+ return response.data;
525
+ }
526
+ async function fetchMyPackages({ idToken }) {
527
+ const path = "api/v8/packages/quota-details";
528
+ const rawPayload = {
529
+ is_enterprise: false,
530
+ lang: "en",
531
+ family_member_id: ""
532
+ };
533
+ return await sendApiRequest(path, rawPayload, idToken, "POST");
534
+ }
535
+ // src/client.ts
536
+ init_utils();
537
+ var exports_client = {};
538
+ __export(exports_client, {
539
+ getTransactionHistory: () => getTransactionHistory,
540
+ dashboardSegments: () => dashboardSegments
541
+ });
542
+ async function getTransactionHistory({ idToken }) {
543
+ const path = "payments/api/v8/transaction-history";
544
+ const payload = {
545
+ is_enterprise: false,
546
+ lang: "en"
547
+ };
548
+ console.log("Fetching transaction history...");
549
+ const res = await sendApiRequest(path, payload, idToken, "POST");
550
+ return res.data.list;
551
+ }
552
+ async function dashboardSegments({ idToken, accessToken }) {
553
+ const path = "dashboard/api/v8/segments";
554
+ const rawPayload = {
555
+ access_token: accessToken
556
+ };
557
+ const res = await sendApiRequest(path, rawPayload, idToken, "POST");
558
+ return res;
559
+ }
560
+
561
+ // src/index.ts
562
+ init_config();
563
+
564
+ // src/device.ts
565
+ init_config();
566
+ var exports_device = {};
567
+ __export(exports_device, {
568
+ getAxDeviceId: () => getAxDeviceId,
569
+ generateAxFp: () => generateAxFp,
570
+ buildFingerprintPlain: () => buildFingerprintPlain,
571
+ axFingerprint: () => axFingerprint
572
+ });
573
+ import crypto4 from "crypto";
574
+ function randint(min, max) {
575
+ return Math.floor(Math.random() * (max - min + 1)) + min;
576
+ }
577
+ function buildFingerprintPlain(dev) {
578
+ return `${dev.manufacturer}|${dev.model}|${dev.lang}|${dev.resolution}|` + `${dev.tz_short}|${dev.ip}|${dev.font_scale}|Android ${dev.android_release}|${dev.msisdn}`;
579
+ }
580
+ function pkcs7Pad2(buf, blockSize = 16) {
581
+ const padLen = blockSize - (buf.length % blockSize || blockSize);
582
+ const padByte = padLen;
583
+ const padding = Buffer.alloc(padLen, padByte);
584
+ return Buffer.concat([buf, padding]);
585
+ }
586
+ function axFingerprint(dev, secretKey32Ascii) {
587
+ const key = Buffer.from(secretKey32Ascii, "ascii");
588
+ if (![16, 24, 32].includes(key.length)) {
589
+ throw new Error(`AX_FP_KEY invalid length: got ${key.length} bytes. Expected 16/24/32 ASCII chars.`);
590
+ }
591
+ const iv = Buffer.alloc(16, 0);
592
+ const pt = Buffer.from(buildFingerprintPlain(dev), "utf8");
593
+ const padded = pkcs7Pad2(pt, 16);
594
+ const cipher = crypto4.createCipheriv(key.length === 16 ? "aes-128-cbc" : key.length === 24 ? "aes-192-cbc" : "aes-256-cbc", key, iv);
595
+ cipher.setAutoPadding(false);
596
+ const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
597
+ return ct.toString("base64");
598
+ }
599
+ function generateAxFp(params) {
600
+ const dev = {
601
+ manufacturer: "samsung" + String(randint(1000, 9999)),
602
+ model: "SM-N93" + String(randint(1000, 9999)),
603
+ lang: "en",
604
+ resolution: "720x1540",
605
+ tz_short: "GMT07:00",
606
+ ip: params?.ip ?? "192.169.69.69",
607
+ font_scale: 1,
608
+ android_release: "13",
609
+ msisdn: params?.msisdn ?? "6281398370564"
610
+ };
611
+ const fp = axFingerprint(dev, AX_FP_KEY);
612
+ return fp;
613
+ }
614
+ function getAxDeviceId(axFp) {
615
+ if (!axFp || !axFp.trim())
616
+ throw new Error("AX_FP is empty");
617
+ return crypto4.createHash("md5").update(axFp, "utf8").digest("hex");
618
+ }
619
+
620
+ // src/index.ts
621
+ init_encrypt();
622
+
623
+ // src/family.ts
624
+ init_utils();
625
+ var exports_family = {};
626
+ __export(exports_family, {
627
+ getFamilySafe: () => getFamilySafe,
628
+ getFamily: () => getFamily
629
+ });
630
+ async function getFamily(idToken, familyCode, isEnterprise, migrationType) {
631
+ let isEnterpriseList = [false, true];
632
+ let migrationTypeList = [
633
+ "NONE",
634
+ "PRE_TO_PRIOH",
635
+ "PRIOH_TO_PRIO",
636
+ "PRIO_TO_PRIOH"
637
+ ];
638
+ if (typeof isEnterprise !== "undefined") {
639
+ isEnterpriseList = [isEnterprise];
640
+ }
641
+ if (typeof migrationType !== "undefined") {
642
+ migrationTypeList = [migrationType];
643
+ }
644
+ const path = "api/v8/xl-stores/options/list";
645
+ const comboList = [];
646
+ for (const mt of migrationTypeList) {
647
+ for (const ie of isEnterpriseList) {
648
+ comboList.push({ ie, mt });
649
+ }
650
+ }
651
+ const requests = comboList.map(({ ie, mt }) => {
652
+ const payloadDict = {
653
+ is_show_tagging_tab: true,
654
+ is_dedicated_event: true,
655
+ is_transaction_routine: false,
656
+ migration_type: mt,
657
+ package_family_code: familyCode,
658
+ is_autobuy: false,
659
+ is_enterprise: ie,
660
+ is_pdlp: true,
661
+ referral_code: "",
662
+ is_migration: false,
663
+ lang: "en"
664
+ };
665
+ return sendApiRequest(path, payloadDict, idToken, "POST").then((res) => ({
666
+ res,
667
+ ie,
668
+ mt
669
+ })).catch((e) => {
670
+ return { res: null, ie, mt, error: e };
671
+ });
672
+ });
673
+ const results = await Promise.all(requests);
674
+ for (const { res, ie, mt } of results) {
675
+ if (res && res["status"] === "SUCCESS") {
676
+ const familyName = res.data?.package_family?.name ?? "";
677
+ if (familyName !== "") {
678
+ console.log(`Success with is_enterprise=${ie}, migration_type=${mt}. Family name: ${familyName}`);
679
+ return res.data;
680
+ }
681
+ }
682
+ }
683
+ return null;
684
+ }
685
+ async function getFamilySafe(idToken, familyCode, isEnterprise, migrationType) {
686
+ let isEnterpriseList = [false, true];
687
+ let migrationTypeList = [
688
+ "NONE",
689
+ "PRE_TO_PRIOH",
690
+ "PRIOH_TO_PRIO",
691
+ "PRIO_TO_PRIOH"
692
+ ];
693
+ if (typeof isEnterprise !== "undefined") {
694
+ isEnterpriseList = [isEnterprise];
695
+ }
696
+ if (typeof migrationType !== "undefined") {
697
+ migrationTypeList = [migrationType];
698
+ }
699
+ const path = "api/v8/xl-stores/options/list";
700
+ let familyData = null;
701
+ for (const mt of migrationTypeList) {
702
+ if (familyData !== null)
703
+ break;
704
+ for (const ie of isEnterpriseList) {
705
+ if (familyData !== null)
706
+ break;
707
+ const payloadDict = {
708
+ is_show_tagging_tab: true,
709
+ is_dedicated_event: true,
710
+ is_transaction_routine: false,
711
+ migration_type: mt,
712
+ package_family_code: familyCode,
713
+ is_autobuy: false,
714
+ is_enterprise: ie,
715
+ is_pdlp: true,
716
+ referral_code: "",
717
+ is_migration: false,
718
+ lang: "en"
719
+ };
720
+ try {
721
+ const res = await sendApiRequest(path, payloadDict, idToken, "POST");
722
+ if (!res || res["status"] !== "SUCCESS") {
723
+ continue;
724
+ }
725
+ const familyName = res.data?.package_family?.name ?? "";
726
+ if (familyName !== "") {
727
+ familyData = res.data;
728
+ console.log(`Success with is_enterprise=${ie}, migration_type=${mt}. Family name: ${familyName}`);
729
+ }
730
+ } catch (e) {
731
+ continue;
732
+ }
733
+ }
734
+ }
735
+ return familyData;
736
+ }
737
+ // src/family-plan.ts
738
+ init_utils();
739
+ var exports_family_plan = {};
740
+ __export(exports_family_plan, {
741
+ validateMsisdn: () => validateMsisdn,
742
+ setQuotaLimit: () => setQuotaLimit,
743
+ removeMember: () => removeMember,
744
+ getFamilyData: () => getFamilyData,
745
+ changeMember: () => changeMember
746
+ });
747
+ async function getFamilyData(idToken) {
748
+ const path = "sharings/api/v8/family-plan/member-info";
749
+ const payload = {
750
+ group_id: 0,
751
+ is_enterprise: false,
752
+ lang: "en"
753
+ };
754
+ return sendApiRequest(path, payload, idToken, "POST");
755
+ }
756
+ async function validateMsisdn(idToken, msisdn) {
757
+ const path = "api/v8/auth/validate-msisdn";
758
+ const payload = {
759
+ with_bizon: true,
760
+ with_family_plan: true,
761
+ is_enterprise: false,
762
+ with_optimus: true,
763
+ lang: "en",
764
+ msisdn,
765
+ with_regist_status: true,
766
+ with_enterprise: true
767
+ };
768
+ return sendApiRequest(path, payload, idToken, "POST");
769
+ }
770
+ async function changeMember(idToken, parentAlias, alias, slotId, familyMemberId, newMsisdn) {
771
+ const path = "sharings/api/v8/family-plan/change-member";
772
+ const payload = {
773
+ parent_alias: parentAlias,
774
+ is_enterprise: false,
775
+ slot_id: slotId,
776
+ alias,
777
+ lang: "en",
778
+ msisdn: newMsisdn,
779
+ family_member_id: familyMemberId
780
+ };
781
+ return sendApiRequest(path, payload, idToken, "POST");
782
+ }
783
+ async function removeMember(idToken, familyMemberId) {
784
+ const path = "sharings/api/v8/family-plan/remove-member";
785
+ const payload = {
786
+ is_enterprise: false,
787
+ family_member_id: familyMemberId,
788
+ lang: "en"
789
+ };
790
+ return sendApiRequest(path, payload, idToken, "POST");
791
+ }
792
+ async function setQuotaLimit(idToken, originalAllocation, newAllocation, familyMemberId) {
793
+ const path = "sharings/api/v8/family-plan/allocate-quota";
794
+ const payload = {
795
+ is_enterprise: false,
796
+ member_allocations: [{
797
+ new_text_allocation: 0,
798
+ original_text_allocation: 0,
799
+ original_voice_allocation: 0,
800
+ original_allocation: originalAllocation,
801
+ new_voice_allocation: 0,
802
+ message: "",
803
+ new_allocation: newAllocation,
804
+ family_member_id: familyMemberId,
805
+ status: ""
806
+ }],
807
+ lang: "en"
808
+ };
809
+ return sendApiRequest(path, payload, idToken, "POST");
810
+ }
811
+ // src/notification.ts
812
+ init_utils();
813
+ var exports_notification = {};
814
+ __export(exports_notification, {
815
+ getNotifications: () => getNotifications,
816
+ getNotificationDetail: () => getNotificationDetail
817
+ });
818
+ async function getNotifications(idToken) {
819
+ const path = "api/v8/notification-non-grouping";
820
+ const payload = {
821
+ is_enterprise: false,
822
+ lang: "en"
823
+ };
824
+ return sendApiRequest(path, payload, idToken, "POST");
825
+ }
826
+ async function getNotificationDetail(idToken, notificationId) {
827
+ const path = "api/v8/notification/detail";
828
+ const payload = {
829
+ is_enterprise: false,
830
+ lang: "en",
831
+ notification_id: notificationId
832
+ };
833
+ return sendApiRequest(path, payload, idToken, "POST");
834
+ }
835
+ // src/package.ts
836
+ var exports_package = {};
837
+ __export(exports_package, {
838
+ getPackageByOrderId: () => getPackageByOrderId,
839
+ getPackage: () => getPackage,
840
+ getAddons: () => getAddons
841
+ });
842
+ init_utils();
843
+ async function getPackage({
844
+ idToken,
845
+ packageOptionCode,
846
+ packageFamilyCode = "",
847
+ packageVariantCode = ""
848
+ }) {
849
+ const path = "api/v8/xl-stores/options/detail";
850
+ const payload = {
851
+ is_transaction_routine: false,
852
+ migration_type: "NONE",
853
+ package_family_code: packageFamilyCode,
854
+ family_role_hub: "",
855
+ is_autobuy: false,
856
+ is_enterprise: false,
857
+ is_shareable: false,
858
+ is_migration: false,
859
+ lang: "en",
860
+ package_option_code: packageOptionCode,
861
+ is_upsell_pdp: false,
862
+ package_variant_code: packageVariantCode
863
+ };
864
+ console.log("Fetching package...");
865
+ const response = await sendApiRequest(path, payload, idToken, "POST");
866
+ return response.data;
867
+ }
868
+ async function getPackageByOrderId({
869
+ idToken,
870
+ packageFamilyCode,
871
+ packageVariantCode,
872
+ order,
873
+ isEnterprise,
874
+ migrationType
875
+ }) {
876
+ const xpackages = await getFamily(idToken, packageFamilyCode, isEnterprise, migrationType);
877
+ if (!xpackages) {
878
+ throw new Error("Data tidak ditemukan untuk family code yang diberikan.");
879
+ }
880
+ const findVariant = xpackages.package_variants.find((v) => v.package_variant_code === packageVariantCode);
881
+ if (!findVariant) {
882
+ throw new Error(`Package variant with code ${packageVariantCode} not found in family ${packageFamilyCode}`);
883
+ }
884
+ const findPackageOption = findVariant.package_options.find((x) => x.order === order);
885
+ if (!findPackageOption) {
886
+ throw new Error(`Package option with order ${order} not found in variant ${findVariant.package_variant_code}`);
887
+ }
888
+ const data = await getPackage({
889
+ idToken,
890
+ packageOptionCode: findPackageOption.package_option_code
891
+ });
892
+ data.package_option.package_option_code = findPackageOption.package_option_code;
893
+ return data;
894
+ }
895
+ async function getAddons({
896
+ idToken,
897
+ packageOptionCode
898
+ }) {
899
+ const path = "api/v8/xl-stores/options/addons-pinky-box";
900
+ const rawPayload = {
901
+ is_enterprise: false,
902
+ lang: "en",
903
+ package_option_code: packageOptionCode
904
+ };
905
+ console.log("Fetching addons...");
906
+ const res = await sendApiRequest(path, rawPayload, idToken, "POST");
907
+ if (!("data" in res)) {
908
+ console.log("Error getting addons:", res.error ?? "Unknown error");
909
+ return null;
910
+ }
911
+ return res.data;
912
+ }
913
+ // src/payments/index.ts
914
+ var exports_payments = {};
915
+ __export(exports_payments, {
916
+ settlementQris: () => settlementQris,
917
+ settlementEWallet: () => settlementEWallet,
918
+ settlementBalance: () => settlementBalance,
919
+ EWalletProviderEnum: () => EWalletProviderEnum
920
+ });
921
+
922
+ // src/payments/balance.ts
923
+ init_encrypt();
924
+ init_utils();
925
+ init_config();
926
+ import axios4 from "axios";
927
+ import { v4 as uuidv44 } from "uuid";
928
+ import { DateTime as DateTime4 } from "luxon";
929
+ async function settlementBalance({
930
+ idToken,
931
+ accessToken,
932
+ item,
933
+ items,
934
+ paymentFor,
935
+ tokenConfirmation,
936
+ topup_number = "",
937
+ stage_token = "",
938
+ overwriteAmount = null,
939
+ paymentTargetsMethodsOption
940
+ }) {
941
+ const payment_targets = items.map((item2) => item2.item_code).join(";");
942
+ const [paymentRes, encryptedFields] = await Promise.all([
943
+ sendApiRequest("payments/api/v8/payment-methods-option", {
944
+ payment_type: "PURCHASE",
945
+ is_enterprise: false,
946
+ payment_target: paymentTargetsMethodsOption ?? item.item_code,
947
+ lang: "en",
948
+ is_referral: false,
949
+ token_confirmation: tokenConfirmation
950
+ }, idToken, "POST"),
951
+ Promise.all([
952
+ buildEncryptedField(null, true),
953
+ buildEncryptedField(null, true)
954
+ ])
955
+ ]);
956
+ const { token_payment, timestamp } = paymentRes.data;
957
+ const price = overwriteAmount === 0 ? 0 : item.item_price;
958
+ const [encrypted_payment_token, encrypted_authentication_id] = encryptedFields;
959
+ const settlementPath = "payments/api/v8/settlement-multipayment";
960
+ const sigInput = {
961
+ accessToken,
962
+ timestamp,
963
+ itemCode: item.item_code,
964
+ token_payment,
965
+ payment_method: "BALANCE",
966
+ paymentFor,
967
+ settlementPath
968
+ };
969
+ const settlementPayload = {
970
+ total_discount: 0,
971
+ is_enterprise: false,
972
+ payment_token: "",
973
+ token_payment,
974
+ activated_autobuy_code: "",
975
+ cc_payment_type: "",
976
+ is_myxl_wallet: false,
977
+ pin: "",
978
+ ewallet_promo_id: "",
979
+ members: [],
980
+ total_fee: 0,
981
+ fingerprint: "",
982
+ autobuy_threshold_setting: { label: "", type: "", value: 0 },
983
+ is_use_point: false,
984
+ lang: "en",
985
+ payment_method: "BALANCE",
986
+ timestamp,
987
+ points_gained: 0,
988
+ can_trigger_rating: false,
989
+ akrab_members: [],
990
+ akrab_parent_alias: "",
991
+ referral_unique_code: "",
992
+ coupon: "",
993
+ payment_for: paymentFor,
994
+ with_upsell: false,
995
+ topup_number,
996
+ stage_token,
997
+ authentication_id: "",
998
+ encrypted_payment_token,
999
+ token: "",
1000
+ token_confirmation: "",
1001
+ access_token: accessToken,
1002
+ wallet_number: "",
1003
+ encrypted_authentication_id,
1004
+ additional_data: {
1005
+ original_price: item.item_price,
1006
+ is_spend_limit_temporary: false,
1007
+ migration_type: "",
1008
+ akrab_m2m_group_id: "false",
1009
+ spend_limit_amount: 0,
1010
+ is_spend_limit: false,
1011
+ mission_id: "",
1012
+ tax: 0,
1013
+ quota_bonus: 0,
1014
+ cashtag: "",
1015
+ is_family_plan: false,
1016
+ combo_details: [],
1017
+ is_switch_plan: false,
1018
+ discount_recurring: 0,
1019
+ is_akrab_m2m: false,
1020
+ balance_type: "PREPAID_BALANCE",
1021
+ has_bonus: false,
1022
+ discount_promo: 0
1023
+ },
1024
+ total_amount: price,
1025
+ is_using_autobuy: false,
1026
+ items
1027
+ };
1028
+ const [encrypted, xSig] = await Promise.all([
1029
+ encryptSignXData("POST", settlementPath, idToken, settlementPayload),
1030
+ makeXSignaturePayment(accessToken, timestamp, payment_targets, token_payment, "BALANCE", paymentFor, settlementPath)
1031
+ ]);
1032
+ const xtimeRaw = encrypted.encrypted_body?.xtime;
1033
+ const sigTimeSec = Math.floor(Number(xtimeRaw) / 1000);
1034
+ const apiHost = BASE_API_URL.replace(/^https?:\/\//, "").replace(/\/$/, "");
1035
+ const headers = {
1036
+ host: apiHost,
1037
+ "content-type": "application/json; charset=utf-8",
1038
+ "user-agent": UA,
1039
+ "x-api-key": API_KEY,
1040
+ authorization: `Bearer ${idToken}`,
1041
+ "x-hv": "v3",
1042
+ "x-signature-time": String(sigTimeSec),
1043
+ "x-signature": xSig,
1044
+ "x-request-id": uuidv44(),
1045
+ "x-request-at": javaLikeTimestamp(DateTime4.fromSeconds(sigTimeSec, { zone: "utc" }).setZone("local")),
1046
+ "x-version-app": X_APP_VERSION
1047
+ };
1048
+ const url = `${BASE_API_URL.replace(/\/$/, "")}/${settlementPath}`;
1049
+ const resp = await axios4.post(url, encrypted.encrypted_body, { headers, timeout: 30000 });
1050
+ const { xdata, xtime } = resp.data;
1051
+ const decryptedXData = await decryptXData2(xdata, xtime);
1052
+ return decryptedXData;
1053
+ }
1054
+ // src/payments/ewallet.ts
1055
+ init_encrypt();
1056
+ init_utils();
1057
+ init_config();
1058
+ import axios5 from "axios";
1059
+ import { v4 as uuidv45 } from "uuid";
1060
+ import { DateTime as DateTime5 } from "luxon";
1061
+ var EWalletProviderEnum;
1062
+ ((EWalletProviderEnum2) => {
1063
+ EWalletProviderEnum2["DANA"] = "DANA";
1064
+ EWalletProviderEnum2["ShopeePay"] = "SHOPEEPAY";
1065
+ EWalletProviderEnum2["GoPay"] = "GOPAY";
1066
+ EWalletProviderEnum2["OVO"] = "OVO";
1067
+ })(EWalletProviderEnum ||= {});
1068
+ async function settlementEWallet({
1069
+ idToken,
1070
+ accessToken,
1071
+ item,
1072
+ items,
1073
+ paymentFor,
1074
+ tokenConfirmation,
1075
+ topup_number = "",
1076
+ walletNumber = "",
1077
+ stage_token = "",
1078
+ overwriteAmount = null,
1079
+ paymentTargetsMethodsOption,
1080
+ paymentMethod
1081
+ }) {
1082
+ const payment_targets = items.map((item2) => item2.item_code).join(";");
1083
+ await interceptPage(idToken, item.item_code, false);
1084
+ const paymentRes = await sendApiRequest("payments/api/v8/payment-methods-option", {
1085
+ payment_type: "PURCHASE",
1086
+ is_enterprise: false,
1087
+ payment_target: paymentTargetsMethodsOption ?? item.item_code,
1088
+ lang: "en",
1089
+ is_referral: false,
1090
+ token_confirmation: tokenConfirmation
1091
+ }, idToken, "POST");
1092
+ const { token_payment, timestamp } = paymentRes.data;
1093
+ const price = overwriteAmount === 0 ? 0 : item.item_price;
1094
+ const settlementPath = "payments/api/v8/settlement-multipayment/ewallet";
1095
+ const settlementPayload = {
1096
+ akrab: {
1097
+ akrab_members: [],
1098
+ akrab_parent_alias: "",
1099
+ members: []
1100
+ },
1101
+ can_trigger_rating: false,
1102
+ total_discount: 0,
1103
+ coupon: "",
1104
+ payment_for: paymentFor,
1105
+ topup_number,
1106
+ stage_token,
1107
+ is_enterprise: false,
1108
+ autobuy: {
1109
+ is_using_autobuy: false,
1110
+ activated_autobuy_code: "",
1111
+ autobuy_threshold_setting: {
1112
+ label: "",
1113
+ type: "",
1114
+ value: 0
1115
+ }
1116
+ },
1117
+ access_token: accessToken,
1118
+ is_myxl_wallet: false,
1119
+ wallet_number: walletNumber,
1120
+ additional_data: {},
1121
+ total_amount: price,
1122
+ total_fee: 0,
1123
+ is_use_point: false,
1124
+ lang: "en",
1125
+ items,
1126
+ verification_token: token_payment,
1127
+ payment_method: paymentMethod,
1128
+ timestamp
1129
+ };
1130
+ const encrypted = await encryptSignXData("POST", settlementPath, idToken, settlementPayload);
1131
+ const xtimeRaw = encrypted.encrypted_body?.xtime;
1132
+ const sigTimeSec = Math.floor((typeof xtimeRaw === "string" ? parseInt(xtimeRaw) : Number(xtimeRaw)) / 1000);
1133
+ const xSig = await makeXSignaturePayment(accessToken, timestamp, payment_targets, token_payment, paymentMethod, paymentFor, settlementPath);
1134
+ const headers = {
1135
+ host: BASE_API_URL.replace("https://", ""),
1136
+ "content-type": "application/json; charset=utf-8",
1137
+ "user-agent": UA,
1138
+ "x-api-key": API_KEY,
1139
+ authorization: `Bearer ${idToken}`,
1140
+ "x-hv": "v3",
1141
+ "x-signature-time": String(sigTimeSec),
1142
+ "x-signature": xSig,
1143
+ "x-request-id": uuidv45(),
1144
+ "x-request-at": javaLikeTimestamp(DateTime5.fromSeconds(sigTimeSec, { zone: "utc" }).setZone("local")),
1145
+ "x-version-app": X_APP_VERSION
1146
+ };
1147
+ const url = `${BASE_API_URL}/${settlementPath}`;
1148
+ const resp = await axios5.post(url, encrypted.encrypted_body, { headers, timeout: 30000 });
1149
+ const decryptedXData = await decryptXData2(resp.data.xdata, resp.data.xtime);
1150
+ return decryptedXData;
1151
+ }
1152
+ // src/payments/qris.ts
1153
+ init_encrypt();
1154
+ init_utils();
1155
+ init_config();
1156
+ import axios6 from "axios";
1157
+ import { v4 as uuidv46 } from "uuid";
1158
+ import { DateTime as DateTime6 } from "luxon";
1159
+ async function settlementQris({
1160
+ idToken,
1161
+ accessToken,
1162
+ item,
1163
+ items,
1164
+ paymentFor,
1165
+ tokenConfirmation,
1166
+ topup_number = "",
1167
+ stage_token = "",
1168
+ overwriteAmount = null,
1169
+ paymentTargetsMethodsOption
1170
+ }) {
1171
+ const payment_targets = items.map((item2) => item2.item_code).join(";");
1172
+ await interceptPage(idToken, item.item_code, false);
1173
+ const paymentRes = await sendApiRequest("payments/api/v8/payment-methods-option", {
1174
+ payment_type: "PURCHASE",
1175
+ is_enterprise: false,
1176
+ payment_target: paymentTargetsMethodsOption ?? item.item_code,
1177
+ lang: "en",
1178
+ is_referral: false,
1179
+ token_confirmation: tokenConfirmation
1180
+ }, idToken, "POST");
1181
+ const { token_payment, timestamp } = paymentRes.data;
1182
+ const price = overwriteAmount === 0 ? 0 : item.item_price;
1183
+ const settlementPath = "payments/api/v8/settlement-multipayment/qris";
1184
+ const settlementPayload = {
1185
+ akrab: {
1186
+ akrab_members: [],
1187
+ akrab_parent_alias: "",
1188
+ members: []
1189
+ },
1190
+ can_trigger_rating: false,
1191
+ total_discount: 0,
1192
+ coupon: "",
1193
+ payment_for: paymentFor,
1194
+ topup_number,
1195
+ stage_token,
1196
+ is_enterprise: false,
1197
+ autobuy: {
1198
+ is_using_autobuy: false,
1199
+ activated_autobuy_code: "",
1200
+ autobuy_threshold_setting: {
1201
+ label: "",
1202
+ type: "",
1203
+ value: 0
1204
+ }
1205
+ },
1206
+ access_token: accessToken,
1207
+ is_myxl_wallet: false,
1208
+ additional_data: {
1209
+ original_price: item.item_price,
1210
+ is_spend_limit_temporary: false,
1211
+ migration_type: "",
1212
+ spend_limit_amount: 0,
1213
+ is_spend_limit: false,
1214
+ tax: 0,
1215
+ benefit_type: "",
1216
+ quota_bonus: 0,
1217
+ cashtag: "",
1218
+ is_family_plan: false,
1219
+ combo_details: [],
1220
+ is_switch_plan: false,
1221
+ discount_recurring: 0,
1222
+ has_bonus: false,
1223
+ discount_promo: 0
1224
+ },
1225
+ total_amount: price,
1226
+ total_fee: 0,
1227
+ is_use_point: false,
1228
+ lang: "en",
1229
+ items,
1230
+ verification_token: token_payment,
1231
+ payment_method: "QRIS",
1232
+ timestamp
1233
+ };
1234
+ const encrypted = await encryptSignXData("POST", settlementPath, idToken, settlementPayload);
1235
+ const xtimeRaw = encrypted.encrypted_body?.xtime;
1236
+ const sigTimeSec = Math.floor((typeof xtimeRaw === "string" ? parseInt(xtimeRaw) : Number(xtimeRaw)) / 1000);
1237
+ const xSig = await makeXSignaturePayment(accessToken, timestamp, payment_targets, token_payment, "QRIS", paymentFor, settlementPath);
1238
+ const headers = {
1239
+ host: BASE_API_URL.replace("https://", ""),
1240
+ "content-type": "application/json; charset=utf-8",
1241
+ "user-agent": UA,
1242
+ "x-api-key": API_KEY,
1243
+ authorization: `Bearer ${idToken}`,
1244
+ "x-hv": "v3",
1245
+ "x-signature-time": String(sigTimeSec),
1246
+ "x-signature": xSig,
1247
+ "x-request-id": uuidv46(),
1248
+ "x-request-at": javaLikeTimestamp(DateTime6.fromSeconds(sigTimeSec, { zone: "utc" }).setZone("local")),
1249
+ "x-version-app": X_APP_VERSION
1250
+ };
1251
+ const url = `${BASE_API_URL}/${settlementPath}`;
1252
+ const resp = await axios6.post(url, encrypted.encrypted_body, { headers, timeout: 30000 });
1253
+ const decryptedXData = await decryptXData2(resp.data.xdata, resp.data.xtime);
1254
+ return decryptedXData;
1255
+ }
1256
+ // src/profile.ts
1257
+ init_utils();
1258
+ var exports_profile = {};
1259
+ __export(exports_profile, {
1260
+ getPendingTransaction: () => getPendingTransaction
1261
+ });
1262
+ async function getPendingTransaction(idToken) {
1263
+ const path = "api/v8/profile";
1264
+ const payload = {
1265
+ is_enterprise: false,
1266
+ lang: "en"
1267
+ };
1268
+ const res = await sendApiRequest(path, payload, idToken, "POST");
1269
+ return res.data;
1270
+ }
1271
+ // src/@types/payment.ts
1272
+ var exports_payment = {};
1273
+ __export(exports_payment, {
1274
+ PaymentMethodEnum: () => PaymentMethodEnum
1275
+ });
1276
+ var PaymentMethodEnum;
1277
+ ((PaymentMethodEnum2) => {
1278
+ PaymentMethodEnum2["Pulsa"] = "BALANCE";
1279
+ PaymentMethodEnum2["EWallet"] = "EWALLET";
1280
+ PaymentMethodEnum2["QRIS"] = "QRIS";
1281
+ PaymentMethodEnum2["PulsaDecoy"] = "BALANCE_DECOY";
1282
+ PaymentMethodEnum2["PulsaDecoyV2"] = "BALANCE_DECOY_V2";
1283
+ PaymentMethodEnum2["QRISDecoy"] = "QRIS_DECOY";
1284
+ PaymentMethodEnum2["QRISDecoyV2"] = "QRIS_DECOY_V2";
1285
+ PaymentMethodEnum2["PulsaN"] = "BALANCE_N";
1286
+ })(PaymentMethodEnum ||= {});
1287
+
1288
+ // src/index.ts
1289
+ init_utils();
1290
+
1291
+ // src/verification.ts
1292
+ init_utils();
1293
+ var exports_verification = {};
1294
+ __export(exports_verification, {
1295
+ validatePuk: () => validatePuk,
1296
+ checkDukcapil: () => checkDukcapil
1297
+ });
1298
+ async function validatePuk(msisdn, puk) {
1299
+ const path = "api/v8/infos/validate-puk";
1300
+ const payload = {
1301
+ is_enterprise: false,
1302
+ puk,
1303
+ is_enc: false,
1304
+ msisdn,
1305
+ lang: "en"
1306
+ };
1307
+ return sendApiRequest(path, payload, "", "POST");
1308
+ }
1309
+ async function checkDukcapil(msisdn, kk, nik) {
1310
+ const path = "api/v8/auth/regist/dukcapil";
1311
+ const payload = {
1312
+ msisdn,
1313
+ kk,
1314
+ nik,
1315
+ lang: "en"
1316
+ };
1317
+ return sendApiRequest(path, payload, "", "POST");
1318
+ }
1319
+
1320
+ // src/index.ts
1321
+ init_encrypt_helper();
1322
+
1323
+ // src/lib/payment.ts
1324
+ init_utils();
1325
+ var exports_payment2 = {};
1326
+ __export(exports_payment2, {
1327
+ getTransactionDetail: () => getTransactionDetail
1328
+ });
1329
+ async function getTransactionDetail({
1330
+ idToken,
1331
+ transactionId
1332
+ }) {
1333
+ const path = "payments/api/v8/pending-detail";
1334
+ const payload = {
1335
+ transaction_id: transactionId,
1336
+ is_enterprise: false,
1337
+ lang: "en",
1338
+ status: ""
1339
+ };
1340
+ const res = await sendApiRequest(path, payload, idToken, "POST");
1341
+ return res.data;
1342
+ }
1343
+ // src/lib/decoy.ts
1344
+ var exports_decoy = {};
1345
+ __export(exports_decoy, {
1346
+ getDecoyName: () => getDecoyName,
1347
+ getDecoyData: () => getDecoyData,
1348
+ decoyIsExits: () => decoyIsExits
1349
+ });
1350
+ // src/data/decoys/decoy-default-balance.json
1351
+ var decoy_default_balance_default = {
1352
+ family_name: "XL PASS",
1353
+ family_code: "b0a20d74-0c54-4e3b-8f3f-01e7482e50bf",
1354
+ is_enterprise: true,
1355
+ migration_type: "NONE",
1356
+ variant_code: "719d093f-6f8d-46a4-8390-6a0003a172ea",
1357
+ option_name: "XL PASS 30 days",
1358
+ order: 1,
1359
+ price: 889750
1360
+ };
1361
+ // src/data/decoys/decoy-default-qris.json
1362
+ var decoy_default_qris_default = {
1363
+ family_name: "",
1364
+ family_code: "580c1f94-7dc4-416e-96f6-8faf26567516",
1365
+ is_enterprise: false,
1366
+ migration_type: "NONE",
1367
+ variant_code: "b50f954a-696e-46d0-8700-8e4d38521525",
1368
+ option_name: "",
1369
+ order: 27,
1370
+ price: 1000
1371
+ };
1372
+ // src/data/decoys/decoy-default-qris0.json
1373
+ var decoy_default_qris0_default = {
1374
+ family_name: "Kuota Aplikasi BIZ 2GB",
1375
+ family_code: "c6f2cd72-8b21-420a-b8d5-e0186afe5be6",
1376
+ is_enterprise: true,
1377
+ migration_type: "NONE",
1378
+ variant_code: "b7cf278e-c989-4760-8a26-0a20c1a47a40",
1379
+ option_name: "Vidio 2GB",
1380
+ order: 11,
1381
+ price: 0
1382
+ };
1383
+ // src/data/decoys/decoy-prio-balance.json
1384
+ var decoy_prio_balance_default = {
1385
+ family_name: "PRIO PASS",
1386
+ family_code: "2512b72a-a3cd-4c70-a736-132cf2c1f0c0",
1387
+ is_enterprise: null,
1388
+ migration_type: null,
1389
+ variant_code: "cff298bd-8ec8-4696-b689-12407d36be15",
1390
+ option_name: "PRIO PASS 30 days",
1391
+ order: 1,
1392
+ price: 999000
1393
+ };
1394
+ // src/data/decoys/decoy-prio-qris.json
1395
+ var decoy_prio_qris_default = {
1396
+ family_name: "Conference",
1397
+ family_code: "5dab52d5-6f02-4678-b72f-088396ceb113",
1398
+ is_enterprise: true,
1399
+ migration_type: "PRIOH_TO_PRIO",
1400
+ variant_code: "bf84ad5b-87e9-4769-9bd2-2359535c05e4",
1401
+ option_name: "Conference 2GB",
1402
+ order: 1,
1403
+ price: 2000
1404
+ };
1405
+ // src/data/decoys/decoy-prio-qris0.json
1406
+ var decoy_prio_qris0_default = {
1407
+ family_name: "Conference",
1408
+ family_code: "5dab52d5-6f02-4678-b72f-088396ceb113",
1409
+ is_enterprise: true,
1410
+ migration_type: "PRIOH_TO_PRIO",
1411
+ variant_code: "bf84ad5b-87e9-4769-9bd2-2359535c05e4",
1412
+ option_name: "Conference 2GB",
1413
+ order: 1,
1414
+ price: 2000
1415
+ };
1416
+
1417
+ // src/lib/decoy.ts
1418
+ var needPrioDecoys = ["PRIORITAS", "PRIOHYBRID", "GO"];
1419
+ var getDecoyName = (paymentMethod) => {
1420
+ switch (paymentMethod) {
1421
+ case "BALANCE_DECOY" /* PulsaDecoy */:
1422
+ return "balance";
1423
+ case "BALANCE_DECOY_V2" /* PulsaDecoyV2 */:
1424
+ return "balance";
1425
+ case "QRIS_DECOY" /* QRISDecoy */:
1426
+ return "qris";
1427
+ case "QRIS_DECOY_V2" /* QRISDecoyV2 */:
1428
+ return "qris0";
1429
+ default:
1430
+ return "balance";
1431
+ }
1432
+ };
1433
+ var decoyIsExits = (paymentMethod) => {
1434
+ return [
1435
+ "BALANCE_DECOY" /* PulsaDecoy */,
1436
+ "BALANCE_DECOY_V2" /* PulsaDecoyV2 */,
1437
+ "QRIS_DECOY" /* QRISDecoy */,
1438
+ "QRIS_DECOY_V2" /* QRISDecoyV2 */
1439
+ ].includes(paymentMethod);
1440
+ };
1441
+ var decoyMap = {
1442
+ prio: {
1443
+ balance: decoy_prio_balance_default,
1444
+ qris: decoy_prio_qris_default,
1445
+ qris0: decoy_prio_qris0_default
1446
+ },
1447
+ default: {
1448
+ balance: decoy_default_balance_default,
1449
+ qris: decoy_default_qris_default,
1450
+ qris0: decoy_default_qris0_default
1451
+ }
1452
+ };
1453
+ var getDecoyData = ({
1454
+ subscriptionType,
1455
+ decoy
1456
+ }) => {
1457
+ const isPrio = needPrioDecoys.includes(subscriptionType);
1458
+ const group = isPrio ? "prio" : "default";
1459
+ return decoyMap[group][decoy];
1460
+ };
1461
+ // src/payments/decoy.ts
1462
+ var exports_decoy2 = {};
1463
+ __export(exports_decoy2, {
1464
+ default: () => decoy_default
1465
+ });
1466
+ var decoy_default = undefined;
1467
+ export {
1468
+ exports_verification as Verification,
1469
+ exports_utils as Utils,
1470
+ exports_payment as Types,
1471
+ exports_profile as Profile,
1472
+ exports_decoy2 as PaymentsDecoy,
1473
+ exports_payments as Payments,
1474
+ exports_payment2 as Payment,
1475
+ exports_package as Package,
1476
+ exports_notification as Notification,
1477
+ exports_family_plan as FamilyPlan,
1478
+ exports_family as Family,
1479
+ exports_encrypt_helper as EncryptHelper,
1480
+ exports_encrypt as Encrypt,
1481
+ exports_device as Device,
1482
+ exports_decoy as Decoy,
1483
+ exports_config as Config,
1484
+ exports_client as Client,
1485
+ exports_ciam as Ciam,
1486
+ exports_auth as Auth
1487
+ };