# QRIS Statis ke Dinamis 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. --- ## Fitur - Menghapus tag 54 lama (jika ada) - Menambahkan nominal baru sesuai input - Menghitung ulang CRC-16 (standar EMVCo/QRIS) - Generate file PNG QR Code otomatis --- ## Cara Mendapatkan String QRIS Statis Ada beberapa cara untuk mendapatkan string dari gambar QRIS: ### 1. Menggunakan Aplikasi Scanner (Paling Mudah) 1. Buka aplikasi seperti **Google Lens**, **QR & Barcode Scanner**, atau kamera bawaan HP 2. Arahkan ke QRIS yang ingin diubah 3. Salin teks hasil scan (biasanya diawali `000201...`) ### 2. Menggunakan Website Online - Buka [https://zxing.org/w/decode](https://zxing.org/w/decode) atau [https://webqr.com](https://webqr.com) - Upload gambar QRIS - Salin hasil string yang muncul ### 3. Tips agar Hasil Scan Lebih Akurat - Crop gambar supaya **hanya QR code yang terlihat** (sedikit margin aman) - Pastikan gambar tidak blur dan kontras bagus - Hindari pantulan cahaya atau bayangan > **Catatan:** Cropping tidak selalu wajib, tapi sangat membantu jika gambar ramai atau QR code kecil. --- ## Persyaratan - Node.js (versi 16 ke atas disarankan) - Library `qrcode` --- ## Cara Install ```bash npm install qrcode ``` --- ## Cara Pakai 1. Buka file `main.js` 2. Ganti string QRIS dan nominal: ```js const result = parser.parseQris( "PASTE_QRIS_STATIS_DISINI", // ganti dengan string QRIS statis "50000" // ganti dengan nominal (contoh: 50000 = Rp 50.000) ); ``` 3. Jalankan script: ```bash node qris.js ``` 4. Hasilnya akan tersimpan sebagai file **`qris-dinamis.png`** --- ## Contoh Penggunaan ```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"); } } // — 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); ``` --- ## Output Setelah dijalankan, kamu akan mendapat: - File `qris-dinamis.png` → QR Code siap discan - String QRIS dinamis di console --- ## Catatan Penting - Nominal harus berupa **string angka** (contoh: `"10000"`, `"2500"`, `"1"`) - Script ini **tidak mengubah** tag `01` dari `11` (statis) menjadi `12` (dinamis). Untuk kebanyakan e-wallet sudah cukup berfungsi. - Pastikan QRIS statis yang dimasukkan valid. - Hasil QRIS dinamis hanya berlaku untuk nominal yang ditentukan. - Script ini hanya manipulasi string lokal, tidak terhubung ke server Bank Indonesia atau payment gateway. --- ## Struktur File ``` ├── qris.js # Script utama ├── package.json # (opsional) └── README.md # Dokumentasi ini ``` --- ## Lisensi Bebas digunakan untuk keperluan pribadi maupun pembelajaran.