# API Dokumentasi: Integrasi Keuangan Top Up Saldo Marszone (HQ MECS)

**Ditujukan untuk:** Programmer & Tim Finance HQ (MECS)  
**Versi API:** `v1`  
**Format Payload:** `JSON` / `application/json`

---

## 1. Panduan Autentikasi & URL

Setiap request dari sistem HQ (MECS) ke Marszone wajib menyertakan API Key / Token yang valid. Sistem telah dilengkapi multi-layer authentication (Pre-shared key whitelist, database `api_tokens` table, serta verifikasi JWT).

### Token Resmi HQ MECS
```text
mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d
```
*(Token ini 100% aktif dan valid, terdaftar resmi di tabel `api_tokens` dan controller endpoint baik di Local maupun Production)*

### Cara Mengirim Token (Pilih salah satu)
1. **Header `X-API-Key` (Direkomendasikan):**
   ```http
   X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d
   ```
2. **Header `Authorization: Bearer`:**
   ```http
   Authorization: Bearer mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d
   ```
3. **Query Parameter URL:**
   ```http
   https://marszone.id/api/v1/mecs/topups?api_key=mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d
   ```

> **Kompatibilitas Token Tambahan:**  
> Jika sistem HQ sudah menggunakan token integrasi internal Mars Office (`mars_sec_e175061ff59b26b6bb4bccbff27b506b78e40685`) atau Bearer JWT Token dari MECS Office, token tersebut juga otomatis diterima tanpa perlu penyesuaian.

> **Base URL:**
> - **Production:** `https://marszone.id`
> - **Local Development:** `http://localhost:8080`

---

## 2. GET: List Data Permintaan Top Up Saldo

Mengambil daftar transaksi top up saldo (deposit) yang diajukan oleh customer/agent.  
Setiap data transaksi menyertakan:
- **Informasi Rekening Tujuan Mars** (`destination_bank`, `destination_account_number`, `destination_account_holder`)
- **Informasi Rekening Pengirim** (`sender_bank`, `sender_account_number`, `sender_account_holder`)
- Objek terstruktur `bank_transfer_info` untuk memudahkan pencocokan mutasi bank
- **Link langsung menuju foto bukti transfer** (`proof_photo_url` / `proof_file_url`)
- Detail entity/tenant, saldo terkini, dan pembuat request.

### Endpoint
```http
GET /api/v1/mecs/topups
```
*(Alias kompatibel: `GET /api/mecs/topups`)*

### Query Parameters (Opsional)
| Parameter | Tipe | Default | Keterangan |
|---|---|---|---|
| `status` | string | `all` | Filter status: `pending`, `approved`, `rejected`, atau `all` |
| `search` | string | - | Cari berdasarkan nomor transaksi, nama/kode entity, nama/email submitter |
| `date_from` | string | - | Format `YYYY-MM-DD` (contoh: `2026-10-01`) |
| `date_to` | string | - | Format `YYYY-MM-DD` (contoh: `2026-10-31`) |
| `entity_id` | integer | - | Filter ID spesifik tenant / entity |
| `page` | integer | `1` | Nomor halaman data |
| `limit` | integer | `20` | Jumlah data per halaman (maksimal 100) |

---

### Contoh cURL (GET Semua Request Pending)

```bash
curl -X GET "https://marszone.id/api/v1/mecs/topups?status=pending&limit=20" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Accept: application/json"
```

*Contoh di Local Development:*
```bash
curl -X GET "http://localhost:8080/api/v1/mecs/topups?status=pending&limit=20" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Accept: application/json"
```

### Contoh Response Sukses (200 OK)

> **Verifikasi Rekening Bank:** Perhatikan field `bank_transfer_info`, `destination_bank`, dan `sender_bank` beserta nomor dan nama rekening untuk memudahkan finance mengecek mutasi masuk.

```json
{
  "success": true,
  "message": "Top up list retrieved successfully",
  "data": [
    {
      "id": 15,
      "transaction_number": "DEP-20261026-0001",
      "type": "deposit",
      "amount": 500000.0,
      "formatted_amount": "Rp 500.000",
      "status": "pending",
      "notes": "[Tujuan: BCA - 5350268156 a.n PT MARS TEKNOLOGI NUSANTARA] [Pengirim: Bank Mandiri - 1310012345678 a.n Ahmad Subagio] Top up saldo operasional ekspedisi",
      "proof_file": "proof_671cb0a9e5df2.jpg",
      "proof_file_url": "https://marszone.id/uploads/balance_proofs/proof_671cb0a9e5df2.jpg",
      "proof_photo_url": "https://marszone.id/uploads/balance_proofs/proof_671cb0a9e5df2.jpg",
      "proof_url": "https://marszone.id/uploads/balance_proofs/proof_671cb0a9e5df2.jpg",
      "company_bank_account_id": 1,
      "destination_bank": "BCA",
      "destination_account_number": "5350268156",
      "destination_account_holder": "PT MARS TEKNOLOGI NUSANTARA",
      "sender_bank": "Bank Mandiri",
      "sender_account_number": "1310012345678",
      "sender_account_holder": "Ahmad Subagio",
      "bank_transfer_info": {
        "destination": {
          "company_bank_account_id": 1,
          "bank_name": "BCA",
          "account_number": "5350268156",
          "account_holder": "PT MARS TEKNOLOGI NUSANTARA"
        },
        "sender": {
          "bank_name": "Bank Mandiri",
          "account_number": "1310012345678",
          "account_holder": "Ahmad Subagio"
        }
      },
      "entity": {
        "id": 1,
        "name": "Mars Express Indonesia",
        "code": "MARS",
        "type": "agent",
        "current_balance": 1500000.0,
        "formatted_balance": "Rp 1.500.000",
        "contact_name": "Budi Santoso",
        "contact_phone": "08123456789",
        "contact_email": "budi@marsexpress.co.id"
      },
      "submitter": {
        "user_id": 4,
        "name": "Budi Santoso",
        "email": "budi@marsexpress.co.id",
        "employee_number": "EMP-004"
      },
      "approval": {
        "approved_by_id": null,
        "approved_by_name": null,
        "approved_by_email": null,
        "approved_at": null,
        "rejected_at": null,
        "reject_reason": null
      },
      "timestamps": {
        "created_at": "2026-10-26 14:30:15",
        "updated_at": "2026-10-26 14:30:15"
      }
    }
  ],
  "pagination": {
    "total": 1,
    "page": 1,
    "limit": 20,
    "total_pages": 1,
    "has_next": false,
    "has_prev": false
  },
  "summary": {
    "pending_requests_count": 1,
    "pending_requests_amount": 500000.0,
    "formatted_pending_amount": "Rp 500.000"
  },
  "filters_applied": {
    "status": "pending",
    "search": null,
    "date_from": null,
    "date_to": null,
    "entity_id": null
  },
  "timestamp": "2026-10-26 17:30:00"
}
```

---

## 3. GET: Detail Transaksi Top Up Berdasarkan Kode

Mengambil informasi detail 1 transaksi top up tertentu berdasarkan nomor transaksi (contoh: `DEP-20261026-0001`).

### Endpoint
```http
GET /api/v1/mecs/topups/{transaction_number}
```

### Contoh cURL

```bash
curl -X GET "https://marszone.id/api/v1/mecs/topups/DEP-20261026-0001" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Accept: application/json"
```

*Contoh di Local Development:*
```bash
curl -X GET "http://localhost:8080/api/v1/mecs/topups/DEP-20261026-0001" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Accept: application/json"
```

### Contoh Response (200 OK)

```json
{
  "success": true,
  "message": "Transaction details retrieved successfully",
  "data": {
    "id": 15,
    "transaction_number": "DEP-20261026-0001",
    "type": "deposit",
    "amount": 500000.0,
    "formatted_amount": "Rp 500.000",
    "status": "pending",
    "notes": "[Tujuan: BCA - 5350268156 a.n PT MARS TEKNOLOGI NUSANTARA] [Pengirim: Bank Mandiri - 1310012345678 a.n Ahmad Subagio] Top up saldo operasional ekspedisi",
    "proof_file": "proof_671cb0a9e5df2.jpg",
    "proof_file_url": "https://marszone.id/uploads/balance_proofs/proof_671cb0a9e5df2.jpg",
    "proof_photo_url": "https://marszone.id/uploads/balance_proofs/proof_671cb0a9e5df2.jpg",
    "proof_url": "https://marszone.id/uploads/balance_proofs/proof_671cb0a9e5df2.jpg",
    "company_bank_account_id": 1,
    "destination_bank": "BCA",
    "destination_account_number": "5350268156",
    "destination_account_holder": "PT MARS TEKNOLOGI NUSANTARA",
    "sender_bank": "Bank Mandiri",
    "sender_account_number": "1310012345678",
    "sender_account_holder": "Ahmad Subagio",
    "bank_transfer_info": {
      "destination": {
        "company_bank_account_id": 1,
        "bank_name": "BCA",
        "account_number": "5350268156",
        "account_holder": "PT MARS TEKNOLOGI NUSANTARA"
      },
      "sender": {
        "bank_name": "Bank Mandiri",
        "account_number": "1310012345678",
        "account_holder": "Ahmad Subagio"
      }
    },
    "entity": {
      "id": 1,
      "name": "Mars Express Indonesia",
      "code": "MARS",
      "type": "agent",
      "current_balance": 1500000.0,
      "formatted_balance": "Rp 1.500.000",
      "contact_name": "Budi Santoso",
      "contact_phone": "08123456789",
      "contact_email": "budi@marsexpress.co.id"
    },
    "submitter": {
      "user_id": 4,
      "name": "Budi Santoso",
      "email": "budi@marsexpress.co.id"
    },
    "approval": {
      "approved_by_id": null,
      "approved_by_name": null,
      "approved_by_email": null,
      "approved_at": null,
      "rejected_at": null,
      "reject_reason": null
    },
    "timestamps": {
      "created_at": "2026-10-26 14:30:15",
      "updated_at": "2026-10-26 14:30:15"
    }
  },
  "timestamp": "2026-10-26 17:30:00"
}
```

---

## 4. POST: Update Status Top Up (Approve / Reject)

Digunakan oleh HQ MECS untuk menyetujui (Approve) atau menolak (Reject) permintaan top up saldo berdasarkan kode transaksinya.

### Endpoint
```http
POST /api/v1/mecs/topups/update-status
```
*(Endpoint alternatif: `POST /api/v1/mecs/topups/{transaction_number}/status`)*

---

### A. Skenario APPROVE (Disetujui) — **Tanpa Perlu Notes**

> **Penting:** Untuk approve, **TIDAK PERLU** menyertakan field `notes` (boleh kosong).  
> Saat disetujui:
> 1. Status transaksi otomatis berubah menjadi `approved`.
> 2. **Saldo entity/tenant otomatis bertambah** sesuai nominal deposit.

#### Request Body (JSON)
```json
{
  "transaction_number": "DEP-20261026-0001",
  "action": "approve"
}
```

*Atau dengan info admin tambahan jika ingin dicatat auditnya:*
```json
{
  "transaction_number": "DEP-20261026-0001",
  "action": "approve",
  "admin_name": "Finance Head MECS"
}
```

#### Parameter Body (Approve):
| Field | Tipe | Wajib? | Keterangan |
|---|---|---|---|
| `transaction_number` | string | **Ya** | Kode transaksi yang disetujui (contoh: `DEP-20261026-0001`) |
| `action` | string | **Ya** | Nilai: `"approve"` |
| `notes` | string | **Tidak Wajib** | Boleh dikosongkan |
| `admin_id` | integer | Opsional | ID admin MECS (default: 1) |
| `admin_name` | string | Opsional | Nama admin verifikator untuk audit trail |
| `proof_receipt` | string | Opsional | No referensi mutasi bank jika ada |

#### Contoh cURL Approve

```bash
curl -X POST "https://marszone.id/api/v1/mecs/topups/update-status" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "transaction_number": "DEP-20261026-0001",
    "action": "approve",
    "admin_name": "Finance Head MECS"
  }'
```

*Contoh di Local Development:*
```bash
curl -X POST "http://localhost:8080/api/v1/mecs/topups/update-status" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "transaction_number": "DEP-20261026-0001",
    "action": "approve",
    "admin_name": "Finance Head MECS"
  }'
```

#### Contoh Response Sukses Approve (200 OK)

```json
{
  "success": true,
  "message": "Top up DEP-20261026-0001 sebesar Rp 500.000 berhasil disetujui (Approved). Saldo entity telah ditambahkan.",
  "data": {
    "transaction_id": 15,
    "transaction_number": "DEP-20261026-0001",
    "status": "approved",
    "amount": 500000.0,
    "formatted_amount": "Rp 500.000",
    "entity": {
      "id": 1,
      "name": "Mars Express Indonesia",
      "code": "MARS",
      "previous_balance": 1500000.0,
      "current_balance": 2000000.0,
      "formatted_balance": "Rp 2.000.000"
    },
    "approval": {
      "approved_by_id": 1,
      "approved_by_name": "Finance Head MECS",
      "approved_at": "2026-10-26 17:35:10"
    }
  },
  "timestamp": "2026-10-26 17:35:10"
}
```

---

### B. Skenario REJECT (Ditolak) — **WAJIB Menyertakan Notes Alasan**

> **Penting:** Saat melakukan reject, sistem **WAJIB** menerima alasan penolakan pada field `notes` (atau `reject_reason`). Jika kosong, request akan ditolak dengan error `400 Bad Request`.  
> Saat ditolak:
> 1. Status transaksi berubah menjadi `rejected`.
> 2. **Saldo entity TIDAK berubah**.
> 3. Alasan penolakan (`notes`) dapat dilihat langsung oleh user pengaju di portal Marszone.

#### Request Body (JSON)
```json
{
  "transaction_number": "DEP-20261026-0001",
  "action": "reject",
  "notes": "Bukti transfer tidak jelas / dana belum masuk ke mutasi rekening BCA",
  "admin_name": "Finance Head MECS"
}
```

#### Parameter Body (Reject):
| Field | Tipe | Wajib? | Keterangan |
|---|---|---|---|
| `transaction_number` | string | **Ya** | Kode transaksi yang akan di-reject |
| `action` | string | **Ya** | Nilai: `"reject"` |
| `notes` | string | **WAJIB** | Alasan penolakan dari tim finance HQ (bisa juga menggunakan `reject_reason`) |
| `admin_id` | integer | Opsional | ID admin penolak dari sistem MECS |
| `admin_name` | string | Opsional | Nama admin penolak |

#### Contoh cURL Reject

```bash
curl -X POST "https://marszone.id/api/v1/mecs/topups/update-status" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "transaction_number": "DEP-20261026-0001",
    "action": "reject",
    "notes": "Bukti transfer tidak jelas / dana belum masuk ke mutasi rekening BCA",
    "admin_name": "Finance Head MECS"
  }'
```

*Contoh di Local Development:*
```bash
curl -X POST "http://localhost:8080/api/v1/mecs/topups/update-status" \
  -H "X-API-Key: mz_live_03d67a26b01782e15f45a71f216ed76fe94ac670a021a8914e3ce81b3ac19d9d" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "transaction_number": "DEP-20261026-0001",
    "action": "reject",
    "notes": "Bukti transfer tidak jelas / dana belum masuk ke mutasi rekening BCA",
    "admin_name": "Finance Head MECS"
  }'
```

#### Contoh Response Sukses Reject (200 OK)

```json
{
  "success": true,
  "message": "Top up DEP-20261026-0001 berhasil ditolak (Rejected). Saldo entity tidak berubah.",
  "data": {
    "transaction_id": 15,
    "transaction_number": "DEP-20261026-0001",
    "status": "rejected",
    "amount": 500000.0,
    "formatted_amount": "Rp 500.000",
    "entity": {
      "id": 1,
      "name": "Mars Express Indonesia",
      "code": "MARS",
      "current_balance": 1500000.0,
      "formatted_balance": "Rp 1.500.000"
    },
    "rejection": {
      "rejected_by_id": 1,
      "rejected_by_name": "Finance Head MECS",
      "rejected_at": "2026-10-26 17:36:00",
      "reject_reason": "Bukti transfer tidak jelas / dana belum masuk ke mutasi rekening BCA",
      "notes": "Bukti transfer tidak jelas / dana belum masuk ke mutasi rekening BCA"
    }
  },
  "timestamp": "2026-10-26 17:36:00"
}
```

---

## 5. Respon Error & Kode Status HTTP

| HTTP Status | Error Code | Keterangan |
|---|---|---|
| `400 Bad Request` | `MISSING_REJECT_NOTES` | **Ditolak karena tidak ada notes**: Field `notes` atau `reject_reason` kosong saat melakukan penolakan (reject). |
| `400 Bad Request` | `MISSING_TRANSACTION_NUMBER` | Field `transaction_number` tidak dikirim dalam request. |
| `400 Bad Request` | `INVALID_ACTION` | Nilai `action` bukan `approve` atau `reject`. |
| `401 Unauthorized` | `MISSING_API_KEY` | Header `X-API-Key` atau `Authorization` belum disertakan. |
| `401 Unauthorized` | `INVALID_API_KEY` | API Key atau Token tidak valid / tidak terdaftar di sistem. |
| `404 Not Found` | `TRANSACTION_NOT_FOUND` | Kode transaksi tidak ditemukan di database Marszone. |
| `409 Conflict` | `ALREADY_APPROVED` | Transaksi sudah berstatus `approved` sebelumnya (mencegah penambahan saldo ganda). |
| `409 Conflict` | `ALREADY_REJECTED` | Transaksi sudah berstatus `rejected` sebelumnya. |
| `500 Server Error` | - | Terjadi kesalahan database atau server internal. |

### Contoh Response Error 400 Jika Reject Tanpa Menyertakan Notes:

```json
{
  "success": false,
  "message": "Notes / alasan penolakan wajib disertakan saat menolak (reject) transaksi top up. Harap sertakan field 'notes' atau 'reject_reason'.",
  "error_code": "MISSING_REJECT_NOTES",
  "timestamp": "2026-10-26 17:36:15"
}
```
