# Midtrans CIFO Product Requirements Document (PRD)

## 1. Goals and Background Context

### Goals
- Mendukung pembayaran melalui Midtrans Core API di aplikasi.
- Menyediakan pilihan metode pembayaran: bank transfer/VA, QRIS, kartu, dan lainnya.
- Menjamin status transaksi akurat melalui webhook/callback.
- Menyediakan UI yang jelas untuk memilih metode dan melihat status.
- Menangani error/timeout dengan retry dan fallback terukur.
- Menyediakan histori transaksi dan audit trail.
- Memenuhi kepatuhan keamanan (tokenisasi, PCI-aligned, tidak menyimpan data sensitif).
- Mendukung testing via sandbox dan konfigurasi multi-environment.

### Background Context
Integrasi Midtrans Core API memungkinkan aplikasi menggunakan UI sendiri dan berkomunikasi programatik dengan sistem pembayaran Midtrans. Sandbox aktif secara default, sehingga pengujian dapat dilakukan segera. Aktivasi untuk Production memerlukan request aktivasi ke Midtrans. Integrasi harus end-to-end: pembuatan transaksi, pemilihan metode, penanganan callback/webhook, verifikasi status, serta penanganan error. Fokus awal pada MVP yang aman, reliabel, dan mudah diuji. [0]

### Change Log
| Date       | Version | Description                                   | Author |
|------------|---------|-----------------------------------------------|--------|
| 2025-11-07 | v4      | Initial PRD draft (Midtrans Core multi-metode) | PM (John) |

## 2. Requirements

### Functional Requirements (FR)
- FR1: Integrasi Midtrans Core untuk pembuatan transaksi dan pilihan metode.
- FR2: UI pemilihan metode: VA, QRIS, kartu; extensible untuk metode lain.
- FR3: Dukungan bank transfer/Virtual Account (generate, display, expiry).
- FR4: Dukungan QRIS (generate QR, countdown expiry, status polling/callback).
- FR5: Dukungan kartu (tokenisasi, 3DS jika relevan).
- FR6: Webhook/callback listener untuk status (settlement, pending, deny, expire).
- FR7: Verifikasi dan rekonsiliasi status transaksi dengan Midtrans.
- FR8: Idempotensi request pembayaran dan penanganan retry/failure.
- FR9: Histori transaksi per user dan audit trail.
- FR10: Konfigurasi sandbox/production dan kunci rahasia aman.
- FR11: Notifikasi UI atas status (sukses, gagal, pending).
- FR12: Refund/void (scope: disiapkan; eksekusi via peran operator/otomasi terkontrol).
- FR13: Logging terstruktur untuk pembayaran (correlation id).
- FR14: Dukungan i18n untuk label metode dan pesan status (opsional MVP).

### Non-Functional Requirements (NFR)
- NFR1: Latensi end-to-end pembayaran ≤2 detik untuk operasi non-3DS (target).
- NFR2: Availability ≥99.9% untuk endpoint pembayaran internal.
- NFR3: Keamanan sejalan PCI DSS; tidak menyimpan PAN/CVV; gunakan token.
- NFR4: Idempotent key untuk operasi pembuatan pembayaran.
- NFR5: Observability: logging, audit log, dan peninjauan manual berkala.
- NFR6: Rate limiting dan circuit breaker untuk API eksternal.
- NFR7: Audit log lengkap untuk akses/aksi terkait pembayaran.
- NFR8: Skalabilitas horizontal pada komponen callback/queue bila diperlukan.
- NFR9: Aksesibilitas dasar pada UI (WCAG AA target, jika ada UI).
- NFR10: Konfigurasi terpisah per environment dengan secret management aman.

## 3. User Interface Design Goals

### Overall UX Vision
- Checkout ringkas, jelas, dan membangun kepercayaan.
- Minim langkah: pilih metode → tampilkan instruksi/detail → konfirmasi status.
- Komponen reusable untuk setiap metode; konsisten pola error/feedback.

### Key Interaction Paradigms
- Pemilihan metode dengan deskripsi singkat dan estimasi waktu bayar.
- VA: tampilkan nomor VA, bank terkait, expiry, tombol salin, instruksi langkah.
- QRIS: render QR, countdown expiry, status polling + dukungan callback.
- Kartu: tokenisasi, dukungan 3DS bila relevan, pesan error yang ramah.
- Status real-time: pending/sukses/gagal dengan retry/fallback terukur.
- Skeleton/loading states dan empty states yang informatif.

### Core Screens and Views
- Pemilihan Metode Pembayaran
- Detail VA & Instruksi Pembayaran
- Layar QRIS (QR + timer + status)
- Form Kartu (tokenisasi + 3DS)
- Layar Status Pembayaran
- Riwayat Transaksi Pengguna

### Accessibility (WCAG AA)
- Fokus yang jelas, kontras memadai, pengumuman status (ARIA live).
- Alt text pada QR, tidak bergantung warna saja untuk makna.

### Branding
- Ikuti guideline merek bila tersedia; jika belum, gunakan gaya minimalis.
- Sertakan indikator kepercayaan (secure, PCI-aligned) tanpa klaim berlebihan.

### Target Device and Platforms
- Web Responsive; optimasi mobile-first; dukungan desktop.
- Komponen responsif untuk QR, tabel instruksi, dan form.

## 4. Technical Assumptions

### Repository Structure
- Monorepo untuk koordinasi modul UI, service, dan webhook.

### Service Architecture
- Monolith modular + endpoint webhook; opsi job/queue untuk proses asinkron (retry, reconciliation) bila diperlukan.

### Testing Requirements
- Manual QA Only (tanpa unit/integration/E2E otomatis).
- Verifikasi dilakukan oleh manusia berdasarkan checklist per metode (VA, QRIS, kartu), langkah verifikasi status (settlement/deny/expire), dan alur error/retry.

### CI/CD
- Tidak diperlukan (Manual Deployment).
- Prosedur: set secret env (`MIDTRANS_SERVER_KEY`, `MIDTRANS_CLIENT_KEY`, `MIDTRANS_ENV`), deploy manual, smoke test pascadeploy.
- Disarankan staging untuk uji manual sebelum produksi.

### Additional Technical Assumptions and Requests
- Environment & Secrets: `MIDTRANS_BASE_URL` (konfigurabel), `PAYMENT_WEBHOOK_PATH` (mis. `/api/payments/webhook`).
- Signature & Verification: verifikasi notifikasi via signature (gabungan parameter + `server_key`) dan/atau konfirmasi melalui API Midtrans.
- Idempotensi & Retry: idempotent key (berbasis `order_id`/`attempt_id`); retry manual terukur; fokus pada “final states”.
- Observability: logging terstruktur (correlation id per transaksi) dan audit log; review manual berkala.
- Data Model: `Transaction` (order_id, amount, status, method, timestamps) dan `PaymentAttempt` (attempt_id, method, status, raw_payload).
- Security: tidak menyimpan data kartu (tokenisasi), dukungan 3DS bila relevan; secret management aman per environment.
- Platform: asumsi backend PHP/Laravel (Laragon); sesuaikan bila stack berbeda.

## 5. Epic List
- Epic 1: Fondasi & Setup Integrasi Core API
  - Tujuan: Menyiapkan konfigurasi environment, klien API, endpoint awal, dan webhook skeleton; menghadirkan alur checkout minimal dengan pemilihan metode. Memastikan pengujian di sandbox.
- Epic 2: Implementasi Metode Pembayaran (VA, QRIS, Kartu)
  - Tujuan: Mewujudkan flow spesifik tiap metode, dengan UI konsisten, idempotensi, dan penanganan error.
- Epic 3: Status Transaksi & Rekonsiliasi
  - Tujuan: Handler webhook yang andal, verifikasi status, rekonsiliasi on-demand, logging & audit, histori transaksi.
- Epic 4: Refunds/Voids & Operasional
  - Tujuan: Menyediakan alur operator/admin untuk refund/void sesuai kebijakan bisnis, plus checklist QA manual.

## 6. Epic Details — Epic 1: Fondasi & Setup Integrasi Core API

### Expanded Goal
Menetapkan fondasi integrasi Midtrans Core API: konfigurasi environment dan klien, endpoint pembuatan transaksi, skeleton webhook, serta checkout MVP dengan pemilihan metode. Fokus pada kejelasan alur, keamanan dasar, logging/audit, dan pengujian sandbox manual.

#### Story 1.1: Setup Payment Config & Midtrans Client
Acceptance Criteria
1: Secret env (`MIDTRANS_SERVER_KEY`, `MIDTRANS_CLIENT_KEY`, `MIDTRANS_ENV`) terpasang dan tervalidasi di sandbox.
2: Klien Core API terkonfigurasi dan dapat melakukan request terautentikasi ke endpoint yang relevan.
3: Logging terstruktur aktif, menyertakan correlation id per transaksi.
4: Tersedia panduan smoke test manual untuk konektivitas Midtrans (hasil dicatat).

#### Story 1.2: Checkout MVP — Metode Selection UI Skeleton
Acceptance Criteria
1: UI menampilkan pilihan metode (VA, QRIS, Kartu) dengan deskripsi singkat.
2: Responsif (mobile-first) dan aksesibilitas dasar sesuai WCAG AA (fokus/kontras/ARIA live untuk status).
3: Penanganan error dasar (mis. konfigurasi belum lengkap) tampil jelas dan konsisten.
4: Alur mengarahkan ke pembuatan transaksi ketika metode dipilih (stub/placeholder bila perlu).

#### Story 1.3: Create Transaction Endpoint & Order Association
Acceptance Criteria
1: Endpoint server menerima payload order (amount, method) dan mengembalikan detail transaksi.
2: Record `Transaction` tersimpan dengan idempotency key berbasis `order_id`/`attempt_id`.
3: Validasi amount dan metode pembayaran sesuai kebijakan aplikasi.
4: Penanganan error (timeout/deny) dengan logging dan feedback yang jelas ke UI.

#### Story 1.4: Webhook Skeleton Handler & Logging
Acceptance Criteria
1: Endpoint webhook tersedia pada path yang dikonfigurasi (mis. `/api/payments/webhook`).
2: Signature verifikasi diterapkan; notifikasi tidak valid ditolak dengan log yang informatif.
3: Status transaksi diperbarui (settlement/pending/deny/expire) ke data store.
4: Panduan uji manual untuk skenario notifikasi (settlement/deny/expire) tersedia dan dijalankan.

#### Story 1.5: Sandbox Manual Smoke Test & Runbook
Acceptance Criteria
1: Dokumen langkah uji manual sandbox (VA, QRIS, Kartu) tersedia dan dapat diikuti end-to-end.
2: Hasil uji dicatat (sukses/gagal/pending) dengan referensi order/attempt id.
3: Instruksi review log dan audit trail disertakan, termasuk pencarian correlation id.
4: Kriteria keluar (exit criteria) didefinisikan untuk menyatakan Epic 1 siap rilis.

### Opsi Elicitasi (1–9)
1. Lanjut ke Epic 2 details (Proceed)
2. Analisis alur logis dan dependensi antar-story
3. Evaluasi keselarasan dengan tujuan Epic 1
4. Identifikasi risiko dan isu tak terduga
5. Tantang dari perspektif kritis (devil’s advocate)
6. Perspektif tim Agile (PO/SM/Dev/QA)
7. Stakeholder round table (gabungan sudut pandang)
8. Validasi self-consistency (bandingkan alternatif sequencing)
9. Tree of Thoughts deep dive (eksplorasi variasi pemecahan story)

## 7. Epic Details — Epic 2: Implementasi Metode Pembayaran (VA, QRIS, Kartu)

Expanded Goal: Menyelesaikan alur pembayaran untuk Virtual Account (VA), QRIS, dan Kartu (tokenisasi + 3DS) end-to-end, termasuk UI, validasi input, idempotensi, penanganan error/expiry, dan pembaruan status transaksi via webhook/polling sesuai Midtrans Core API [0].

Stories & Acceptance Criteria

Story 2.1 — Virtual Account (VA) Payment Flow
- Functional Acceptance Criteria:
  1: Server membuat transaksi VA via Core API dan mengembalikan `va_number`, `bank`, `expiry`, dan instruksi pembayaran [0].
  2: UI menampilkan detail VA (bank, nomor VA, expiry) dengan tombol copy dan instruksi langkah demi langkah.
  3: Status transaksi diperbarui otomatis melalui webhook (prefer) atau polling; UI mencerminkan status `pending/settlement/expire/deny` secara jelas.
  4: Idempotensi: percobaan create transaksi untuk order yang sama tidak membuat duplikasi; reattempt menggunakan `attempt_id` baru dengan jejak audit.
  5: Error handling: downtime bank/invalid VA ditangani dengan pesan jelas dan opsi kembali memilih metode lain.
  6: Logging & audit: semua event terlog dengan `correlation_id`; record transaksi menyimpan history status.

Story 2.2 — QRIS Payment Flow
- Functional Acceptance Criteria:
  1: Server membuat transaksi QRIS; UI merender QR code dari payload (string/image) dan menampilkan expiry countdown [0].
  2: UI memenuhi aksesibilitas dasar: alt text untuk QR, ARIA live untuk countdown, dan fallback teks instruksi.
  3: Status diperbarui via webhook (prefer) dengan fallback polling; UI mengubah state ke `pending/settlement/expire/deny`.
  4: Saat expired, UI menyediakan aksi reattempt (generate QR baru) dengan idempotensi attempt terjaga.
  5: Error handling: network error/invalid payload ditangani; tidak ada QR usang di-cache; logging terstruktur.

Story 2.3 — Card Payment Flow (Tokenization + 3DS)
- Functional Acceptance Criteria:
  1: Tokenisasi kartu dilakukan di klien menggunakan `CLIENT_KEY`; server menerima token dan melakukan charge sesuai Core API [0].
  2: 3DS challenge/redirect terintegrasi; pengguna menyelesaikan otentikasi dan status final diproses.
  3: Keamanan: PAN/CVV tidak disimpan; hanya token dan metadata aman; jalur data terenkripsi.
  4: Idempotensi charge: percobaan ulang tidak menghasilkan double charge; kontrol reattempt terdokumentasi.
  5: Error & decline mapping: pesan ramah pengguna berdasarkan kode Midtrans; UI menyediakan opsi kembali/memilih metode lain.

Story 2.4 — Common Error & Retry Patterns
- Functional Acceptance Criteria:
  1: Standarisasi pesan error lintas metode dengan `code`, `severity`, dan saran tindakan.
  2: Kontrol retry manual dengan batas percobaan dan panduan backoff; semua percobaan terekam di audit trail.
  3: Deteksi final-state yang konsisten (settlement/deny/expire) untuk mencegah percobaan tak berujung.

Story 2.5 — Method Abstraction & Extensibility
- Functional Acceptance Criteria:
  1: Abstraksi registry metode pembayaran (VA/QRIS/Kartu) sehingga penambahan metode baru (GoPay/ShopeePay) minim perubahan UI.
  2: Dokumentasi instruksi per-metode untuk QA manual beserta acceptance test skenario.
  3: Observability tags menyertakan `method`, `attempt_id`, dan `order_id` untuk pelacakan lintas metode.

Opsi Elicitasi (1–9)
1. Lanjut ke Epic 3 details (Status & Rekonsiliasi)
2. Analisis alur logis dan dependensi antar-story Epic 2
3. Evaluasi keselarasan dengan tujuan Epic 2
4. Identifikasi risiko dan isu tak terduga Epic 2
5. Tantang dari perspektif kritis (devil’s advocate)
6. Perspektif tim Agile (PO/SM/Dev/QA)
7. Stakeholder round table (gabungan sudut pandang)
8. Validasi self-consistency (bandingkan alternatif sequencing)
9. Tree of Thoughts deep dive (eksplorasi variasi pemecahan story)

## 8. Epic Details — Epic 3: Status Transaksi & Rekonsiliasi

Expanded Goal: Menjamin status transaksi akurat, konsisten, dan tersinkron antara UI, data store internal, serta Midtrans. Menyediakan penanganan webhook yang reliabel, fallback polling, state machine yang jelas, proses rekonsiliasi berkala, dan runbook operasional yang mendukung QA manual.

Stories & Acceptance Criteria

Story 3.1 — State Machine Status Transaksi
- Functional Acceptance Criteria:
  1: Definisikan state internal beserta mapping ke Midtrans: `initiated`, `pending`, `challenge` (3DS), `settlement`, `deny`, `cancel`, `expire`, `refund` (opsional). Final states ditandai dan tidak menerima transisi lebih lanjut kecuali override manual ber-audit.
  2: Aturan transisi valid terdokumentasi; mencegah regresi status (mis. dari `settlement` kembali ke `pending`) kecuali kasus khusus yang disetujui dan berjejak audit.
  3: Persist status perubahan dengan metadata `source` (webhook/polling/manual), `updated_by` (system/user), dan `occurred_at`.
  4: Idempotensi update: notifikasi duplikat tidak membuat perubahan status ganda; gunakan kunci unik berbasis `transaction_id + status + provider_event_time`.
  5: Concurrency control: update status menggunakan locking/versi agar paralel event tidak menyebabkan lost update.

Story 3.2 — Webhook Processing Reliabel
- Functional Acceptance Criteria:
  1: Verifikasi signature notifikasi Midtrans; request invalid ditolak dengan log jelas dan tidak memutakhirkan status [0].
  2: Toleransi out-of-order: notifikasi yang datang tidak berurutan tetap menghasilkan status konsisten sesuai prioritas transisi yang diizinkan.
  3: Respons endpoint cepat (200 OK) setelah validasi dasar; pemrosesan lebih berat mencatat event dan memutakhirkan status secara sinkron sederhana (tanpa bergantung CI/CD) dengan error handling.
  4: Retry pada error transient tercatat dengan batas percobaan; idempotensi terjaga sehingga tidak ada double update.
  5: Logging & audit: setiap event webhook memiliki `event_id`, `correlation_id`, payload ringkas, hasil verifikasi, dan dampak terhadap status.

Story 3.3 — Fallback Polling Status
- Functional Acceptance Criteria:
  1: Bila dalam SLA tidak ada webhook, sistem dapat melakukan polling status ke Midtrans untuk transaksi yang `pending` dan menyimpan hasilnya [0].
  2: Polling memiliki backoff dan batas percobaan; status hasil polling ditandai `source=polling` dan diverifikasi terhadap aturan transisi.
  3: UI dan data store merepresentasikan status final secara konsisten; mismatch dicatat sebagai `requires_investigation`.

Story 3.4 — Rekonsiliasi Berkala (Manual/Schedule)
- Functional Acceptance Criteria:
  1: Tersedia perintah/skrip rekonsiliasi yang dapat dijalankan manual (mis. artisan/CLI) untuk mengecek status Midtrans terhadap transaksi lokal dalam periode tertentu.
  2: Laporan rekonsiliasi dihasilkan (CSV/JSON) berisi `order_id`, `transaction_id`, `method`, `amount`, `status_local`, `status_midtrans`, dan rekomendasi resolusi.
  3: Transaksi dengan mismatch ditandai `requires_investigation`; runbook menyertakan langkah koreksi (re-fetch status, reprocess event) dan dokumentasi hasil.

Story 3.5 — Audit Trail & Export
- Functional Acceptance Criteria:
  1: Timeline perubahan status per transaksi tersedia (internal), termasuk sumber perubahan dan waktu kejadian.
  2: Ekspor CSV untuk Finance/Operasional mencakup filter periode, metode, dan status final.
  3: Observability tags konsisten: `order_id`, `transaction_id`, `method`, `status`, `attempt_id`, `correlation_id`.

Story 3.6 — Runbook Operasional
- Functional Acceptance Criteria:
  1: Dokumentasi langkah-langkah: validasi signature, re-run webhook (simulasi), polling manual, interpretasi kode status, dan tindakan korektif.
  2: Panduan troubleshooting untuk kasus umum: notifikasi tidak datang, duplikasi notifikasi, mismatch status, timeout.
  3: Exit criteria rekonsiliasi: seluruh transaksi dalam periode uji memiliki status final konsisten, tidak ada mismatch terbuka.

Opsi Elicitasi (1–9)
1. Lanjut ke Epic 4 details (Refund/Void & Operasional)
2. Analisis dependensi antar-story Epic 3
3. Evaluasi keselarasan dengan tujuan Epic 3
4. Identifikasi risiko dan isu tak terduga Epic 3
5. Tantang dari perspektif kritis (devil’s advocate)
6. Perspektif tim Agile (PO/SM/Dev/QA)
7. Stakeholder round table (gabungan sudut pandang)
8. Validasi self-consistency (bandingkan alternatif sequencing)
9. Tree of Thoughts deep dive (eksplorasi variasi pemecahan story)

## References
[0] Midtrans Core API — Custom Interface: https://docs.midtrans.com/docs/custom-interface-core-api