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.
- package/README.md +15 -0
- package/dist/@types/payment.d.ts +10 -0
- package/dist/auth.d.ts +20 -0
- package/dist/auth.js +157 -0
- package/dist/ciam.d.ts +259 -0
- package/dist/ciam.js +351 -0
- package/dist/client.d.ts +56 -0
- package/dist/client.js +276 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.js +70 -0
- package/dist/device.d.ts +23 -0
- package/dist/device.js +107 -0
- package/dist/encrypt.d.ts +37 -0
- package/dist/encrypt.js +259 -0
- package/dist/family-plan.d.ts +28 -0
- package/dist/family-plan.js +325 -0
- package/dist/family.d.ts +146 -0
- package/dist/family.js +365 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +1487 -0
- package/dist/lib/decoy.d.ts +17 -0
- package/dist/lib/decoy.js +117 -0
- package/dist/lib/encrypt-helper.d.ts +71 -0
- package/dist/lib/encrypt-helper.js +166 -0
- package/dist/lib/payment.d.ts +116 -0
- package/dist/lib/payment.js +271 -0
- package/dist/lib/utils.d.ts +15 -0
- package/dist/lib/utils.js +290 -0
- package/dist/notification.d.ts +28 -0
- package/dist/notification.js +275 -0
- package/dist/package.d.ts +259 -0
- package/dist/package.js +387 -0
- package/dist/payments/balance.d.ts +2 -0
- package/dist/payments/balance.js +408 -0
- package/dist/payments/decoy.d.ts +1 -0
- package/dist/payments/decoy.js +6 -0
- package/dist/payments/ewallet.d.ts +11 -0
- package/dist/payments/ewallet.js +373 -0
- package/dist/payments/index.d.ts +3 -0
- package/dist/payments/index.js +632 -0
- package/dist/payments/qris.d.ts +2 -0
- package/dist/payments/qris.js +378 -0
- package/dist/profile.d.ts +1 -0
- package/dist/profile.js +266 -0
- package/dist/verification.d.ts +2 -0
- package/dist/verification.js +279 -0
- package/package.json +116 -0
|
@@ -0,0 +1,632 @@
|
|
|
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/utils.ts
|
|
42
|
+
import axios from "axios";
|
|
43
|
+
import { v4 as uuidv4 } from "uuid";
|
|
44
|
+
import { DateTime } from "luxon";
|
|
45
|
+
function javaLikeTimestamp(dt = DateTime.now()) {
|
|
46
|
+
return dt.toMillis().toString();
|
|
47
|
+
}
|
|
48
|
+
async function sendApiRequest(path, payloadDict, idToken, method = "POST") {
|
|
49
|
+
const encryptedPayload = encryptSignXData(method, path, idToken, payloadDict);
|
|
50
|
+
const xtime = Number(encryptedPayload.encrypted_body.xtime);
|
|
51
|
+
const sigTimeSec = Math.floor(xtime / 1000);
|
|
52
|
+
const body = encryptedPayload.encrypted_body;
|
|
53
|
+
const x_sig = encryptedPayload.x_signature;
|
|
54
|
+
const headers = {
|
|
55
|
+
host: BASE_API_URL.replace(/^https?:\/\//, ""),
|
|
56
|
+
"content-type": "application/json; charset=utf-8",
|
|
57
|
+
"user-agent": UA,
|
|
58
|
+
"x-api-key": API_KEY,
|
|
59
|
+
authorization: `Bearer ${idToken}`,
|
|
60
|
+
"x-hv": "v3",
|
|
61
|
+
"x-signature-time": String(sigTimeSec),
|
|
62
|
+
"x-signature": x_sig,
|
|
63
|
+
"x-request-id": uuidv4(),
|
|
64
|
+
"x-request-at": javaLikeTimestamp(),
|
|
65
|
+
"x-version-app": X_APP_VERSION
|
|
66
|
+
};
|
|
67
|
+
const url = `${BASE_API_URL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
68
|
+
const resp = await axios.post(url, body, {
|
|
69
|
+
headers,
|
|
70
|
+
timeout: 30000
|
|
71
|
+
});
|
|
72
|
+
const respData = resp.data;
|
|
73
|
+
const decryptedXData = await decryptXData(respData.xdata, respData.xtime);
|
|
74
|
+
if (decryptedXData.status === "FAILED") {
|
|
75
|
+
throw new Error(JSON.stringify(decryptedXData));
|
|
76
|
+
}
|
|
77
|
+
return decryptedXData;
|
|
78
|
+
}
|
|
79
|
+
async function interceptPage(idToken, optionCode, isEnterprise = false) {
|
|
80
|
+
const path = "misc/api/v8/utility/intercept-page";
|
|
81
|
+
const rawPayload = {
|
|
82
|
+
is_enterprise: isEnterprise,
|
|
83
|
+
lang: "en",
|
|
84
|
+
package_option_code: optionCode
|
|
85
|
+
};
|
|
86
|
+
console.log("Fetching intercept page...");
|
|
87
|
+
try {
|
|
88
|
+
const res = await sendApiRequest(path, rawPayload, idToken, "POST");
|
|
89
|
+
if ("status" in res) {
|
|
90
|
+
console.log(`Intercept status: ${res["status"]}`);
|
|
91
|
+
} else {
|
|
92
|
+
console.log("Intercept error");
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
console.log("Intercept error", err);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function unseal(getter, fallback) {
|
|
99
|
+
try {
|
|
100
|
+
const hex = getter();
|
|
101
|
+
if (!hex || typeof __SEED__ === "undefined")
|
|
102
|
+
return fallback;
|
|
103
|
+
const seed = Buffer.from(__SEED__, "hex");
|
|
104
|
+
const data = Buffer.from(hex, "hex");
|
|
105
|
+
return Buffer.from(data.map((b, i) => b ^ seed[i % seed.length])).toString("utf8");
|
|
106
|
+
} catch {
|
|
107
|
+
return fallback;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
var init_utils = __esm(() => {
|
|
111
|
+
init_config();
|
|
112
|
+
init_encrypt();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// src/config.ts
|
|
116
|
+
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";
|
|
117
|
+
var init_config = __esm(() => {
|
|
118
|
+
init_utils();
|
|
119
|
+
BASE_API_URL = unseal(() => __E_BASE_API_URL__, "https://api.myxl.xlaxiata.co.id");
|
|
120
|
+
BASE_CIAM_URL = unseal(() => __E_BASE_CIAM_URL__, "https://gede.ciam.xlaxiata.co.id");
|
|
121
|
+
BASIC_AUTH = unseal(() => __E_BASIC_AUTH__, "OWZjOTdlZDEtNmEzMC00OGQ1LTk1MTYtNjBjNTNjZTNhMTM1OllEV21GNExKajlYSUt3UW56eTJlMmxiMHRKUWIyOW8z");
|
|
122
|
+
AX_FP_KEY = unseal(() => __E_AX_FP_KEY__, "18b4d589826af50241177961590e6693");
|
|
123
|
+
UA = unseal(() => __E_UA__, "myXL / 8.9.0(1202); com.android.vending; (samsung; SM-N935F; SDK 33; Android 13)");
|
|
124
|
+
API_KEY = unseal(() => __E_API_KEY__, "vT8tINqHaOxXbGE7eOWAhA==");
|
|
125
|
+
ENCRYPTED_FIELD_KEY = unseal(() => __E_ENCRYPTED_FIELD_KEY__, "5dccbf08920a5527");
|
|
126
|
+
XDATA_KEY = unseal(() => __E_XDATA_KEY__, "5dccbf08920a5527b99e222789c34bb7");
|
|
127
|
+
AX_API_SIG_KEY = unseal(() => __E_AX_API_SIG_KEY__, "18b4d589826af50241177961590e6693");
|
|
128
|
+
X_API_BASE_SECRET = unseal(() => __E_X_API_BASE_SECRET__, "mU1Y4n1vBjf3M7tMnRkFU08mVyUJHed8B5En3EAniu1mXLixeuASmBmKnkyzVziOye7rG5nIekMdthensbQMcOJ6SLnrkGyfXALD7mrBC6vuWv6G01pmD3XlU5rT7Tzx");
|
|
129
|
+
CIRCLE_MSISDN_KEY = unseal(() => __E_CIRCLE_MSISDN_KEY__, "5dccbf08920a5527");
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// src/lib/encrypt-helper.ts
|
|
133
|
+
var exports_encrypt_helper = {};
|
|
134
|
+
__export(exports_encrypt_helper, {
|
|
135
|
+
makeXSignaturePayment: () => makeXSignaturePayment,
|
|
136
|
+
makeXSignatureLoyalty: () => makeXSignatureLoyalty,
|
|
137
|
+
makeXSignatureBountyAllotment: () => makeXSignatureBountyAllotment,
|
|
138
|
+
makeXSignatureBounty: () => makeXSignatureBounty,
|
|
139
|
+
makeXSignatureBasic: () => makeXSignatureBasic,
|
|
140
|
+
makeXSignature: () => makeXSignature,
|
|
141
|
+
makeAxApiSignature: () => makeAxApiSignature,
|
|
142
|
+
encryptXData: () => encryptXData,
|
|
143
|
+
encryptEncryptedField: () => encryptEncryptedField,
|
|
144
|
+
decryptXData: () => decryptXData2,
|
|
145
|
+
decryptEncryptedField: () => decryptEncryptedField
|
|
146
|
+
});
|
|
147
|
+
import crypto from "crypto";
|
|
148
|
+
function pkcs7Pad(buf, blockSize = 16) {
|
|
149
|
+
const pad = blockSize - buf.length % blockSize;
|
|
150
|
+
const padBuf = Buffer.alloc(pad, pad);
|
|
151
|
+
return Buffer.concat([buf, padBuf]);
|
|
152
|
+
}
|
|
153
|
+
function pkcs7Unpad(buf) {
|
|
154
|
+
const pad = buf[buf.length - 1] ?? 16;
|
|
155
|
+
if (pad < 1 || pad > 16)
|
|
156
|
+
throw new Error("Invalid PKCS7 padding");
|
|
157
|
+
return buf.slice(0, buf.length - pad);
|
|
158
|
+
}
|
|
159
|
+
function deriveIv(xtimeMs) {
|
|
160
|
+
const sha = crypto.createHash("sha256").update(String(xtimeMs)).digest("hex");
|
|
161
|
+
return Buffer.from(sha.slice(0, 16), "ascii");
|
|
162
|
+
}
|
|
163
|
+
function urlsafeB64Encode(buf) {
|
|
164
|
+
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_");
|
|
165
|
+
}
|
|
166
|
+
function urlsafeB64Decode(s) {
|
|
167
|
+
const b64 = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
168
|
+
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
169
|
+
return Buffer.from(padded, "base64");
|
|
170
|
+
}
|
|
171
|
+
function encryptXData(plaintext, xtimeMs) {
|
|
172
|
+
const key = Buffer.from(XDATA_KEY, "ascii");
|
|
173
|
+
const iv = deriveIv(xtimeMs);
|
|
174
|
+
const padded = pkcs7Pad(Buffer.from(plaintext, "utf-8"));
|
|
175
|
+
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
|
|
176
|
+
cipher.setAutoPadding(false);
|
|
177
|
+
const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
|
|
178
|
+
return urlsafeB64Encode(ct);
|
|
179
|
+
}
|
|
180
|
+
function decryptXData2(xdata, xtimeMs) {
|
|
181
|
+
const key = Buffer.from(XDATA_KEY, "ascii");
|
|
182
|
+
const iv = deriveIv(xtimeMs);
|
|
183
|
+
const ct = urlsafeB64Decode(xdata);
|
|
184
|
+
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
|
|
185
|
+
decipher.setAutoPadding(false);
|
|
186
|
+
const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
|
|
187
|
+
return pkcs7Unpad(pt).toString("utf-8");
|
|
188
|
+
}
|
|
189
|
+
function makeXSignature(idToken, method, path, sigTimeSec) {
|
|
190
|
+
const keyStr = `${X_API_BASE_SECRET};${idToken};${method};${path};${sigTimeSec}`;
|
|
191
|
+
const msg = `${idToken};${sigTimeSec};`;
|
|
192
|
+
return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
|
|
193
|
+
}
|
|
194
|
+
function makeXSignaturePayment(accessToken, sigTimeSec, packageCode, tokenPayment, paymentMethod, paymentFor, path) {
|
|
195
|
+
const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
|
|
196
|
+
const msg = `${accessToken};${tokenPayment};${sigTimeSec};${paymentFor};${paymentMethod};${packageCode};`;
|
|
197
|
+
return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
|
|
198
|
+
}
|
|
199
|
+
function makeXSignatureBounty(accessToken, sigTimeSec, packageCode, tokenPayment) {
|
|
200
|
+
const path = "api/v8/personalization/bounties-exchange";
|
|
201
|
+
const keyStr = `${X_API_BASE_SECRET};${accessToken};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
|
|
202
|
+
const msg = `${accessToken};${tokenPayment};${sigTimeSec};${packageCode};`;
|
|
203
|
+
return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
|
|
204
|
+
}
|
|
205
|
+
function makeXSignatureLoyalty(sigTimeSec, packageCode, tokenConfirmation, path) {
|
|
206
|
+
const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;POST;${path};${sigTimeSec}`;
|
|
207
|
+
const msg = `${tokenConfirmation};${sigTimeSec};${packageCode};`;
|
|
208
|
+
return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
|
|
209
|
+
}
|
|
210
|
+
function makeXSignatureBountyAllotment(sigTimeSec, packageCode, tokenConfirmation, path, destinationMsisdn) {
|
|
211
|
+
const keyStr = `${X_API_BASE_SECRET};${sigTimeSec}#ae-hei_9Tee6he+Ik3Gais5=;${destinationMsisdn};POST;${path};${sigTimeSec}`;
|
|
212
|
+
const msg = `${tokenConfirmation};${sigTimeSec};${destinationMsisdn};${packageCode};`;
|
|
213
|
+
return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
|
|
214
|
+
}
|
|
215
|
+
function makeXSignatureBasic(method, path, sigTimeSec) {
|
|
216
|
+
const keyStr = `${X_API_BASE_SECRET};${method};${path};${sigTimeSec}`;
|
|
217
|
+
const msg = `${sigTimeSec};en;`;
|
|
218
|
+
return crypto.createHmac("sha512", keyStr).update(msg).digest("hex");
|
|
219
|
+
}
|
|
220
|
+
function makeAxApiSignature(tsForSign, contact, code, contactType) {
|
|
221
|
+
const preimage = `${tsForSign}password${contactType}${contact}${code}openid`;
|
|
222
|
+
const digest = crypto.createHmac("sha256", Buffer.from(AX_API_SIG_KEY, "ascii")).update(preimage).digest();
|
|
223
|
+
return digest.toString("base64");
|
|
224
|
+
}
|
|
225
|
+
function decryptEncryptedField(encryptedB64) {
|
|
226
|
+
const ivAscii = encryptedB64.slice(-16);
|
|
227
|
+
const b64Part = encryptedB64.slice(0, -16);
|
|
228
|
+
const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
|
|
229
|
+
const iv = Buffer.from(ivAscii, "ascii");
|
|
230
|
+
const ct = urlsafeB64Decode(b64Part);
|
|
231
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);
|
|
232
|
+
decipher.setAutoPadding(false);
|
|
233
|
+
const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
|
|
234
|
+
return pkcs7Unpad(pt).toString("utf-8");
|
|
235
|
+
}
|
|
236
|
+
function encryptEncryptedField(plaintext) {
|
|
237
|
+
const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
|
|
238
|
+
const ivHex = crypto.randomBytes(8).toString("hex");
|
|
239
|
+
const iv = Buffer.from(ivHex, "ascii");
|
|
240
|
+
const padded = pkcs7Pad(Buffer.from(plaintext, "utf-8"));
|
|
241
|
+
const cipher = crypto.createCipheriv("aes-128-cbc", key, iv);
|
|
242
|
+
cipher.setAutoPadding(false);
|
|
243
|
+
const ct = Buffer.concat([cipher.update(padded), cipher.final()]);
|
|
244
|
+
return urlsafeB64Encode(ct) + ivHex;
|
|
245
|
+
}
|
|
246
|
+
var init_encrypt_helper = __esm(() => {
|
|
247
|
+
init_config();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// src/encrypt.ts
|
|
251
|
+
import crypto2 from "crypto";
|
|
252
|
+
function encryptSignXData(method, path, idToken, payload) {
|
|
253
|
+
const plainBody = JSON.stringify(payload);
|
|
254
|
+
const xtime = Date.now();
|
|
255
|
+
const xdata = encryptXData(plainBody, xtime);
|
|
256
|
+
const sigTimeSec = Math.floor(xtime / 1000);
|
|
257
|
+
const xSignature = makeXSignature(idToken, method, path, sigTimeSec);
|
|
258
|
+
return {
|
|
259
|
+
x_signature: xSignature,
|
|
260
|
+
encrypted_body: { xdata, xtime }
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
async function decryptXData(xdata, xtimeMs) {
|
|
264
|
+
const { decryptXData: _decrypt } = (init_encrypt_helper(), __toCommonJS(exports_encrypt_helper));
|
|
265
|
+
return JSON.parse(_decrypt(xdata, xtimeMs));
|
|
266
|
+
}
|
|
267
|
+
function randomIvHex16() {
|
|
268
|
+
return crypto2.randomBytes(8).toString("hex");
|
|
269
|
+
}
|
|
270
|
+
function b64(data, urlsafe) {
|
|
271
|
+
const b64str = data.toString("base64");
|
|
272
|
+
if (urlsafe) {
|
|
273
|
+
return b64str.replace(/\+/g, "-").replace(/\//g, "_");
|
|
274
|
+
}
|
|
275
|
+
return b64str;
|
|
276
|
+
}
|
|
277
|
+
function buildEncryptedField(ivHex16 = null, urlsafeB64 = false) {
|
|
278
|
+
const key = Buffer.from(ENCRYPTED_FIELD_KEY, "ascii");
|
|
279
|
+
const ivHex = ivHex16 ?? randomIvHex16();
|
|
280
|
+
const iv = Buffer.from(ivHex, "ascii");
|
|
281
|
+
const pt = Buffer.alloc(16, 16);
|
|
282
|
+
const cipher = crypto2.createCipheriv("aes-128-cbc", key, iv);
|
|
283
|
+
cipher.setAutoPadding(false);
|
|
284
|
+
const ct = Buffer.concat([cipher.update(pt), cipher.final()]);
|
|
285
|
+
return b64(ct, urlsafeB64) + ivHex;
|
|
286
|
+
}
|
|
287
|
+
var init_encrypt = __esm(() => {
|
|
288
|
+
init_config();
|
|
289
|
+
init_encrypt_helper();
|
|
290
|
+
init_encrypt_helper();
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// src/payments/balance.ts
|
|
294
|
+
init_encrypt();
|
|
295
|
+
init_utils();
|
|
296
|
+
init_config();
|
|
297
|
+
import axios2 from "axios";
|
|
298
|
+
import { v4 as uuidv42 } from "uuid";
|
|
299
|
+
import { DateTime as DateTime2 } from "luxon";
|
|
300
|
+
async function settlementBalance({
|
|
301
|
+
idToken,
|
|
302
|
+
accessToken,
|
|
303
|
+
item,
|
|
304
|
+
items,
|
|
305
|
+
paymentFor,
|
|
306
|
+
tokenConfirmation,
|
|
307
|
+
topup_number = "",
|
|
308
|
+
stage_token = "",
|
|
309
|
+
overwriteAmount = null,
|
|
310
|
+
paymentTargetsMethodsOption
|
|
311
|
+
}) {
|
|
312
|
+
const payment_targets = items.map((item2) => item2.item_code).join(";");
|
|
313
|
+
const [paymentRes, encryptedFields] = await Promise.all([
|
|
314
|
+
sendApiRequest("payments/api/v8/payment-methods-option", {
|
|
315
|
+
payment_type: "PURCHASE",
|
|
316
|
+
is_enterprise: false,
|
|
317
|
+
payment_target: paymentTargetsMethodsOption ?? item.item_code,
|
|
318
|
+
lang: "en",
|
|
319
|
+
is_referral: false,
|
|
320
|
+
token_confirmation: tokenConfirmation
|
|
321
|
+
}, idToken, "POST"),
|
|
322
|
+
Promise.all([
|
|
323
|
+
buildEncryptedField(null, true),
|
|
324
|
+
buildEncryptedField(null, true)
|
|
325
|
+
])
|
|
326
|
+
]);
|
|
327
|
+
const { token_payment, timestamp } = paymentRes.data;
|
|
328
|
+
const price = overwriteAmount === 0 ? 0 : item.item_price;
|
|
329
|
+
const [encrypted_payment_token, encrypted_authentication_id] = encryptedFields;
|
|
330
|
+
const settlementPath = "payments/api/v8/settlement-multipayment";
|
|
331
|
+
const sigInput = {
|
|
332
|
+
accessToken,
|
|
333
|
+
timestamp,
|
|
334
|
+
itemCode: item.item_code,
|
|
335
|
+
token_payment,
|
|
336
|
+
payment_method: "BALANCE",
|
|
337
|
+
paymentFor,
|
|
338
|
+
settlementPath
|
|
339
|
+
};
|
|
340
|
+
const settlementPayload = {
|
|
341
|
+
total_discount: 0,
|
|
342
|
+
is_enterprise: false,
|
|
343
|
+
payment_token: "",
|
|
344
|
+
token_payment,
|
|
345
|
+
activated_autobuy_code: "",
|
|
346
|
+
cc_payment_type: "",
|
|
347
|
+
is_myxl_wallet: false,
|
|
348
|
+
pin: "",
|
|
349
|
+
ewallet_promo_id: "",
|
|
350
|
+
members: [],
|
|
351
|
+
total_fee: 0,
|
|
352
|
+
fingerprint: "",
|
|
353
|
+
autobuy_threshold_setting: { label: "", type: "", value: 0 },
|
|
354
|
+
is_use_point: false,
|
|
355
|
+
lang: "en",
|
|
356
|
+
payment_method: "BALANCE",
|
|
357
|
+
timestamp,
|
|
358
|
+
points_gained: 0,
|
|
359
|
+
can_trigger_rating: false,
|
|
360
|
+
akrab_members: [],
|
|
361
|
+
akrab_parent_alias: "",
|
|
362
|
+
referral_unique_code: "",
|
|
363
|
+
coupon: "",
|
|
364
|
+
payment_for: paymentFor,
|
|
365
|
+
with_upsell: false,
|
|
366
|
+
topup_number,
|
|
367
|
+
stage_token,
|
|
368
|
+
authentication_id: "",
|
|
369
|
+
encrypted_payment_token,
|
|
370
|
+
token: "",
|
|
371
|
+
token_confirmation: "",
|
|
372
|
+
access_token: accessToken,
|
|
373
|
+
wallet_number: "",
|
|
374
|
+
encrypted_authentication_id,
|
|
375
|
+
additional_data: {
|
|
376
|
+
original_price: item.item_price,
|
|
377
|
+
is_spend_limit_temporary: false,
|
|
378
|
+
migration_type: "",
|
|
379
|
+
akrab_m2m_group_id: "false",
|
|
380
|
+
spend_limit_amount: 0,
|
|
381
|
+
is_spend_limit: false,
|
|
382
|
+
mission_id: "",
|
|
383
|
+
tax: 0,
|
|
384
|
+
quota_bonus: 0,
|
|
385
|
+
cashtag: "",
|
|
386
|
+
is_family_plan: false,
|
|
387
|
+
combo_details: [],
|
|
388
|
+
is_switch_plan: false,
|
|
389
|
+
discount_recurring: 0,
|
|
390
|
+
is_akrab_m2m: false,
|
|
391
|
+
balance_type: "PREPAID_BALANCE",
|
|
392
|
+
has_bonus: false,
|
|
393
|
+
discount_promo: 0
|
|
394
|
+
},
|
|
395
|
+
total_amount: price,
|
|
396
|
+
is_using_autobuy: false,
|
|
397
|
+
items
|
|
398
|
+
};
|
|
399
|
+
const [encrypted, xSig] = await Promise.all([
|
|
400
|
+
encryptSignXData("POST", settlementPath, idToken, settlementPayload),
|
|
401
|
+
makeXSignaturePayment(accessToken, timestamp, payment_targets, token_payment, "BALANCE", paymentFor, settlementPath)
|
|
402
|
+
]);
|
|
403
|
+
const xtimeRaw = encrypted.encrypted_body?.xtime;
|
|
404
|
+
const sigTimeSec = Math.floor(Number(xtimeRaw) / 1000);
|
|
405
|
+
const apiHost = BASE_API_URL.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
406
|
+
const headers = {
|
|
407
|
+
host: apiHost,
|
|
408
|
+
"content-type": "application/json; charset=utf-8",
|
|
409
|
+
"user-agent": UA,
|
|
410
|
+
"x-api-key": API_KEY,
|
|
411
|
+
authorization: `Bearer ${idToken}`,
|
|
412
|
+
"x-hv": "v3",
|
|
413
|
+
"x-signature-time": String(sigTimeSec),
|
|
414
|
+
"x-signature": xSig,
|
|
415
|
+
"x-request-id": uuidv42(),
|
|
416
|
+
"x-request-at": javaLikeTimestamp(DateTime2.fromSeconds(sigTimeSec, { zone: "utc" }).setZone("local")),
|
|
417
|
+
"x-version-app": X_APP_VERSION
|
|
418
|
+
};
|
|
419
|
+
const url = `${BASE_API_URL.replace(/\/$/, "")}/${settlementPath}`;
|
|
420
|
+
const resp = await axios2.post(url, encrypted.encrypted_body, { headers, timeout: 30000 });
|
|
421
|
+
const { xdata, xtime } = resp.data;
|
|
422
|
+
const decryptedXData = await decryptXData(xdata, xtime);
|
|
423
|
+
return decryptedXData;
|
|
424
|
+
}
|
|
425
|
+
// src/payments/ewallet.ts
|
|
426
|
+
init_encrypt();
|
|
427
|
+
init_utils();
|
|
428
|
+
init_config();
|
|
429
|
+
import axios3 from "axios";
|
|
430
|
+
import { v4 as uuidv43 } from "uuid";
|
|
431
|
+
import { DateTime as DateTime3 } from "luxon";
|
|
432
|
+
var EWalletProviderEnum;
|
|
433
|
+
((EWalletProviderEnum2) => {
|
|
434
|
+
EWalletProviderEnum2["DANA"] = "DANA";
|
|
435
|
+
EWalletProviderEnum2["ShopeePay"] = "SHOPEEPAY";
|
|
436
|
+
EWalletProviderEnum2["GoPay"] = "GOPAY";
|
|
437
|
+
EWalletProviderEnum2["OVO"] = "OVO";
|
|
438
|
+
})(EWalletProviderEnum ||= {});
|
|
439
|
+
async function settlementEWallet({
|
|
440
|
+
idToken,
|
|
441
|
+
accessToken,
|
|
442
|
+
item,
|
|
443
|
+
items,
|
|
444
|
+
paymentFor,
|
|
445
|
+
tokenConfirmation,
|
|
446
|
+
topup_number = "",
|
|
447
|
+
walletNumber = "",
|
|
448
|
+
stage_token = "",
|
|
449
|
+
overwriteAmount = null,
|
|
450
|
+
paymentTargetsMethodsOption,
|
|
451
|
+
paymentMethod
|
|
452
|
+
}) {
|
|
453
|
+
const payment_targets = items.map((item2) => item2.item_code).join(";");
|
|
454
|
+
await interceptPage(idToken, item.item_code, false);
|
|
455
|
+
const paymentRes = await sendApiRequest("payments/api/v8/payment-methods-option", {
|
|
456
|
+
payment_type: "PURCHASE",
|
|
457
|
+
is_enterprise: false,
|
|
458
|
+
payment_target: paymentTargetsMethodsOption ?? item.item_code,
|
|
459
|
+
lang: "en",
|
|
460
|
+
is_referral: false,
|
|
461
|
+
token_confirmation: tokenConfirmation
|
|
462
|
+
}, idToken, "POST");
|
|
463
|
+
const { token_payment, timestamp } = paymentRes.data;
|
|
464
|
+
const price = overwriteAmount === 0 ? 0 : item.item_price;
|
|
465
|
+
const settlementPath = "payments/api/v8/settlement-multipayment/ewallet";
|
|
466
|
+
const settlementPayload = {
|
|
467
|
+
akrab: {
|
|
468
|
+
akrab_members: [],
|
|
469
|
+
akrab_parent_alias: "",
|
|
470
|
+
members: []
|
|
471
|
+
},
|
|
472
|
+
can_trigger_rating: false,
|
|
473
|
+
total_discount: 0,
|
|
474
|
+
coupon: "",
|
|
475
|
+
payment_for: paymentFor,
|
|
476
|
+
topup_number,
|
|
477
|
+
stage_token,
|
|
478
|
+
is_enterprise: false,
|
|
479
|
+
autobuy: {
|
|
480
|
+
is_using_autobuy: false,
|
|
481
|
+
activated_autobuy_code: "",
|
|
482
|
+
autobuy_threshold_setting: {
|
|
483
|
+
label: "",
|
|
484
|
+
type: "",
|
|
485
|
+
value: 0
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
access_token: accessToken,
|
|
489
|
+
is_myxl_wallet: false,
|
|
490
|
+
wallet_number: walletNumber,
|
|
491
|
+
additional_data: {},
|
|
492
|
+
total_amount: price,
|
|
493
|
+
total_fee: 0,
|
|
494
|
+
is_use_point: false,
|
|
495
|
+
lang: "en",
|
|
496
|
+
items,
|
|
497
|
+
verification_token: token_payment,
|
|
498
|
+
payment_method: paymentMethod,
|
|
499
|
+
timestamp
|
|
500
|
+
};
|
|
501
|
+
const encrypted = await encryptSignXData("POST", settlementPath, idToken, settlementPayload);
|
|
502
|
+
const xtimeRaw = encrypted.encrypted_body?.xtime;
|
|
503
|
+
const sigTimeSec = Math.floor((typeof xtimeRaw === "string" ? parseInt(xtimeRaw) : Number(xtimeRaw)) / 1000);
|
|
504
|
+
const xSig = await makeXSignaturePayment(accessToken, timestamp, payment_targets, token_payment, paymentMethod, paymentFor, settlementPath);
|
|
505
|
+
const headers = {
|
|
506
|
+
host: BASE_API_URL.replace("https://", ""),
|
|
507
|
+
"content-type": "application/json; charset=utf-8",
|
|
508
|
+
"user-agent": UA,
|
|
509
|
+
"x-api-key": API_KEY,
|
|
510
|
+
authorization: `Bearer ${idToken}`,
|
|
511
|
+
"x-hv": "v3",
|
|
512
|
+
"x-signature-time": String(sigTimeSec),
|
|
513
|
+
"x-signature": xSig,
|
|
514
|
+
"x-request-id": uuidv43(),
|
|
515
|
+
"x-request-at": javaLikeTimestamp(DateTime3.fromSeconds(sigTimeSec, { zone: "utc" }).setZone("local")),
|
|
516
|
+
"x-version-app": X_APP_VERSION
|
|
517
|
+
};
|
|
518
|
+
const url = `${BASE_API_URL}/${settlementPath}`;
|
|
519
|
+
const resp = await axios3.post(url, encrypted.encrypted_body, { headers, timeout: 30000 });
|
|
520
|
+
const decryptedXData = await decryptXData(resp.data.xdata, resp.data.xtime);
|
|
521
|
+
return decryptedXData;
|
|
522
|
+
}
|
|
523
|
+
// src/payments/qris.ts
|
|
524
|
+
init_encrypt();
|
|
525
|
+
init_utils();
|
|
526
|
+
init_config();
|
|
527
|
+
import axios4 from "axios";
|
|
528
|
+
import { v4 as uuidv44 } from "uuid";
|
|
529
|
+
import { DateTime as DateTime4 } from "luxon";
|
|
530
|
+
async function settlementQris({
|
|
531
|
+
idToken,
|
|
532
|
+
accessToken,
|
|
533
|
+
item,
|
|
534
|
+
items,
|
|
535
|
+
paymentFor,
|
|
536
|
+
tokenConfirmation,
|
|
537
|
+
topup_number = "",
|
|
538
|
+
stage_token = "",
|
|
539
|
+
overwriteAmount = null,
|
|
540
|
+
paymentTargetsMethodsOption
|
|
541
|
+
}) {
|
|
542
|
+
const payment_targets = items.map((item2) => item2.item_code).join(";");
|
|
543
|
+
await interceptPage(idToken, item.item_code, false);
|
|
544
|
+
const paymentRes = await sendApiRequest("payments/api/v8/payment-methods-option", {
|
|
545
|
+
payment_type: "PURCHASE",
|
|
546
|
+
is_enterprise: false,
|
|
547
|
+
payment_target: paymentTargetsMethodsOption ?? item.item_code,
|
|
548
|
+
lang: "en",
|
|
549
|
+
is_referral: false,
|
|
550
|
+
token_confirmation: tokenConfirmation
|
|
551
|
+
}, idToken, "POST");
|
|
552
|
+
const { token_payment, timestamp } = paymentRes.data;
|
|
553
|
+
const price = overwriteAmount === 0 ? 0 : item.item_price;
|
|
554
|
+
const settlementPath = "payments/api/v8/settlement-multipayment/qris";
|
|
555
|
+
const settlementPayload = {
|
|
556
|
+
akrab: {
|
|
557
|
+
akrab_members: [],
|
|
558
|
+
akrab_parent_alias: "",
|
|
559
|
+
members: []
|
|
560
|
+
},
|
|
561
|
+
can_trigger_rating: false,
|
|
562
|
+
total_discount: 0,
|
|
563
|
+
coupon: "",
|
|
564
|
+
payment_for: paymentFor,
|
|
565
|
+
topup_number,
|
|
566
|
+
stage_token,
|
|
567
|
+
is_enterprise: false,
|
|
568
|
+
autobuy: {
|
|
569
|
+
is_using_autobuy: false,
|
|
570
|
+
activated_autobuy_code: "",
|
|
571
|
+
autobuy_threshold_setting: {
|
|
572
|
+
label: "",
|
|
573
|
+
type: "",
|
|
574
|
+
value: 0
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
access_token: accessToken,
|
|
578
|
+
is_myxl_wallet: false,
|
|
579
|
+
additional_data: {
|
|
580
|
+
original_price: item.item_price,
|
|
581
|
+
is_spend_limit_temporary: false,
|
|
582
|
+
migration_type: "",
|
|
583
|
+
spend_limit_amount: 0,
|
|
584
|
+
is_spend_limit: false,
|
|
585
|
+
tax: 0,
|
|
586
|
+
benefit_type: "",
|
|
587
|
+
quota_bonus: 0,
|
|
588
|
+
cashtag: "",
|
|
589
|
+
is_family_plan: false,
|
|
590
|
+
combo_details: [],
|
|
591
|
+
is_switch_plan: false,
|
|
592
|
+
discount_recurring: 0,
|
|
593
|
+
has_bonus: false,
|
|
594
|
+
discount_promo: 0
|
|
595
|
+
},
|
|
596
|
+
total_amount: price,
|
|
597
|
+
total_fee: 0,
|
|
598
|
+
is_use_point: false,
|
|
599
|
+
lang: "en",
|
|
600
|
+
items,
|
|
601
|
+
verification_token: token_payment,
|
|
602
|
+
payment_method: "QRIS",
|
|
603
|
+
timestamp
|
|
604
|
+
};
|
|
605
|
+
const encrypted = await encryptSignXData("POST", settlementPath, idToken, settlementPayload);
|
|
606
|
+
const xtimeRaw = encrypted.encrypted_body?.xtime;
|
|
607
|
+
const sigTimeSec = Math.floor((typeof xtimeRaw === "string" ? parseInt(xtimeRaw) : Number(xtimeRaw)) / 1000);
|
|
608
|
+
const xSig = await makeXSignaturePayment(accessToken, timestamp, payment_targets, token_payment, "QRIS", paymentFor, settlementPath);
|
|
609
|
+
const headers = {
|
|
610
|
+
host: BASE_API_URL.replace("https://", ""),
|
|
611
|
+
"content-type": "application/json; charset=utf-8",
|
|
612
|
+
"user-agent": UA,
|
|
613
|
+
"x-api-key": API_KEY,
|
|
614
|
+
authorization: `Bearer ${idToken}`,
|
|
615
|
+
"x-hv": "v3",
|
|
616
|
+
"x-signature-time": String(sigTimeSec),
|
|
617
|
+
"x-signature": xSig,
|
|
618
|
+
"x-request-id": uuidv44(),
|
|
619
|
+
"x-request-at": javaLikeTimestamp(DateTime4.fromSeconds(sigTimeSec, { zone: "utc" }).setZone("local")),
|
|
620
|
+
"x-version-app": X_APP_VERSION
|
|
621
|
+
};
|
|
622
|
+
const url = `${BASE_API_URL}/${settlementPath}`;
|
|
623
|
+
const resp = await axios4.post(url, encrypted.encrypted_body, { headers, timeout: 30000 });
|
|
624
|
+
const decryptedXData = await decryptXData(resp.data.xdata, resp.data.xtime);
|
|
625
|
+
return decryptedXData;
|
|
626
|
+
}
|
|
627
|
+
export {
|
|
628
|
+
settlementQris,
|
|
629
|
+
settlementEWallet,
|
|
630
|
+
settlementBalance,
|
|
631
|
+
EWalletProviderEnum
|
|
632
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { SettlementProps, SettlementResponse } from "./../lib/payment";
|
|
2
|
+
export declare function settlementQris({ idToken, accessToken, item, items, paymentFor, tokenConfirmation, topup_number, stage_token, overwriteAmount, paymentTargetsMethodsOption, }: SettlementProps): Promise<SettlementResponse>;
|