SUPONO.
ISP-Billing • Kursus PraktisiPanduan Praktik Hands-On

Lab 3: Webhook Python Flask untuk Otomasi Generate Voucher QRIS

Praktikum membangun service webhook dengan Python Flask untuk menangkap event QRIS dan membuat user MikroTik otomatis.

Format: Markdown (.MD)•File: lab_3_webhook_otomasi_voucher_qris.md•Sasaran: Praktisi & DevOps
Filter Versi CLI:

Tujuan Praktikum #

  1. Membangun server webhook mini menggunakan Python Flask.
  2. Menerima payload callback notifikasi status pembayaran QRIS.
  3. Menghasilkan user voucher baru di User Manager RouterOS via REST API.
  4. Mengirimkan notifikasi kredensial voucher ke WhatsApp pelanggan.

Langkah 1: Script Server Webhook (qris_webhook_service.py) #

PYTHON
from flask import Flask, request, jsonify
import requests
import hashlib
import random
import string
import urllib3

urllib3.disable_warnings()

app = Flask(__name__)

# Konfigurasi MikroTik REST API
ROUTER_API = "https://103.120.40.10/rest"
ROUTER_AUTH = ("api-admin", "P@ssw0rdDevOps2026!")
SERVER_SECRET_KEY = "MidtransServerKeySecret-xxxx"

def generate_code(length=6):
    return ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))

def create_userman_voucher(username, password, profile_name):
    url = f"{ROUTER_API}/user-manager/user"
    payload = {
        "name": username,
        "password": password,
        "group": "default",
        "profile": profile_name
    }
    res = requests.put(url, json=payload, auth=ROUTER_AUTH, verify=False)
    return res.status_code in [200, 201]

@app.route('/webhook/qris', methods=['POST'])
def qris_callback():
    data = request.json
    order_id = data.get('order_id')
    status_code = data.get('status_code')
    gross_amount = data.get('gross_amount')
    signature = data.get('signature_key')

    # Validasi SHA512 Signature Hash
    raw_sig = f"{order_id}{status_code}{gross_amount}{SERVER_SECRET_KEY}"
    expected_sig = hashlib.sha512(raw_sig.encode()).hexdigest()

    if signature != expected_sig:
        return jsonify({"status": "error", "message": "Invalid signature"}), 403

    # Jika pembayaran berhasil diselesaikan (settlement)
    if data.get('transaction_status') == 'settlement':
        voucher_user = f"NET-{generate_code(5)}"
        voucher_pass = generate_code(6)
        profile = "HARIAN-UNLI" if float(gross_amount) >= 10000 else "PROMO-1JAM"

        success = create_userman_voucher(voucher_user, voucher_pass, profile)
        if success:
            print(f"[+] Pembayaran sukses order {order_id}. Voucher {voucher_user} dibuat.")
            # Di sini Anda bisa memanggil API Gateway WhatsApp (e.g. Fonnte/Waba)
            return jsonify({"status": "success", "user": voucher_user, "pass": voucher_pass}), 200

    return jsonify({"status": "received"}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Langkah 2: Uji Coba Simulasi Webhook dengan cURL #

BASH
curl -X POST http://localhost:5000/webhook/qris \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "INV-20261001-001",
    "status_code": "200",
    "gross_amount": "10000.00",
    "transaction_status": "settlement",
    "signature_key": "dummy_sig"
  }'