# 18. Integrasi Payment Gateway

Panduan teknis untuk mengintegrasikan payment gateway ke dalam Smart Order OS. Saat ini sistem mendukung **Midtrans** (QRIS, VA, GoPay, dll), dan dirancang agar mudah menambahkan gateway lain.

---

## Arsitektur

```
POS (Blade/JS)
  │
  ├─ Manual ──→ POSController::pay() ──→ OrderService::addPayment()
  │
  └─ Online ──→ POSController::getSnapToken()
                    │
                    ▼
               MidtransService::createSnapToken()
                    │
                    ▼ (HTTP API)
               Midtrans Snap API
                    │
                    ▼ (async webhook)
               MidtransController::callback()
                    │
                    ▼
               OrderService::addPayment() → Order COMPLETED
```

## Feature Toggle

Payment gateway dikendalikan oleh **feature flag** di `config/features.php`:

```php
'midtrans' => true, // global default
```

Bisa di-override per outlet melalui `outlet_settings`:

| Key | Deskripsi |
|-----|-----------|
| `midtrans_server_key` | Server Key dari Dashboard Midtrans |
| `midtrans_client_key` | Client Key untuk Snap.js di frontend |

Jika key tidak disetel di outlet, sistem fallback ke `config('services.midtrans.server_key')` dan `config('services.midtrans.client_key')`.

---

## Midtrans — Setup

### 1. Daftar Sandbox

1. Buat akun di [https://dashboard.sandbox.midtrans.com](https://dashboard.sandbox.midtrans.com).
2. Salin **Server Key** dan **Client Key** dari menu Settings → Access Keys.

### 2. Konfigurasi di Sistem

**Opsi A: Global (`.env`)**

```env
MIDTRANS_SERVER_KEY=SB-Mid-server-xxxxx
MIDTRANS_CLIENT_KEY=SB-Mid-client-xxxxx
```

Tambahkan di `config/services.php`:

```php
'midtrans' => [
    'server_key' => env('MIDTRANS_SERVER_KEY'),
    'client_key' => env('MIDTRANS_CLIENT_KEY'),
],
```

**Opsi B: Per Outlet**

Masuk ke pengaturan outlet → tambah setting `midtrans_server_key` dan `midtrans_client_key`.

### 3. Webhook (Notification URL)

Daftarkan URL berikut di Dashboard Midtrans:

```
https://your-domain.com/midtrans/callback
```

Webhook ini menerima POST dari Midtrans saat status pembayaran berubah (settlement, deny, expire, cancel).

---

## Alur Pembayaran QRIS di POS

1. Kasir klik **"Bayar QRIS (Midtrans)"** di panel pembayaran.
2. Frontend request Snap Token via `GET /pos/orders/{order}/snap-token`.
3. `MidtransService::createSnapToken()` memanggil Midtrans Snap API dengan detail order.
4. Snap popup muncul → pelanggan scan QRIS / pilih metode lain.
5. Setelah bayar, Midtrans kirim webhook ke `/midtrans/callback`.
6. `MidtransController::callback()` verifikasi signature → catat pembayaran → update status order.

---

## File Terkait

| File | Fungsi |
|------|--------|
| `app/Services/MidtransService.php` | Komunikasi API Midtrans (create token, verify signature) |
| `app/Http/Controllers/MidtransController.php` | Handle webhook/callback |
| `app/Http/Controllers/POSController.php` | Method `getSnapToken()` untuk POS |
| `config/features.php` | Feature flag `midtrans` |
| `resources/views/pos/index.blade.php` | Tombol "Bayar QRIS" + Snap.js |
| `routes/web.php` | Route `pos.snap-token` dan `midtrans.callback` |

---

## Keamanan

- **Signature Verification:** Setiap callback divalidasi menggunakan SHA-512 (order_id + status_code + gross_amount + server_key).
- **HTTPS wajib** untuk production callback URL.
- **Server Key** tidak boleh di-expose ke frontend; hanya Client Key yang dikirim ke browser.

---

## Menambahkan Gateway Lain

Jika ingin menambahkan gateway selain Midtrans (misal Xendit, DOKU):

1. Buat service baru: `app/Services/XenditService.php`.
2. Buat controller callback: `app/Http/Controllers/XenditController.php`.
3. Tambahkan feature flag di `config/features.php`: `'xendit' => false`.
4. Tambahkan tombol di POS view dengan kondisi `Feature::enabled('xendit', $outlet)`.
5. Daftarkan route callback.

Arsitektur saat ini sudah modular sehingga gateway baru tidak mempengaruhi gateway yang sudah ada.
