119 lines
4.1 KiB
Markdown
119 lines
4.1 KiB
Markdown
# 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)
|
|
```json
|
|
{
|
|
"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
|