# 01. Pendahuluan dan Arsitektur Sistem PEWE

## 1. Latar Belakang & Permasalahan Domain

Di lingkungan institusi pendidikan dan sekolah modern, operasional harian melibatkan berbagai aplikasi perangkat lunak yang memerlukan transaksi pembayaran elektronik. Beberapa contoh aplikasi internal meliputi:
- **PPDB (Penerimaan Peserta Didik Baru)**: Biaya pendaftaran dan registrasi ulang murid baru.
- **SPP & Biaya Pendidikan**: Tagihan iuran bulanan murid.
- **Tasjil / Event Manager**: Pendaftaran seminar, workshop, pelatihan, atau kegiatan ekstrakurikuler.
- **Kantin / Koperasi**: Top-up saldo dompet digital atau pembayaran merchant harian.

### Permasalahan yang Dihadapi Tanpa Central Bridge
1. **Fragmentasi Akun Payment Gateway**: Sekolah umumnya hanya memiliki 1 akun merchant (seperti Xendit, Midtrans) atau beberapa rekening bank resmi. Mengintegrasikan akun yang sama ke banyak aplikasi secara terpisah sangat berisiko dan tidak efisien.
   - *Risiko Keamanan*: Pembagian Secret Key API vendor ke banyak server/aplikasi meningkatkan potensi kebocoran kredensial.
   - *Konstruksi Kredensial*: Perubahan kredensial atau rotasi API Key dari vendor mengharuskan pembaruan konfigurasi secara manual pada seluruh aplikasi internal.
2. **Duplikasi Kode Integrasi**: Setiap tim/developer aplikasi harus mengimplementasikan library vendor, signature generator, dan webhook listener masing-masing.
   - *Tingginya Technical Debt*: Setiap pembaruan API versi vendor (misal API v2 ke v3) memerlukan refactoring kode redundan di setiap basis kode aplikasi.
   - *Inkonsistensi Penanganan Error*: Setiap aplikasi berpotensi menangani kegagalan jaringan atau parsing respons vendor dengan cara yang berbeda-beda.
3. **Konflik Virtual Account & Callback Chaos**: Penggunaan nomor VA berpotensi mengalami tabrakan jika tidak dikelola oleh satu koordinasi pusat. Selain itu, belasan webhook endpoint dari vendor harus dipasang dan dipelihara secara terpisah di setiap aplikasi.
   - *Polusi Endpoint Webhook*: Pihak penyedia Payment Gateway mengalami kesulitan mengonfigurasi belasan URL callback yang berbeda untuk satu akun merchant.
   - *Race Condition & Inbound Failure*: Ketika webhook gagal terkirim ke aplikasi target (misal server PPDB down), status pembayaran menggantung tanpa mekanisme retri terpusat.
4. **Kesulitan Rekonsiliasi Keuangan Terpusat**: Tim keuangan sekolah kesulitan melacak arus kas masuk dari berbagai aplikasi karena data tersebar di banyak database.
   - *Audit Trail yang Fragmented*: Laporan transaksi terpisah-pisah di database PPDB, SPP, dan Tasjil, sehingga rekonsiliasi kas harian membutuhkan penggabungan data manual (spreadsheet).

### Solusi PEWE (Payment Engine for Workload Exchange)
PEWE bertindak sebagai **Payment Gateway Bridge & Router terpusat**. Aplikasi internal (**Tenant**) tidak lagi berhubungan langsung dengan API vendor (Xendit, Midtrans, Bank Direct). Semua permintaan transaksi pembayaran dikirimkan ke PEWE melalui satu pintu REST API yang seragam. PEWE mengurus autentikasi, penyaluran request ke vendor/bank yang tepat, penerimaan callback webhook, pencatatan log transaksi, serta penerusan notifikasi status pembayaran kembali ke aplikasi tenant secara konsisten.

#### Pilar Utama Mesin PEWE:
- **Centralized Tenant Authentication**: Menggunakan token JWT/API Key yang memverifikasi identitas setiap sub-aplikasi secara aman.
- **Unified Idempotency Engine**: Mencegah duplikasi tagihan/pembayaran akibat percobaan ulang request HTTP (*network retry*) dari aplikasi tenant.
- **Dynamic Channel Router**: Mengarahkan metode pembayaran (Virtual Account, QRIS, E-Wallet, Credit Card) ke adapter driver vendor yang tepat secara dinamis berdasarkan konfigurasi rute.
- **Distributed Webhook Dispatcher & Queue**: Menerima callback dari vendor, memvalidasi signature keamanan, dan meneruskan notifikasi status ke URL callback tenant dengan mekanisme *exponential backoff retry*.
- **Centralized Financial Audit Log & Status Normalization**: Mengubah status spesifik vendor yang bervariasi (misal: `COMPLETED`, `SETTLED`, `SUCCESS`, `00`) menjadi status terstandarisasi internal (`PENDING`, `PAID`, `EXPIRED`, `FAILED`).

#### Diagram Arsitektur Konseptual PEWE

```
┌─────────────────────────────────────────────────────────────────────────┐
│                       Aplikasi Tenant (Internal)                        │
│             [ PPDB ]      [ TASJIL ]      [ SPP ]      [ KANTIN ]       │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ (REST API & Webhook Notification)
┌────────────────────────────────────▼────────────────────────────────────┐
│                        PEWE (Yii3 Gateway Bridge)                       │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │  Tenant Auth  │  Idempotency Engine  │ Channel Router │ Webhook Queue│ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ (Vendor Specific APIs)
┌────────────────────────────────────▼────────────────────────────────────┐
│                   Payment Vendors & Direct Banking                      │
│   [ Xendit API v3 ]   [ Midtrans ]   [ BNI/BRI/BSI/Mandiri Direct ]     │
└─────────────────────────────────────────────────────────────────────────┘
```

#### Alur Transaksi Lengkap (Sequence Workflow)

```mermaid
sequenceDiagram
    autonumber
    actor User as Pembayar / Siswa
    participant Tenant as Aplikasi Tenant (PPDB/SPP)
    participant PEWE as PEWE Gateway Bridge
    participant Vendor as Payment Gateway / Bank API

    User->>Tenant: Checkout / Pilih Pembayaran
    Tenant->>PEWE: POST /api/v1/payment-requests (Bearer Token + X-Idempotency-Key)
    Note over PEWE: 1. Validate Tenant Auth<br/>2. Check Idempotency Key<br/>3. Route Payment Channel Driver
    PEWE->>Vendor: Direct API Request (Create VA / QRIS)
    Vendor-->>PEWE: Response Payload (VA Number / QRIS String / URL)
    PEWE-->>Tenant: Normalized Response JSON (payment_id, status: PENDING, payment_code)
    Tenant-->>User: Tampilkan Nomor VA / QRIS

    Note over User, Vendor: Sesi Pembayaran oleh User via ATM / Mobile Banking
    User->>Vendor: Transfer / Bayar VA / Scan QRIS
    Vendor->>PEWE: Webhook Callback POST /api/v1/webhooks/{vendor} (Payload + Signature)
    Note over PEWE: 1. Verify Webhook Signature<br/>2. Update Payment Status -> PAID<br/>3. Queue Tenant Webhook Delivery
    PEWE-->>Vendor: HTTP 200 OK (Webhook Received)

    PEWE->>Tenant: Async Webhook Notification POST /tenant-callback (Status: PAID)
    Tenant-->>PEWE: HTTP 200 OK (Acknowledged)
    Tenant->>User: Update Status Transaksi Lunas
```

---

## 2. Arsitektur Berbasis Yii3 Framework

PEWE dibangun menggunakan **Yii3 Framework** (versi terbaru Yii Framework berbasis arsitektur terdekopel modern dan mendukung PHP 8.2 hingga PHP 8.5).

Berbeda dari Yii2 yang menggunakan arsitektur monolithic berbasis `Yii::$app` singleton, Yii3 mengadopsi standar PSR (PHP Standard Recommendations) secara penuh:

### Standard PSR yang Digunakan:

1. **PSR-7 (HTTP Message Interfaces)**:
   - Menggunakan `Psr\Http\Message\ServerRequestInterface` dan `Psr\Http\Message\ResponseInterface`.
   - Diimplementasikan via paket `httpsoft/http-message` dan `yiisoft/data-response`.
   - Menjamin bahwa objek request dan response bersifat *immutable* (tidak dapat diubah secara langsung melainkan menghasilkan instansi baru saat dimodifikasi), yang mencegah efek samping (*side-effects*) dalam eksekusi aplikasi.

2. **PSR-15 (HTTP Server Middleware)**:
   - Pipeline request diproses melalui rantai middleware (`yiisoft/middleware-dispatcher`).
   - Setiap HTTP request melewati alur middleware secara sekuensial sebelum mencapai Controller/Handler action.
   - Komponen middleware PEWE bertanggung jawab atas pemrosesan lintas sektoral seperti penanganan autentikasi tenant, verifikasi idempotensitas, standardisasi format respons JSON, serta pencatatan log API.

3. **PSR-11 (Container Interface)**:
   - Injeksi ketergantungan (Dependency Injection) dikelola secara penuh oleh paket `yiisoft/di`.
   - Semua dependensi didefinisikan secara eksplisit di dalam direktori `config/` menggunakan sistem `yiisoft/config` yang menggabungkan konfigurasi (*merge-plan*).
   - Menghilangkan ketergantungan pada Service Locator global (`Yii::$app->service`) demi mendukung keterujian kode (*testability*) dan *clean architecture*.

4. **PSR-3 (Logger Interface)**:
   - Menggunakan `Psr\Log\LoggerInterface` yang diimplementasikan oleh paket `yiisoft/log`.
   - Pencatatan aktivitas sistem terbagi ke dalam beberapa target log seperti file log harian, log transaksi spesifik, dan log kesalahan sistem.

5. **PSR-17 (HTTP Factories)** & **PSR-12 / PER Coding Standard**:
   - Pembuatan instansiasi request, response, dan stream menggunakan factory standar PSR-17 (`psr/http-factory`).
   - Seluruh basis kode mengikuti standar gaya penulisan PHP modern dengan verifikasi otomatis via `php-cs-fixer`, `psalm`, dan `rector`.

### Siklus Hidup Request HTTP Yii3 (Yii3 Request Lifecycle)

Alur perjalanan permintaan HTTP di dalam aplikasi PEWE berjalan sebagai berikut:

```
[ HTTP Request ]
       │
       ▼
1. public/index.php ──► Instansiasi Yii Runner HTTP (yiisoft/yii-runner-http)
       │
       ▼
2. Dependency Injection Container ──► Memuat konfigurasi dari config/ (yiisoft/config)
       │
       ▼
3. PSR-15 Middleware Dispatcher (yiisoft/middleware-dispatcher)
       │
       ├─► Middleware 1: ApiLogger (Mencatat Waktu Masuk Request)
       ├─► Middleware 2: TenantAuth (Validasi Bearer Token / API Key Tenant)
       ├─► Middleware 3: Idempotency (Periksa X-Idempotency-Key pada Cache/DB)
       └─► Middleware 4: ApiFormatter (Menyiapkan Format Data Output JSON)
       │
       ▼
4. FastRoute Router (yiisoft/router-fastroute) ──► Pencocokan Rute URL ke Controller Action
       │
       ▼
5. Controller Action (e.g. App\Controller\Api\V1\PaymentRequestController)
       │
       ├─► Eksekusi Logic Bisnis via PaymentGatewayFactory & PaymentGatewayInterface Driver
       └─► Mengembalikan objek Yiisoft\DataResponse\DataResponse
       │
       ▼
6. PSR-7 Response Emission ──► Konversi DataResponse menjadi Stream HTTP Response ke Client
```

---

## 3. Struktur Direktori Proyek

Berikut adalah tata letak direktori pada aplikasi PEWE:

```
/home/data/workshop/pewe/
├── config/                      # Konfigurasi aplikasi & injeksi DI Yii3
│   ├── common/                  # Definisi dependency umum (DB, Log, Validator)
│   ├── web/                     # Definisi rute web & middleware pipeline
│   ├── console/                 # Definisi command CLI
│   └── configuration.php        # Entry-point merge-plan konfigurasi Yii3
├── public/                      # Document Root Web Server
│   └── index.php                # Entry point HTTP request (Yii Runner HTTP)
├── src/                         # Kode Sumber Utama Application (Namespace App\)
│   ├── Command/                 # CLI Console Commands (Worker, Seeder, Clean)
│   ├── Controller/              # HTTP Controllers
│   │   └── Api/V1/              # API V1 Endpoints (PaymentRequest, Channel, Webhook, Muamalat)
│   ├── Entity/                  # Active Record Domain Models (PaymentRequest, Tenant, Channel, dll)
│   ├── Middleware/              # PSR-15 Middlewares (TenantAuth, Idempotency, ApiFormatter, ApiLogger)
│   ├── Payment/                 # Adapter Engine Payment Gateway & Bank Direct
│   │   ├── Driver/              # Adaptor spesifik vendor (XenditAdapter, BniDirectAdapter, dll)
│   │   ├── HttpClient.php       # HTTP Client wrapper untuk komunikasi vendor
│   │   ├── PaymentGatewayFactory.php   # Factory penyedia instansiasi driver
│   │   └── PaymentGatewayInterface.php # Interface utama kontrak driver
│   ├── Shared/                  # Helper & Utility bersama
│   ├── Web/                     # Controller & Views untuk Admin Dashboard UI
│   │   ├── Auth/                # Login & Logout Admin
│   │   ├── Dashboard/           # Dashboard manajemen transaksi & channel
│   │   └── Shared/              # Layout & Render Template HTML
│   └── Environment.php          # Helper pembaca variabel lingkungan (.env)
├── tests/                       # Suite Pengujian (Codeception & PHPUnit)
├── .env.example                 # Templat konfigurasi variabel lingkungan
├── composer.json                # Dependensi PHP & konfigurasi autoloading PSR-4
├── Makefile                     # Shortcut perintah operasional proyek
├── pewe.sql                     # Skema basis data MariaDB/MySQL awal
└── yii                          # Executable Console Runner (CLI)
```

### Rincian Komponen Direktori Utama

#### 1. Direktori `config/`
Menggunakan plugin `yiisoft/config` untuk memuat dan menggabungkan file konfigurasi modular:
- `config/common/`: Berisi pendaftaran Service DI umum yang berlaku untuk seluruh konteks (Web & Console). Contohnya koneksi database `yiisoft/db-mysql`, pencatat log `yiisoft/log`, serta komponen validator.
- `config/web/`: Definisi khusus aplikasi Web HTTP, seperti rute FastRoute (`routes.php`), pendaftaran PSR-15 Middleware pipeline, dan penangan error HTTP (`yiisoft/error-handler`).
- `config/console/`: Pendaftaran perintah CLI Console (`symfony/console`) yang dapat dijalankan melalui executable `./yii`.
- `config/configuration.php`: Titik masuk utama (*entry-point*) perakitan konfigurasi Yii3 yang menghasilkan file cache `.merge-plan.php`.

#### 2. Direktori `public/`
- `public/index.php`: Satu-satunya titik masuk publik HTTP request yang mengeksekusi `YiiRunner` dari paket `yiisoft/yii-runner-http`. Memuat file autoloader `vendor/autoload.php` dan menginisialisasi DI Container.

#### 3. Direktori `src/` (Namespace `App\`)

- **`src/Command/`**:
  Berisi perintah baris perintah (CLI Command) yang dijalankan secara berkala atau via daemon background:
  - Worker pengiriman retry webhook callback.
  - Command pembersihan log transaksi/idempotency expired.
  - Database seeder dan inisialisasi master data.

- **`src/Controller/Api/V1/`**:
  Titik akhir REST API V1 yang dikonsumsi oleh aplikasi Tenant dan penyedia Payment Gateway:
  - `PaymentRequestController`: Endpoint pembuatan (`POST /api/v1/payment-requests`) dan pengecekan status transaksi (`GET /api/v1/payment-requests/{id}`).
  - `ChannelController`: Endpoint penyedia daftar saluran pembayaran aktif yang tersedia untuk tenant (`GET /api/v1/channels`).
  - `WebhookController`: Endpoint penerima callback webhook terpusat dari Payment Gateway vendor (Xendit, Midtrans, dll).
  - `MuamalatController`: Endpoint khusus penanganan spesifik integrasi Bank Muamalat Direct.

- **`src/Entity/`**:
  Domain model Active Record (`yiisoft/active-record`) yang memetakan tabel database:
  - `Tenant`: Data aplikasi internal terdaftar (misal PPDB, SPP) beserta API Key dan Webhook Callback URL.
  - `PaymentRequest`: Data transaksi pembayaran utama (nomor referensi, nominal, status, tanggal expired).
  - `PaymentStatus`: Enumerasi/referensi status transaksi internal (`PENDING`, `PAID`, `EXPIRED`, `FAILED`).
  - `PaymentMethod`: Jenis instrumen pembayaran (`VIRTUAL_ACCOUNT`, `QRIS`, `EWALLET`, `CREDIT_CARD`).
  - `Channel`: Konfigurasi saluran pembayaran per vendor (misal Xendit VA BNI, Midtrans QRIS).
  - `TransactionLog`: Catatan audit log mentah request & response payload API vendor.
  - `IdempotencyKey`: Penyimpanan Kunci Idempotensi tenant untuk pencegahan duplikasi transaksi.
  - `WebhookDelivery`: Log riwayat pengiriman notifikasi webhook ke server tenant beserta status percobaan retri.
  - `AdminUser`: Pengguna admin pengelola dashboard web PEWE.

- **`src/Middleware/`**:
  Middleware PSR-15 yang bertindak sebagai pemrosesan pra/pasca request:
  - `TenantAuth`: Autentikasi identitas tenant via header `Authorization: Bearer <API_KEY>`.
  - `Idempotency`: Pengecekan header `X-Idempotency-Key` untuk menjamin eksekusi unik.
  - `ApiFormatter`: Menstandardisasi bentuk respons JSON API (`status`, `code`, `message`, `data`, `errors`).
  - `ApiLogger`: Pencatatan log masuk dan durasi pemrosesan setiap HTTP request.
  - `WebAuth` & `Rbac/`: Autentikasi berbasis sesi dan hak akses untuk area Dashboard Admin Web.

- **`src/Payment/`**:
  Jantung mesin transaksi pembayaran PEWE (Driver & Adapter Pattern):
  - `PaymentGatewayInterface.php`: Antarmuka (*contract*) standar yang harus diimplementasikan oleh seluruh driver vendor (`createPayment()`, `checkStatus()`, `parseWebhook()`).
  - `PaymentGatewayFactory.php`: Factory class untuk menginstansiasi adapter driver yang tepat berdasarkan kode saluran (`channel_code`).
  - `HttpClient.php`: Wrapper cURL/Guzzle HTTP Client dengan mekanisme timeout, retry jaringan, dan pencatatan log interaksi vendor.
  - `Driver/`: Implementasi konkret adapter vendor pembayaran:
    - `XenditAdapter.php`: Integrasi Xendit REST API v3 (VA, QRIS, Invoice).
    - `MidtransAdapter.php`: Integrasi Midtrans Snap/Core API.
    - `BniDirectAdapter.php`: Integrasi API Direct Host-to-Host BNI.
    - `BriDirectAdapter.php`: Integrasi API Direct H2H BRI.
    - `BsiDirectAdapter.php`: Integrasi API Direct H2H Bank Syariah Indonesia.
    - `MandiriDirectAdapter.php`: Integrasi API Direct H2H Bank Mandiri.
    - `MuamalatDirectAdapter.php`: Integrasi API Direct H2H Bank Muamalat.

- **`src/Web/`**:
  Modul tampilan antarmuka web (Admin Dashboard UI) berbasis render HTML Yii3 View (`yiisoft/yii-view-renderer`):
  - `Web/Auth/`: Controller untuk alur login, logout, dan reset password admin.
  - `Web/Dashboard/`: Controller tampilan ringkasan transaksi, manajemen tenant, dan konfigurasi channel.
  - `Web/Shared/`: Layout HTML utama, navbar, sidebar, dan komponen template bersama.

#### 4. Direktori `tests/`
Suite pengujian otomatis menggunakan **Codeception** dan **PHPUnit**:
- `tests/Api/`: Test suite otomatis untuk pengujian endpoint REST API v1.
- `tests/Unit/`: Pengujian unit untuk driver payment adapter, helper idempotensi, dan formatting respons.

---

## 4. Lingkungan Pengembangan & Operasional

### Konfigurasi Environment (`.env`)
Pengaturan koneksi database dan kredensial vendor disimpan di dalam file `.env` di root direktori PEWE:

```env
# Mode Aplikasi & Debugging
YII_ENV=dev
YII_DEBUG=true

# Database Configuration (MariaDB / MySQL 8.0+)
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=pewe
DB_USER=root
DB_PASSWORD=secret

# Application Security (Kunci enkripsi & JWT signature)
APP_SECRET=your-super-secret-key-32-chars-long

# Vendor API Credentials (Contoh Sandbox / Staging)
XENDIT_SECRET_KEY=xnd_development_...
MIDTRANS_SERVER_KEY=SB-Mid-server-...
```

#### Rincian Parameter Konfigurasi `.env`:
- `YII_ENV`: Menentukan mode lingkungan (`dev`, `test`, `prod`). Pada mode `prod`, cache konfigurasi `.merge-plan.php` akan dioptimalkan.
- `YII_DEBUG`: Mengaktifkan detail pelacakan error (*stack trace*) saat bernilai `true`. Harus diset `false` di lingkungan produksi.
- `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`: Parameter koneksi ke basis data terpusat MariaDB/MySQL.
- `APP_SECRET`: String acak sepanjang minimal 32 karakter yang digunakan untuk generasi hash keamanan, token session admin, dan enkripsi payload sensitif.
- `XENDIT_SECRET_KEY` & `MIDTRANS_SERVER_KEY`: Kredensial rahasia autentikasi ke server Payment Gateway vendor.

### Executable Command (`./yii` & `Makefile`)
Aplikasi dilengkapi dengan `Makefile` untuk memudahkan perintah-perintah pengembangan:

- **Menjalankan Dev Server**:
  ```bash
  php ./yii serve --port=8080
  # atau via Makefile
  make serve
  ```
  Menjalankan PHP Built-in Web Server dengan Document Root menunjuk ke direktori `public/`.

- **Menjalankan Pengujian**:
  ```bash
  vendor/bin/codecept run
  # atau
  make test
  ```
  Mengeksekusi seluruh suite pengujian API dan Unit test Codeception.

- **Menjalankan Static Analysis & Code Style**:
  ```bash
  # Analisis tipe data & keandalan kode dengan Psalm
  vendor/bin/psalm

  # Perbaikan gaya penulisan kode sesuai standar PSR-12 secara otomatis
  vendor/bin/php-cs-fixer fix

  # Analisis & otomatisasi refactoring PHP modern dengan Rector
  vendor/bin/rector process --dry-run
  ```

### Panduan Operasional & Deployment Produksi

Saat melakukan penggelaran (*deployment*) ke server produksi (Linux Ubuntu/Debian), perhatikan aspek operasional berikut:

1. **Web Server Setup (Nginx + PHP-FPM 8.2+)**:
   - Konfigurasikan Document Root Nginx langsung menuju direktori `/home/data/workshop/pewe/public`.
   - Pastikan seluruh rute non-file dialihkan ke `index.php` (Pattern Front-Controller).
   ```nginx
   location / {
       try_files $uri $uri/ /index.php$is_args$args;
   }
   ```

2. **Optimasi Cache Konfigurasi Yii3**:
   - Jalankan kompilasi merge-plan konfigurasi Yii3 saat proses deployment:
   ```bash
   composer dump-autoload --optimize
   php ./yii config/build
   ```

3. **Background Worker Daemon (Supervisor)**:
   - Gunakan process manager seperti **Supervisor** untuk menjamin worker pengiriman queue webhook (`php ./yii webhook/process-retry`) terus berjalan secara kontinu di background.

4. **Pengamanan Kredensial & Permissions**:
   - Pastikan direktori `runtime/` dan `public/assets/` memiliki hak akses tulis (*write permission*) untuk user web server (`www-data`).
   - Pastikan file `.env` tidak dapat diakses secara publik dari browser web (berada di luar Document Root `public/`).
