LOADING
Script Node.js untuk mengubah QRIS Statis menjadi QRIS Dinamis + generate QR Code PNG
// main.js
import QRCode from 'qrcode';
class Parser {
constructor() {
this.qris = "";
}
parseQris(qris, amount) {
const amountLength = amount.length;
const tag54 = `54${String(amountLength).padStart(2, "0")}${amount}`;
qris = this.removeTag54(qris);
const tag63Position = qris.indexOf("6304");
if (tag63Position === -1) throw new Error("tag 63 not found");
const modifiedPayload =
qris.slice(0, tag63Position) + tag54 + qris.slice(tag63Position);
const payloadWithoutCrc = modifiedPayload.slice(0, -4);
const newCrc = this.calculateCrc(payloadWithoutCrc);
this.qris = `${payloadWithoutCrc}${newCrc}`;
return this.qris;
}
removeTag54(qris) {
let position = 0;
let result = "";
while (position < qris.length) {
if (position + 2 > qris.length) throw new Error("invalid qris");
const tag = qris.substring(position, position + 2);
position += 2;
if (position + 2 > qris.length) throw new Error("invalid qris");
const lengthStr = qris.substring(position, position + 2);
const length = parseInt(lengthStr, 10);
if (Number.isNaN(length)) throw new Error("invalid qris");
position += 2;
if (position + length > qris.length) throw new Error("invalid qris");
const value = qris.substring(position, position + length);
position += length;
if (tag !== "54") result += tag + String(length).padStart(2, "0") + value;
}
return result;
}
calculateCrc(payload) {
let crc = 0xffff;
const polynomial = 0x1021;
for (let i = 0; i < payload.length; i++) {
crc ^= payload.charCodeAt(i) << 8;
for (let j = 0; j < 8; j++) {
crc = (crc & 0x8000) ? ((crc << 1) ^ polynomial) & 0xffff : (crc << 1) & 0xffff;
}
}
return crc.toString(16).toUpperCase().padStart(4, "0");
}
}
// — pakai di sini —
const parser = new Parser();
const result = parser.parseQris(
"PASTE_QRIS_STATIS_DISINI", // ganti dengan QRIS statis
"50000" // ganti dengan nominal (contoh: 50000 = Rp 50.000)
);
// Simpan sebagai file PNG
await QRCode.toFile('qris-dinamis.png', result, {
errorCorrectionLevel: 'M',
width: 512,
margin: 2
});
console.log('QR saved: qris-dinamis.png');Script sederhana untuk mengubah QRIS Statis menjadi QRIS Dinamis dengan menambahkan nominal pembayaran (tag 54) dan menghitung ulang CRC agar valid.
Hasilnya bisa langsung di-generate menjadi file PNG QR Code yang siap discan.
Ada beberapa cara untuk mendapatkan string dari gambar QRIS:
000201...)Catatan: Cropping tidak selalu wajib, tapi sangat membantu jika gambar ramai atau QR code kecil.
qrcodebashnpm install qrcode
main.jsjsconst result = parser.parseQris( "PASTE_QRIS_STATIS_DISINI", // ganti dengan string QRIS statis "50000" // ganti dengan nominal (contoh: 50000 = Rp 50.000) );
bashnode qris.js
qris-dinamis.pngjsimport QRCode from 'qrcode'; class Parser { constructor() { this.qris = ""; } parseQris(qris, amount) { const amountLength = amount.length; const tag54 = `54${String(amountLength).padStart(2, "0")}${amount}`; qris = this.removeTag54(qris); const tag63Position = qris.indexOf("6304"); if (tag63Position === -1) throw new Error("tag 63 not found"); const modifiedPayload = qris.slice(0, tag63Position) + tag54 + qris.slice(tag63Position); const payloadWithoutCrc = modifiedPayload.slice(0, -4); const newCrc = this.calculateCrc(payloadWithoutCrc); this.qris = `${payloadWithoutCrc}${newCrc}`; return this.qris; } removeTag54(qris) { let position = 0; let result = ""; while (position < qris.length) { if (position + 2 > qris.length) throw new Error("invalid qris"); const tag = qris.substring(position, position + 2); position += 2; if (position + 2 > qris.length) throw new Error("invalid qris"); const lengthStr = qris.substring(position, position + 2); const length = parseInt(lengthStr, 10); if (Number.isNaN(length)) throw new Error("invalid qris"); position += 2; if (position + length > qris.length) throw new Error("invalid qris"); const value = qris.substring(position, position + length); position += length; if (tag !== "54") result += tag + String(length).padStart(2, "0") + value; } return result; } calculateCrc(payload) { let crc = 0xffff; const polynomial = 0x1021; for (let i = 0; i < payload.length; i++) { crc ^= payload.charCodeAt(i) << 8; for (let j = 0; j < 8; j++) { crc = (crc & 0x8000) ? ((crc << 1) ^ polynomial) & 0xffff : (crc << 1) & 0xffff; } } return crc.toString(16).toUpperCase().padStart(4, "0"); } } // — Penggunaan — const parser = new Parser(); const result = parser.parseQris( "00020101021126570011ID.DANA.WWW011893600915303337173302090333717330303UMI51440014ID.CO.QRIS.WWW0215ID10265523166670303UMI5204573253033605802ID5910Shan Store6014Kota Pekanbaru6105282666304D061", "1" ); // Simpan sebagai file PNG await QRCode.toFile('qris-dinamis.png', result, { errorCorrectionLevel: 'M', width: 512, margin: 2 }); console.log('QR saved: qris-dinamis.png'); console.log('QRIS Dinamis:', result);
Setelah dijalankan, kamu akan mendapat:
qris-dinamis.png → QR Code siap discan"10000", "2500", "1")01 dari 11 (statis) menjadi 12 (dinamis). Untuk kebanyakan e-wallet sudah cukup berfungsi.├── qris.js # Script utama ├── package.json # (opsional) └── README.md # Dokumentasi ini
Bebas digunakan untuk keperluan pribadi maupun pembelajaran.