orkuthidebot
Version:
Library Orkut Hide Bot: fungsi QRIS, OTP, dan mutasi transaksi
99 lines (81 loc) • 3.51 kB
JavaScript
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const base64 = require('base-64');
const { exec } = require('child_process');
async function generateQrisImage(auth_username, auth_token, merchant, nominal) {
const redirectTarget = "https://app.orderkuota.com/digital_app/qris";
const encodedRedirect = base64.encode(redirectTarget);
const loginUrl = "https://app.orderkuota.com/api/v2/autologin";
const params = { auth_username, auth_token, redirect: encodedRedirect };
const headers = {
'User-Agent': "WebView",
'Accept': "*/*",
'Accept-Encoding': "gzip, deflate",
'x-requested-with': "com.orderkuota.app",
'accept-language': "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7"
};
// Step 1: Autologin → ambil cookie
const loginResponse = await axios.get(loginUrl, {
params,
headers,
maxRedirects: 0,
validateStatus: status => status === 302
});
const rawCookie = loginResponse.headers['set-cookie']?.join(', ') || '';
const cookieMatches = [...rawCookie.matchAll(/\b[\w_]+=.*?(?=,\s\w+=|$)/g)];
const cookieHeader = cookieMatches.map(m => m[0]).join('; ');
// Step 2: Redirect ke QRIS → dapat Referer
const qrisRedirect = await axios.get(redirectTarget, {
params,
headers: { ...headers, Cookie: cookieHeader },
maxRedirects: 0,
validateStatus: status => status === 302
});
const referer = qrisRedirect.headers['location'];
// Step 3: Get PNG image
const imageResponse = await axios.get("https://kasir.orderkuota.com/qris/curl/create_qris_image.php", {
params: { merchant, nominal },
headers: {
...headers,
'Accept': "image/*,*/*",
'Referer': referer,
'sec-fetch-site': "same-origin",
'sec-fetch-mode': "no-cors",
'sec-fetch-dest': "image"
},
responseType: 'arraybuffer'
});
const timestamp = Date.now();
const fileName = `qris_${merchant}_${timestamp}.png`;
// 🛠️ Simpan di folder yang stabil, jangan dalam node_modules
const publicDir = path.join(__dirname, '../../public');
if (!fs.existsSync(publicDir)) {
fs.mkdirSync(publicDir, { recursive: true });
}
const filePath = path.join(publicDir, fileName);
// ✅ TULIS file PNG secara benar
fs.writeFileSync(filePath, Buffer.from(imageResponse.data));
console.log(`✅ File QRIS disimpan: ${filePath}`);
console.log(`📏 Ukuran PNG (bytes): ${imageResponse.data.length}`);
// Step 4: Hapus otomatis setelah 1 jam
setTimeout(() => {
fs.unlink(filePath, (err) => {
if (err) console.error("❌ Gagal hapus QRIS:", err.message);
else console.log("🗑️ QRIS otomatis dihapus:", fileName);
});
}, 60 * 60 * 1000); // 1 hour
// Step 5: Decode PNG → QR string menggunakan zbarimg
const qr_string = await new Promise((resolve, reject) => {
exec(`zbarimg --raw "${filePath}"`, (error, stdout, stderr) => {
if (error) {
console.error("❌ ZBar decode error:", stderr || error.message);
return reject(new Error("QR decode with zbarimg failed"));
}
console.log("✅ QR berhasil didecode dengan zbarimg");
resolve(stdout.trim());
});
});
return { fileName, qr_string };
}
module.exports = { generateQrisImage };