Files
Qris-Soundbox/14-fase1-step3-notification-spec.md
2026-05-25 08:22:12 +07:00

4.1 KiB

Fase 1 — Step 3: Notifikasi MQTT Dasar (Static Payment)

Dokumen ini memandu implementasi notifikasi success payment ke device berbasis event transaksi paid.

1) Tujuan Step 3

  • Memastikan setiap transaksi paid memicu notifikasi sukses ke device yang valid
  • Menyimpan status delivery dan retry agar operasional bisa dipantau
  • Menyediakan endpoint admin untuk retry manual

2) Event Source

  • Trigger dari Step 2: event internal transaction.paid
  • Sumber wajib: event bus internal / service method call dari transaction service (untuk fase awal)

3) Mapping Notifikasi

  • Input: transaction_id, merchant_id, device_id, amount, currency, paid_at, reference
  • Output: payload MQTT payment_success ke topik:
    • devices/{deviceId}/downlink/payment/success
  • Hanya kirim jika device memiliki binding aktif (device_bindings.active_flag = true)

4) Tabel dan Status

notifications

Kolom inti:

  • id
  • transaction_id
  • device_id
  • delivery_channel = mqtt
  • payload_type = payment_success
  • delivery_status: queued | sent | acknowledged | failed | retrying
  • retry_count
  • ack_status: pending | received | not_supported | not_needed
  • sent_at
  • ack_at

Status transisi:

  • dibuat -> queued
  • publish sukses -> sent
  • no ack handler tersedia pada fase awal -> acknowledged otomatis atau failed sesuai konfigurasi broker
  • publish gagal -> retrying
  • retry 3x gagal -> failed

5) Payload Kontrak MQTT (Step 3)

{
  "message_type": "payment_success",
  "event_id": "evt_123",
  "transaction_id": "tx_123",
  "merchant_name": "Toko Berkah",
  "amount": 50000,
  "currency": "IDR",
  "paid_at": "2026-05-23T10:02:10Z",
  "audio_text": "Pembayaran diterima lima puluh ribu rupiah",
  "display_text": "Pembayaran diterima Rp50.000"
}

6) Alur Proses Notifikasi

  1. Step 2 publish event transaction.paid
  2. Notification Orchestrator menerima event
  3. Validasi device_id ada dan memiliki binding aktif
  4. Buat record notifications dengan status queued
  5. Publish ke devices/{deviceId}/downlink/payment/success
  6. Jika sukses, update sent dan sent_at
  7. Jika gagal:
    • hitung retry (exponential/linear simple backoff)
    • update retrying
    • lanjut retry maksimum 3x
  8. Jika 3x gagal tetap failed
  9. Return result ke endpoint retry bila dipanggil manual

7) Retry Policy Fase 1 (Sederhana)

  • max_attempt = 3
  • retry_interval_seconds = 15, 30, 60 (tetap untuk fase awal)
  • retry_count disimpan di notifications.retry_count
  • tiap percobaan harus idempotent via event_id dan transaction_id

8) Endpoint Admin

  • POST /admin/transactions/{transactionId}/retry-notification
    • validasi transaksi status harus paid
    • akan membuat attempt publish baru jika delivery_status bukan acknowledged
    • response:
      • transaction_id
      • notification_id
      • delivery_status
      • next_retry_at

9) Endpoint Ops Monitoring Minimal

  • GET /admin/devices/{deviceId}/notifications
    • list notif by device + delivery_status
  • GET /admin/transactions/{transactionId}
    • tampilkan link notification + timeline status

10) Idempotency dan De-Dupe

  • kombinasi key notifikasi:
    • transaction_id + event_id
  • jika event duplicate:
    • tidak membuat record baru
    • return existing notif status
  • publish duplicate harus ditolak di orchestrator (guard).

11) Error Code (saran)

  • NOTIFICATION_DEVICE_UNAVAILABLE
  • NOTIFICATION_NO_ACTIVE_BINDING
  • NOTIFICATION_PUBLISH_FAILED
  • NOTIFICATION_RETRY_EXHAUSTED

12) Acceptance Criteria Step 3

  • transaksi paid menghasilkan event payment_success ke topik device
  • notification record terbentuk untuk setiap transaksi paid
  • perangkat yang tidak terikat aktif tidak dipush (state failed dengan reason)
  • retry berjalan saat publish gagal
  • endpoint retry admin merubah status dari failed/retrying menjadi sent atau tetap failed setelah limit

13) Catatan Implementasi Step 3 (Tanpa Design)

  • gunakan QoS 1 untuk topic payment success
  • hindari retained message untuk event sukses pembayaran
  • logging harus menyertakan transaction_id, device_id, event_id, request_id
  • payload audit (audio/display) boleh berupa default ID locale