# Integrasi Midtrans Credit Card (Core API + 3DS)

Dokumen ini merangkum integrasi kartu kredit/debit menggunakan Midtrans Core API dan 3DS, sebagaimana diimplementasikan dalam proyek ini.

## Prasyarat

- Akun Midtrans Sandbox dengan `Client Key` dan `Server Key`.
- Dependensi backend: `express`, `cors`, `dotenv`, `midtrans-client` terpasang.
- Dependensi frontend: loader skrip `MidtransNew3ds` via util `midtrans3ds.ts`.

## Konfigurasi Environment

- Frontend (`.env.local`):
  - `VITE_MIDTRANS_CLIENT_KEY="<client key sandbox>"`
  - `VITE_MIDTRANS_ENV="sandbox"` atau `production`
  - `VITE_API_BASE_URL="http://localhost:8000/api"`

- Backend (`.env`):
  - `MIDTRANS_SERVER_KEY="<server key sandbox>"`
  - `MIDTRANS_CLIENT_KEY="<client key sandbox>"` (opsional, untuk referensi log)
  - `MIDTRANS_IS_PRODUCTION=false`

## Alur Frontend

1. Memuat skrip `MidtransNew3ds` dinamis via `ensureMidtrans3ds()` saat mount `CardPanel`.
2. Mengambil input pengguna: `card_number`, `expiry (MM/YY)`, `cvv`.
3. Validasi minimal: panjang nomor kartu (13–19), bulan 01–12, CVV 3–4.
4. Tokenisasi kartu: `getCardToken({ card_number, card_exp_month, card_exp_year, card_cvv })`.
5. Mengirim `token_id` ke backend melalui `postCharge` dengan payload:

```json
{
  "payment_type": "credit_card",
  "transaction_details": { "order_id": "<orderId>", "gross_amount": <amount> },
  "credit_card": { "token_id": "<tokenId>", "authentication": true, "save_token_id": true|false }
}
```

6. Menangani 3DS: jika respons berisi `redirect_url`, panggil `authenticate3ds(redirect_url)` (SDK akan mengarahkan ke challenge 3DS dan kembali lagi).
7. Mengaktifkan tombol "Cek Status Pembayaran" ketika charge sukses (`capture/settlement`) atau setelah 3DS dimulai (state `locked`).

## Alur Backend

- Endpoint `POST /api/payments/charge`
  - Menggunakan `midtrans-client` CoreApi.
  - Meneruskan payload dari frontend, memastikan `credit_card.authentication = true`.
  - Mengembalikan respons Midtrans termasuk `transaction_status` dan `redirect_url` jika 3DS diperlukan.

- Endpoint `GET /api/payments/:orderId/status`
  - Memanggil `core.status(orderId)` untuk mendapatkan status terbaru transaksi.
  - Digunakan oleh UI untuk halaman status pembayaran.

## Menjalankan Proyek

- Backend: `npm run server` (default pada `http://localhost:8000`).
- Frontend: `npm run dev` lalu buka `http://localhost:5173` (atau port alternatif yang dipilih Vite).

Pastikan `VITE_API_BASE_URL` menunjuk ke `http://localhost:8000/api` agar frontend memanggil backend yang tepat.

## Catatan Keamanan

- Jangan pernah mengekspos `MIDTRANS_SERVER_KEY` di frontend atau file publik.
- Token kartu (`token_id`) hanya diproduksi di frontend melalui `MidtransNew3ds` dan dikirim ke backend yang memegang `serverKey`.

## Referensi

- Midtrans Docs: Credit Card with 3DS (Core API).
- Contoh: `coreApiSimpleExample.js` untuk pola panggilan Core API.

## Webhook & ERP Callback

- Endpoint webhook Midtrans: `POST /api/payments/webhook` (server Express)
  - Verifikasi `signature_key = sha512(order_id + status_code + gross_amount + MIDTRANS_SERVER_KEY)`.
  - Menerima notifikasi status dan menandai sukses untuk `settlement` (umum) atau `capture` dengan `fraud_status=accept` (kartu).
- ERP Notification (opsional, via env feature flag):
  - Konfigurasi `.env` backend:
    - `ERP_NOTIFICATION_URL="https://apibackend.erpskrip.id/paymentnotification/"`
    - `ERP_CLIENT_ID="<dari ERP>"`
    - `ERP_MERCANT_ID="<dari ERP>"`
    - `ERP_ENABLE_NOTIF=true`
  - Payload dikirim saat sukses:
    ```json
    {
      "data": {
        "mercant_id": "<id>",
        "status_code": "200",
        "nominal": "<gross_amount>",
        "client_id": "<id>"
      },
      "signature": "sha512(mercant_id + status_code + nominal + client_id)"
    }
    ```