# Implementasi QRIS Payment ## Overview QRIS (Quick Response Code Indonesian Standard) telah ditambahkan sebagai metode pembayaran dengan ketentuan: - **Hanya untuk transaksi di bawah Rp 70.000** - **Tidak menggunakan kode unik** (beda dengan BRI/Manual) - **Auto approve** setelah payment verified ## Flow Pembayaran QRIS ``` 1. User Request Payment (payment_method = 'qris') → Validasi: total < 70.000 → Generate QRIS QR Code via API → Store: qris_qr_code, qris_invoiceid, qris_nmid → Status: DIBUAT 2. User Scan & Pay → User scan QR code dengan e-wallet → Payment processed by QRIS provider 3. User Check Status (POST /timo/cek_status_qris) → Call QRIS API checkStatus → Jika paid → Auto approve ke PDAM → Kirim WhatsApp notifikasi ke user → Status: DIBAYAR ``` ## Endpoint Baru ### POST /timo/cek_status_qris **Request:** ```json { "token": "user_token", "no_sl": "059912" } ``` **Response (Pending):** ```json { "status": 200, "pesan": "Menunggu pembayaran", "data": { "status": "pending", "check_count": 1, "message": "Silahkan scan QR code dan lakukan pembayaran" } } ``` **Response (Paid):** ```json { "status": 200, "pesan": "Pembayaran berhasil", "data": { "status": "paid", "message": "Pembayaran QRIS berhasil diverifikasi" } } ``` ## Update request_pembayaran Endpoint `/timo/request_pembayaran` sekarang support parameter `payment_method`: **Request:** ```json { "token": "user_token", "no_sl": "059912", "nama_bank": "QRIS", // atau "Bank BRI" untuk transfer "no_rek": "", "payment_method": "qris" // atau "transfer" (default) } ``` **Response (QRIS):** ```json { "status": 200, "pesan": "", "data": { "no_trx": "#TIMO...", "jumlah_tagihan": "50000", "biaya_admin": "5000", "jumlah_unik": "0", // QRIS tidak pakai kode unik "qris_qr_code": "000201010212...", // QR code content "qris_invoiceid": "123456", "qris_nmid": "ID1025466699168", "qris_expired_at": "2025-01-15 14:30:00" // 15 menit dari sekarang } } ``` ## Database Schema Field QRIS di tabel `pembayaran`: - `qris_qr_code` TEXT - QR code content dari API - `qris_invoiceid` VARCHAR(100) - Invoice ID untuk check status - `qris_nmid` VARCHAR(100) - NMID dari API - `qris_expired_at` DATETIME - QRIS expiration (15 menit) - `qris_check_count` INT - Jumlah check status - `qris_last_check_at` DATETIME - Last check timestamp **Note:** Field ini perlu ditambahkan ke database jika belum ada. ## Configuration (.env) ```ini # QRIS Configuration QRIS_API_KEY=139139250221910 QRIS_MID=126670220 QRIS_NMID=ID1025466699168 QRIS_BASE_URL=https://qris.interactive.co.id/restapi/qris/ ``` ## Business Rules 1. **Validasi Transaksi:** - QRIS hanya untuk transaksi ≤ Rp 70.000 - Jika > 70.000, return error: "QRIS hanya tersedia untuk transaksi di bawah Rp 70.000" 2. **Kode Unik:** - QRIS: **TIDAK pakai kode unik** (jumlah_unik = 0) - BRI/Manual: **Pakai kode unik** (10-999) 3. **Expiration:** - QRIS: 15 menit dari generate QR code - BRI/Manual: 1 hari dari request 4. **Verification:** - QRIS: Auto verify via API checkStatus - BRI: Manual verify atau auto via BRI API - Manual: Manual verify oleh admin 5. **Notification:** - QRIS: WhatsApp setelah payment verified - BRI: Telegram ke admin saat "saya sudah transfer" - Manual: Telegram ke admin saat upload bukti ## Perbandingan Payment Methods | Method | Kode Unik | Max Amount | Verification | Notification | |--------|-----------|------------|-------------|--------------| | QRIS | ❌ No | ≤ 70.000 | Auto (API) | WhatsApp (user) | | BRI | ✅ Yes | Unlimited | Manual/Auto (BRI API) | Telegram (admin) | | Manual | ✅ Yes | Unlimited | Manual (admin) | Telegram (admin) | ## Testing 1. **Test Request QRIS (< 70rb):** ```bash POST /timo/request_pembayaran { "token": "user_token", "no_sl": "059912", "payment_method": "qris" } ``` 2. **Test Request QRIS (> 70rb):** ```bash # Should return error ``` 3. **Test Check Status:** ```bash POST /timo/cek_status_qris { "token": "user_token", "no_sl": "059912" } ``` ## SQL Migration (Jika diperlukan) ```sql ALTER TABLE pembayaran ADD COLUMN qris_qr_code TEXT NULL, ADD COLUMN qris_invoiceid VARCHAR(100) NULL, ADD COLUMN qris_nmid VARCHAR(100) NULL, ADD COLUMN qris_expired_at DATETIME NULL, ADD COLUMN qris_check_count INT DEFAULT 0, ADD COLUMN qris_last_check_at DATETIME NULL; ```