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
@@ -0,0 +1,387 @@
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/config.ts
42
+ 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, X_APP_VERSION = "8.9.0";
43
+ var init_config = __esm(() => {
44
+ init_utils();
45
+ BASE_API_URL = unseal(() => __E_BASE_API_URL__, "https://api.myxl.xlaxiata.co.id");
46
+ BASE_CIAM_URL = unseal(() => __E_BASE_CIAM_URL__, "https://gede.ciam.xlaxiata.co.id");
47
+ BASIC_AUTH = unseal(() => __E_BASIC_AUTH__, "OWZjOTdlZDEtNmEzMC00OGQ1LTk1MTYtNjBjNTNjZTNhMTM1OllEV21GNExKajlYSUt3UW56eTJlMmxiMHRKUWIyOW8z");
48
+ AX_FP_KEY = unseal(() => __E_AX_FP_KEY__, "18b4d589826af50241177961590e6693");
49
+ UA = unseal(() => __E_UA__, "myXL / 8.9.0(1202); com.android.vending; (samsung; SM-N935F; SDK 33; Android 13)");
50
+ API_KEY = unseal(() => __E_API_KEY__, "vT8tINqHaOxXbGE7eOWAhA==");
51
+ ENCRYPTED_FIELD_KEY = unseal(() => __E_ENCRYPTED_FIELD_KEY__, "5dccbf08920a5527");
52
+ XDATA_KEY = unseal(() => __E_XDATA_KEY__, "5dccbf08920a5527b99e222789c34bb7");
53
+ AX_API_SIG_KEY = unseal(() => __E_AX_API_SIG_KEY__, "18b4d589826af50241177961590e6693");
54
+ X_API_BASE_SECRET = unseal(() => __E_X_API_BASE_SECRET__, "mU1Y4n1vBjf3M7tMnRkFU08mVyUJHed8B5En3EAniu1mXLixeuASmBmKnkyzVziOye7rG5nIekMdthensbQMcOJ6SLnrkGyfXALD7mrBC6vuWv6G01pmD3XlU5rT7Tzx");
55
+ CIRCLE_MSISDN_KEY = unseal(() => __E_CIRCLE_MSISDN_KEY__, "5dccbf08920a5527");
56
+ });
57
+
58
+ // src/lib/encrypt-helper.ts
59
+ var exports_encrypt_helper = {};
60
+ __export(exports_encrypt_helper, {
61
+ makeXSignaturePayment: () => makeXSignaturePayment,
62
+ makeXSignatureLoyalty: () => makeXSignatureLoyalty,
63
+ makeXSignatureBountyAllotment: () => makeXSignatureBountyAllotment,
64
+ makeXSignatureBounty: () => makeXSignatureBounty,
65
+ makeXSignatureBasic: () => makeXSignatureBasic,
66
+ makeXSignature: () => makeXSignature,
67
+ makeAxApiSignature: () => makeAxApiSignature,
68
+ encryptXData: () => encryptXData,
69
+ encryptEncryptedField: () => encryptEncryptedField,
70
+ decryptXData: () => decryptXData,
71
+ decryptEncryptedField: () => decryptEncryptedField
72
+ });
73
+ import crypto from "crypto";
74
+ function pkcs7Pad(buf, blockSize = 16) {
75
+ const pad = blockSize - buf.length % blockSize;
76
+ const padBuf = Buffer.alloc(pad, pad);
77
+ return Buffer.concat([buf, padBuf]);
78
+ }
79
+ function pkcs7Unpad(buf) {
80
+ const pad = buf[buf.length - 1] ?? 16;
81
+ if (pad < 1 || pad > 16)
82
+ throw new Error("Invalid PKCS7 padding");
83
+ return buf.slice(0, buf.length - pad);
84
+ }
85
+ function deriveIv(xtimeMs) {
86
+ const sha = crypto.createHash("sha256").update(String(xtimeMs)).digest("hex");
87
+ return Buffer.from(sha.slice(0, 16), "ascii");
88
+ }
89
+ function urlsafeB64Encode(buf) {
90
+ return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_");
91
+ }
92
+ function urlsafeB64Decode(s) {
93
+ const b64 = s.replace(/-/g, "+").replace(/_/g, "/");
94
+ const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
95
+ return Buffer.from(padded, "base64");
96
+ }
97
+ function encryptXData(plaintext, xtimeMs) {
98
+ const key = Buffer.from(XDATA_KEY, "ascii");
99
+ const iv = deriveIv(xtimeMs);
100
+ const padded = pkcs7Pad(Buffer.from(plaintext, "utf-8"));
101
+ const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
102
+ cipher.setAutoPadding(false);
103
+ const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
104
+ return urlsafeB64Encode(ct);
105
+ }
106
+ function decryptXData(xdata, xtimeMs) {
107
+ const key = Buffer.from(XDATA_KEY, "ascii");
108
+ const iv = deriveIv(xtimeMs);
109
+ const ct = urlsafeB64Decode(xdata);
110
+ const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
111
+ decipher.setAutoPadding(false);
112
+ const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
113
+ return pkcs7Unpad(pt).toString("utf-8");
114
+ }
115
+ function makeXSignature(idToken, method, path, sigTimeSec) {
116
+ const keyStr = `${X_API_BASE_SECRET};${idToken};${method};${path};${sigTimeSec}`;
117
+ const msg = `${idToken};${sigTimeSec};`;
118
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
119
+ }
120
+ function makeXSignaturePayment(accessToken, sigTimeSec, packageCode, tokenPayment, paymentMethod, paymentFor, path) {
121
+ const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
122
+ const msg = `${accessToken};${tokenPayment};${sigTimeSec};${paymentFor};${paymentMethod};${packageCode};`;
123
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
124
+ }
125
+ function makeXSignatureBounty(accessToken, sigTimeSec, packageCode, tokenPayment) {
126
+ const path = "api/v8/personalization/bounties-exchange";
127
+ const keyStr = `${X_API_BASE_SECRET};${accessToken};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
128
+ const msg = `${accessToken};${tokenPayment};${sigTimeSec};${packageCode};`;
129
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
130
+ }
131
+ function makeXSignatureLoyalty(sigTimeSec, packageCode, tokenConfirmation, path) {
132
+ const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
133
+ const msg = `${tokenConfirmation};${sigTimeSec};${packageCode};`;
134
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
135
+ }
136
+ function makeXSignatureBountyAllotment(sigTimeSec, packageCode, tokenConfirmation, path, destinationMsisdn) {
137
+ const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;${destinationMsisdn};POST;${path};${sigTimeSec}`;
138
+ const msg = `${tokenConfirmation};${sigTimeSec};${destinationMsisdn};${packageCode};`;
139
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
140
+ }
141
+ function makeXSignatureBasic(method, path, sigTimeSec) {
142
+ const keyStr = `${X_API_BASE_SECRET};${method};${path};${sigTimeSec}`;
143
+ const msg = `${sigTimeSec};en;`;
144
+ return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
145
+ }
146
+ function makeAxApiSignature(tsForSign, contact, code, contactType) {
147
+ const preimage = `${tsForSign}password${contactType}${contact}${code}openid`;
148
+ const digest = crypto.createHmac("sha256", Buffer.from(AX_API_SIG_KEY, "ascii")).update(preimage).digest();
149
+ return digest.toString("base64");
150
+ }
151
+ function decryptEncryptedField(encryptedB64) {
152
+ const ivAscii = encryptedB64.slice(-16);
153
+ const b64Part = encryptedB64.slice(0, -16);
154
+ const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
155
+ const iv = Buffer.from(ivAscii, "ascii");
156
+ const ct = urlsafeB64Decode(b64Part);
157
+ const decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);
158
+ decipher.setAutoPadding(false);
159
+ const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
160
+ return pkcs7Unpad(pt).toString("utf-8");
161
+ }
162
+ function encryptEncryptedField(plaintext) {
163
+ const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
164
+ const ivHex = crypto.randomBytes(8).toString("hex");
165
+ const iv = Buffer.from(ivHex, "ascii");
166
+ const padded = pkcs7Pad(Buffer.from(plaintext, "utf-8"));
167
+ const cipher = crypto.createCipheriv("aes-128-cbc", key, iv);
168
+ cipher.setAutoPadding(false);
169
+ const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
170
+ return urlsafeB64Encode(ct) + ivHex;
171
+ }
172
+ var init_encrypt_helper = __esm(() => {
173
+ init_config();
174
+ });
175
+
176
+ // src/encrypt.ts
177
+ function encryptSignXData(method, path, idToken, payload) {
178
+ const plainBody = JSON.stringify(payload);
179
+ const xtime = Date.now();
180
+ const xdata = encryptXData(plainBody, xtime);
181
+ const sigTimeSec = Math.floor(xtime / 1000);
182
+ const xSignature = makeXSignature(idToken, method, path, sigTimeSec);
183
+ return {
184
+ x_signature: xSignature,
185
+ encrypted_body: { xdata, xtime }
186
+ };
187
+ }
188
+ async function decryptXData2(xdata, xtimeMs) {
189
+ const { decryptXData: _decrypt } = (init_encrypt_helper(), __toCommonJS(exports_encrypt_helper));
190
+ return JSON.parse(_decrypt(xdata, xtimeMs));
191
+ }
192
+ var init_encrypt = __esm(() => {
193
+ init_config();
194
+ init_encrypt_helper();
195
+ init_encrypt_helper();
196
+ });
197
+
198
+ // src/lib/utils.ts
199
+ import axios from "axios";
200
+ import { v4 as uuidv4 } from "uuid";
201
+ import { DateTime } from "luxon";
202
+ function javaLikeTimestamp(dt = DateTime.now()) {
203
+ return dt.toMillis().toString();
204
+ }
205
+ async function sendApiRequest(path, payloadDict, idToken, method = "POST") {
206
+ const encryptedPayload = encryptSignXData(method, path, idToken, payloadDict);
207
+ const xtime = Number(encryptedPayload.encrypted_body.xtime);
208
+ const sigTimeSec = Math.floor(xtime / 1000);
209
+ const body = encryptedPayload.encrypted_body;
210
+ const x_sig = encryptedPayload.x_signature;
211
+ const headers = {
212
+ host: BASE_API_URL.replace(/^https?:\/\//, ""),
213
+ "content-type": "application/json; charset=utf-8",
214
+ "user-agent": UA,
215
+ "x-api-key": API_KEY,
216
+ authorization: `Bearer ${idToken}`,
217
+ "x-hv": "v3",
218
+ "x-signature-time": String(sigTimeSec),
219
+ "x-signature": x_sig,
220
+ "x-request-id": uuidv4(),
221
+ "x-request-at": javaLikeTimestamp(),
222
+ "x-version-app": X_APP_VERSION
223
+ };
224
+ const url = `${BASE_API_URL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
225
+ const resp = await axios.post(url, body, {
226
+ headers,
227
+ timeout: 30000
228
+ });
229
+ const respData = resp.data;
230
+ const decryptedXData = await decryptXData2(respData.xdata, respData.xtime);
231
+ if (decryptedXData.status === "FAILED") {
232
+ throw new Error(JSON.stringify(decryptedXData));
233
+ }
234
+ return decryptedXData;
235
+ }
236
+ function unseal(getter, fallback) {
237
+ try {
238
+ const hex = getter();
239
+ if (!hex || typeof __SEED__ === "undefined")
240
+ return fallback;
241
+ const seed = Buffer.from(__SEED__, "hex");
242
+ const data = Buffer.from(hex, "hex");
243
+ return Buffer.from(data.map((b, i) => b ^ seed[i % seed.length])).toString("utf8");
244
+ } catch {
245
+ return fallback;
246
+ }
247
+ }
248
+ var init_utils = __esm(() => {
249
+ init_config();
250
+ init_encrypt();
251
+ });
252
+
253
+ // src/family.ts
254
+ init_utils();
255
+ async function getFamily(idToken, familyCode, isEnterprise, migrationType) {
256
+ let isEnterpriseList = [false, true];
257
+ let migrationTypeList = [
258
+ "NONE",
259
+ "PRE_TO_PRIOH",
260
+ "PRIOH_TO_PRIO",
261
+ "PRIO_TO_PRIOH"
262
+ ];
263
+ if (typeof isEnterprise !== "undefined") {
264
+ isEnterpriseList = [isEnterprise];
265
+ }
266
+ if (typeof migrationType !== "undefined") {
267
+ migrationTypeList = [migrationType];
268
+ }
269
+ const path = "api/v8/xl-stores/options/list";
270
+ const comboList = [];
271
+ for (const mt of migrationTypeList) {
272
+ for (const ie of isEnterpriseList) {
273
+ comboList.push({ ie, mt });
274
+ }
275
+ }
276
+ const requests = comboList.map(({ ie, mt }) => {
277
+ const payloadDict = {
278
+ is_show_tagging_tab: true,
279
+ is_dedicated_event: true,
280
+ is_transaction_routine: false,
281
+ migration_type: mt,
282
+ package_family_code: familyCode,
283
+ is_autobuy: false,
284
+ is_enterprise: ie,
285
+ is_pdlp: true,
286
+ referral_code: "",
287
+ is_migration: false,
288
+ lang: "en"
289
+ };
290
+ return sendApiRequest(path, payloadDict, idToken, "POST").then((res) => ({
291
+ res,
292
+ ie,
293
+ mt
294
+ })).catch((e) => {
295
+ return { res: null, ie, mt, error: e };
296
+ });
297
+ });
298
+ const results = await Promise.all(requests);
299
+ for (const { res, ie, mt } of results) {
300
+ if (res && res["status"] === "SUCCESS") {
301
+ const familyName = res.data?.package_family?.name ?? "";
302
+ if (familyName !== "") {
303
+ console.log(`Success with is_enterprise=${ie}, migration_type=${mt}. Family name: ${familyName}`);
304
+ return res.data;
305
+ }
306
+ }
307
+ }
308
+ return null;
309
+ }
310
+
311
+ // src/package.ts
312
+ init_utils();
313
+ async function getPackage({
314
+ idToken,
315
+ packageOptionCode,
316
+ packageFamilyCode = "",
317
+ packageVariantCode = ""
318
+ }) {
319
+ const path = "api/v8/xl-stores/options/detail";
320
+ const payload = {
321
+ is_transaction_routine: false,
322
+ migration_type: "NONE",
323
+ package_family_code: packageFamilyCode,
324
+ family_role_hub: "",
325
+ is_autobuy: false,
326
+ is_enterprise: false,
327
+ is_shareable: false,
328
+ is_migration: false,
329
+ lang: "en",
330
+ package_option_code: packageOptionCode,
331
+ is_upsell_pdp: false,
332
+ package_variant_code: packageVariantCode
333
+ };
334
+ console.log("Fetching package...");
335
+ const response = await sendApiRequest(path, payload, idToken, "POST");
336
+ return response.data;
337
+ }
338
+ async function getPackageByOrderId({
339
+ idToken,
340
+ packageFamilyCode,
341
+ packageVariantCode,
342
+ order,
343
+ isEnterprise,
344
+ migrationType
345
+ }) {
346
+ const xpackages = await getFamily(idToken, packageFamilyCode, isEnterprise, migrationType);
347
+ if (!xpackages) {
348
+ throw new Error("Data tidak ditemukan untuk family code yang diberikan.");
349
+ }
350
+ const findVariant = xpackages.package_variants.find((v) => v.package_variant_code === packageVariantCode);
351
+ if (!findVariant) {
352
+ throw new Error(`Package variant with code ${packageVariantCode} not found in family ${packageFamilyCode}`);
353
+ }
354
+ const findPackageOption = findVariant.package_options.find((x) => x.order === order);
355
+ if (!findPackageOption) {
356
+ throw new Error(`Package option with order ${order} not found in variant ${findVariant.package_variant_code}`);
357
+ }
358
+ const data = await getPackage({
359
+ idToken,
360
+ packageOptionCode: findPackageOption.package_option_code
361
+ });
362
+ data.package_option.package_option_code = findPackageOption.package_option_code;
363
+ return data;
364
+ }
365
+ async function getAddons({
366
+ idToken,
367
+ packageOptionCode
368
+ }) {
369
+ const path = "api/v8/xl-stores/options/addons-pinky-box";
370
+ const rawPayload = {
371
+ is_enterprise: false,
372
+ lang: "en",
373
+ package_option_code: packageOptionCode
374
+ };
375
+ console.log("Fetching addons...");
376
+ const res = await sendApiRequest(path, rawPayload, idToken, "POST");
377
+ if (!("data" in res)) {
378
+ console.log("Error getting addons:", res.error ?? "Unknown error");
379
+ return null;
380
+ }
381
+ return res.data;
382
+ }
383
+ export {
384
+ getPackageByOrderId,
385
+ getPackage,
386
+ getAddons
387
+ };
@@ -0,0 +1,2 @@
1
+ import type { SettlementProps, SettlementResponse } from "./../lib/payment";
2
+ export declare function settlementBalance({ idToken, accessToken, item, items, paymentFor, tokenConfirmation, topup_number, stage_token, overwriteAmount, paymentTargetsMethodsOption, }: SettlementProps): Promise<SettlementResponse>;