# Rencana Arsitektur & Implementasi: Sandbox Mode vs Production Mode
**HizzPay Payment Gateway (hizzpay.com)**  
*Dokumen Perencanaan Teknis & Spesifikasi Pengembang*  
*Kontak Tim Engineering & Support: cs@hizzpay.com*

---

## 1. Ringkasan Eksekutif (Executive Summary)

Sebagai penyedia infrastruktur gerbang pembayaran (*Payment Gateway Aggregator*), **HizzPay** harus memfasilitasi dua lingkungan operasi independen untuk setiap mitra:
1. **Mode Sandbox (Staging / Testing):** Lingkungan uji coba terisolasi di mana pengembang dapat menguji integrasi API, pembuatan tagihan, render UI Snap, dan penerimaan webhook **tanpa memerlukan transfer uang asli**.
2. **Mode Deployment (Production / Live):** Lingkungan transaksi komersial sesungguhnya yang terhubung ke QRIS aktif dan sistem robotik mutasi rekening HizzPay.

Sesuai standar industri modern (seperti Stripe, Midtrans, dan Xendit), pembedaan lingkungan ini didorong oleh **Dual API Keys (Kunci API Ganda)** yang diterbitkan otomatis saat mitra mendaftar.

---

## 2. Perbandingan Spesifikasi: Sandbox vs Production

| Aspek Arsitektur | Mode Sandbox (Uji Coba) | Mode Production (Deployment) |
| :--- | :--- | :--- |
| **Awalan Kunci API (API Key)** | `sb_api_...` | `live_api_...` |
| **Awalan Kunci Rahasia (Secret Key)** | `sb_sec_...` | `live_sec_...` |
| **Uang Riil / Transfer Bank** | **Rp 0 (TIDAK PERLU TRANSFER)** | Wajib ditransfer sesuai total nominal |
| **Payload QRIS yang Dirender** | Dummy QRIS Simulator (*watermarked*) | QRIS Dinamis GoBiz Resmi Platform Owner |
| **Sistem Alokasi Kode Unik** | Alokasi virtual (1 - 999) otomatis lepas | Rentang partisi kode unik terisolasi per mitra |
| **Mekanisme Pelunasan (Settlement)** | **Mock Trigger** via API / Tombol Simulator UI | **Robot Poller Mutasi GoBiz 24/7** |
| **Tanda Tangan Webhook (Signature)** | `HMAC-SHA256(payload, sb_sec_...)` | `HMAC-SHA256(payload, live_sec_...)` |
| **Pencatatan Finansial** | Tabel tagihan bertanda `is_sandbox = TRUE` | Tabel tagihan bertanda `is_sandbox = FALSE` |
| **Tujuan Lingkungan** | Localhost, Staging, QA testing, CI/CD | Website produksi komersial mitra |

---

## 3. Skema Kunci API Ganda (Dual API Key Architecture)

Setiap akun mitra memiliki dua pasang kredensial yang dapat di-generate ulang (*roll/rotate*) kapan saja melalui Developer Portal:

### A. Kredensial Mode Sandbox
- **Sandbox Public/API Key:** Digunakan untuk inisialisasi frontend Snap modal (`HizzPaySnap.pay()`) dan otentikasi request REST API tahap uji coba.
  - Format: `sb_api_` + 32 karakter hex acak  
  - Contoh: `sb_api_9a8f2c4e1b7d5a3f6e8c0b2d4f1a7e9c`
- **Sandbox Secret Key:** Digunakan oleh backend server mitra untuk memverifikasi signature webhook staging.
  - Format: `sb_sec_` + 48 karakter hex acak  
  - Contoh: `sb_sec_e4b1c8f3a9d2e7a5c1b6f0d8e2a4c9f1b7e3d5a8c2f4b0e9`

### B. Kredensial Mode Production (Live)
- **Production Public/API Key:** Digunakan pada domain live toko online mitra yang telah disetujui (*whitelisted*).
  - Format: `live_api_` + 32 karakter hex acak  
  - Contoh: `live_api_1f8b3c9e2a7d4f6a8c0e2b4d6f1a8c3e`
- **Production Secret Key:** Kunci privat dengan hak otorisasi finansial penuh dan penandatanganan webhook produksi.
  - Format: `live_sec_` + 48 karakter hex acak  
  - Contoh: `live_sec_8a3d5e7b1c9f2a4e6c8b0d2f4a1c7e9b3d5f8a0c2e4b6f1a`

---

## 4. Alur Kerja Pengembang (Developer Workflow)

```mermaid
sequenceDiagram
    autonumber
    actor Dev as Developer Mitra
    participant SDK as HizzPay Snap / REST API
    participant Engine as HizzPay Gateway Backend
    participant Sim as Simulator Engine
    participant Poller as GoBiz Poller Robot
    participant PartnerServer as Server Webhook Mitra

    Note over Dev, SDK: FASE 1: INTEGRASI & SANDBOX (Tanpa Uang Asli)
    Dev->>SDK: POST /api/v1/invoices (Authorization: Bearer sb_api_xxx)
    SDK->>Engine: Deteksi prefix "sb_api_" -> Masuk Sandbox Context
    Engine-->>Dev: Response Invoice Sandbox (is_sandbox = true, No QRIS asli)
    Dev->>Sim: POST /api/v1/sandbox/simulate-payment (Invoice No)
    Sim->>Engine: Tandai PAID seketika (Bebas alokasi nominal)
    Engine->>PartnerServer: Dispatch Webhook (Signed with sb_sec_xxx)
    PartnerServer-->>Engine: 200 OK (Status pesanan staging lunas)

    Note over Dev, SDK: FASE 2: DEPLOYMENT KE PRODUCTION (Uang Nyata)
    Dev->>SDK: Ganti kredensial menjadi live_api_xxx
    Dev->>SDK: POST /api/v1/invoices (Authorization: Bearer live_api_xxx)
    SDK->>Engine: Deteksi prefix "live_api_" -> Masuk Production Context
    Engine-->>Dev: Response Invoice Live + Dynamic GoBiz QRIS
    Note over Engine, Poller: Pelanggan scan QRIS & transfer ke akun HizzPay
    Poller->>Engine: Mutasi terdeteksi persis total nominal
    Engine->>PartnerServer: Dispatch Webhook (Signed with live_sec_xxx)
    PartnerServer-->>Engine: 200 OK (Pesanan live diproses)
```

---

## 5. Rencana Perubahan Database (Migration Plan)

Untuk mengaktifkan model Dual API Key, skema tabel `partners` dan `invoices` akan diperbarui:

```sql
-- 1. Tambahkan kolom kunci sandbox pada tabel partners
ALTER TABLE partners 
    ADD COLUMN IF NOT EXISTS api_key_sandbox VARCHAR(64) UNIQUE AFTER api_key,
    ADD COLUMN IF NOT EXISTS secret_key_sandbox VARCHAR(96) AFTER secret_key,
    ADD COLUMN IF NOT EXISTS sandbox_webhook_url VARCHAR(255) AFTER webhook_url;

-- 2. Pastikan kolom is_sandbox pada invoices memiliki index performa
ALTER TABLE invoices 
    ADD COLUMN IF NOT EXISTS is_sandbox BOOLEAN DEFAULT FALSE AFTER status,
    ADD INDEX IF NOT EXISTS idx_invoices_sandbox_partner (partner_id, is_sandbox, status);
```

---

## 6. Rencana Implementasi Middleware Backend (Go Engine)

Middleware otentikasi [`backend/internal/middleware/auth.go`](file:///home/azhar/Documents/project/gobiz-webhook/backend/internal/middleware/auth.go) akan mengekstrak mode eksekusi dari format kunci:

```go
type RequestMode string
const (
    ModeSandbox    RequestMode = "SANDBOX"
    ModeProduction RequestMode = "PRODUCTION"
)

func PartnerAuthMiddleware(partnerRepo *repository.PartnerRepository) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            apiKey := extractToken(r)
            if apiKey == "" {
                respondUnauthorized(w, "API Key is required")
                return
            }

            var mode RequestMode
            var partner *model.Partner
            var err error

            if strings.HasPrefix(apiKey, "sb_api_") {
                mode = ModeSandbox
                partner, err = partnerRepo.GetBySandboxAPIKey(r.Context(), apiKey)
            } else if strings.HasPrefix(apiKey, "live_api_") || !strings.Contains(apiKey, "_") {
                mode = ModeProduction
                partner, err = partnerRepo.GetByAPIKey(r.Context(), apiKey)
            } else {
                respondUnauthorized(w, "Format API Key tidak valid")
                return
            }

            if err != nil || partner == nil {
                respondUnauthorized(w, "Kredensial tidak dikenali")
                return
            }

            // Simpan partner dan context mode ke dalam request context
            ctx := context.WithValue(r.Context(), ContextPartnerKey, partner)
            ctx = context.WithValue(ctx, ContextModeKey, mode)
            next.ServeHTTP(w, r.WithContext(ctx))
        })
    }
}
```

---

## 7. Rencana Antarmuka Portal Mitra (Frontend UI Plan)

Pada Dashboard Mitra ([`frontend/dashboard/developer.html`](file:///home/azhar/Documents/project/gobiz-webhook/frontend/dashboard/developer.html) dan [`index.html`](file:///home/azhar/Documents/project/gobiz-webhook/frontend/dashboard/index.html)):

1. **Header Environment Switcher Pill:**
   Terdapat tombol sakelar status aktif di navbar:
   - `[ Mode Sandbox (Kuning) ]` ⇄ `[ Mode Production (Hijau) ]`
2. **Tab Kredensial Pengembang:**
   - **Tab Sandbox:** Menampilkan `Sandbox API Key`, `Sandbox Secret Key`, dan form pengujian Webhook Callback simulator.
   - **Tab Production:** Menampilkan `Production API Key`, `Production Secret Key`, dan statistik perputaran omzet nyata.
3. **Penyaringan Riwayat Transaksi (`invoices.html`):**
   - Transaksi sandbox ditandai dengan badge `SANDBOX TEST` dan dapat difilter secara terpisah agar tidak mengotori buku besar omzet asli mitra.

---

## 8. Panduan Integrasi Cepat (Quick Integration Snippet)

### Inisialisasi REST API (cURL)

```bash
# 1. Mode Sandbox (Pengujian)
curl -X POST https://api.hizzpay.com/api/v1/invoices \
  -H "Authorization: Bearer sb_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "TEST-ORD-001",
    "base_amount": 50000,
    "customer_name": "Tester Sandbox"
  }'

# 2. Mode Production (Deployment Live)
curl -X POST https://api.hizzpay.com/api/v1/invoices \
  -H "Authorization: Bearer live_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "ORD-LIVE-2026-001",
    "base_amount": 50000,
    "customer_name": "Budi Santoso",
    "return_url": "https://tokosaya.com/selesai"
  }'
```

### Inisialisasi HizzPay Snap Popup (Frontend)

```html
<script src="https://pay.hizzpay.com/snap/snap.js"></script>
<script>
  // Cukup masukkan invoice token yang dihasilkan dari API
  HizzPaySnap.pay("INV-20261004-9a8f", {
    onSuccess: function(result) {
      console.log("Pembayaran selesai:", result);
      window.location.href = "/pesanan-berhasil";
    },
    onPending: function(result) {
      console.log("Menunggu transfer QRIS...", result);
    },
    onExpired: function(result) {
      alert("Waktu pembayaran telah habis.");
    }
  });
</script>
```

---

## 9. Kontak Bantuan Teknis & Korespondensi

Untuk konsultasi integrasi, pengajuan kenaikan limit rate-limit, atau verifikasi akun mitra:
- **Email Layanan Mitra & CS:** `cs@hizzpay.com`
- **Portal Dokumentasi Resmi:** `https://hizzpay.com/docs.html`
- **Pusat Bantuan Teknis:** `https://hizzpay.pages.dev/docs.html`
- **Operasional Perusahaan:** PT HizzPay Digital Nusantara
