Lewati ke isi

Sentra Rental — API Documentation

Semua response menggunakan format REST JSON. Otorisasi via JWT bearer token. Booking endpoint mengacquire Redis Redlock sebelum membuat draft transaksi.

5.1 POST /api/v1/bookings

Membuat draf booking baru dan langsung mengunci aset terpilih di Redis selama proses pembayaran.

  • Request Headers: Authorization: Bearer <JWT_TOKEN>
  • Request Payload (JSON):
{
  "branch_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "items": [
    {
      "asset_id": "4a71b3e8-5b12-42da-8789-22a4bbbb9988",
      "start_time": "2026-05-25T08:00:00+07:00",
      "end_time": "2026-05-27T17:00:00+07:00"
    }
  ]
}
  • Response Success (201 Created):
{
  "success": true,
  "message": "Booking draft created and asset locked",
  "data": {
    "booking_id": "e38a2e5d-16f3-4a1b-93ff-d9c02ff8812c",
    "booking_code": "SR/20260521/00042",
    "rental_amount": 1000000.00,
    "deposit_amount": 500000.00,
    "ppn_amount": 110000.00,
    "total_bill": 1610000.00,
    "expires_at": "2026-05-21T20:34:49+07:00"
  }
}
  • Error (409 Conflict) — Redlock tidak dapat di-acquire:
{
  "success": false,
  "error": "ASSET_LOCKED",
  "message": "Aset sedang dipesan oleh pengguna lain. Silakan tunggu 10 menit."
}

5.2 POST /api/v1/handovers/check-out

Digunakan oleh petugas lapangan (Inspector) untuk mendokumentasikan kondisi barang saat diserahkan ke pelanggan. Payload multipart karena menyertakan foto.

  • Request Payload (Multipart Form Data):
  • booking_id: e38a2e5d-16f3-4a1b-93ff-d9c02ff8812c
  • asset_id: 4a71b3e8-5b12-42da-8789-22a4bbbb9988
  • checklist: { "cleanliness": "CLEAN", "scratch_detected": false, "fuel_level": "80%", "electrical_check": "PASS" }
  • photos: Binary images (multi-upload ke S3, maks 10 foto)
  • signature: File SVG/PNG tanda tangan pelanggan

  • Response Success (200 OK):

{
  "success": true,
  "message": "Check-out inspection successfully recorded. Asset status set to DISPATCHED.",
  "data": {
    "inspection_id": "77df01e8-765f-4621-bc74-1234bc5678ab",
    "tamper_proof_hash": "a45f9d2a33ec6b1d1f22e89d892d19283f9829cdcdab3818e901a9bf1c19b889"
  }
}

5.3 POST /api/v1/handovers/check-in

Merekam pengembalian unit, menghitung denda keterlambatan dan kerusakan jika ada, serta menginisiasi proses deposit settlement.

  • Request Payload (Multipart Form Data):
  • booking_id: e38a2e5d-16f3-4a1b-93ff-d9c02ff8812c
  • asset_id: 4a71b3e8-5b12-42da-8789-22a4bbbb9988
  • actual_return_time: 2026-05-27T19:30:00+07:00 — terlambat 2 jam 30 menit
  • checklist: { "cleanliness": "DIRTY_NEED_WASH", "scratch_detected": true, "scratch_details": "Baret baru di bemper kiri depan 10cm" }
  • photos: Binary images bukti baret
  • signature: File SVG/PNG tanda tangan inspektur & customer

  • Response Success (200 OK):

{
  "success": true,
  "message": "Check-in recorded. Late fees and damages calculated.",
  "data": {
    "late_duration_minutes": 150,
    "late_fee": 150000.00,
    "damage_fee": 250000.00,
    "total_penalties": 400000.00,
    "deposit_action": "PARTIAL_REFUND",
    "remaining_deposit_refunded": 100000.00
  }
}

5.4 GET /api/v1/assets/:sku/calendar

Mengembalikan matrix ketersediaan aset berdasarkan SKU untuk bulan tertentu. Data dibaca dari Redis bitmask (cache-first), fallback ke PostgreSQL jika cache miss.

  • Query Params: year=2026&month=05&branch_id=<UUID>
  • Response Success (200 OK):
{
  "success": true,
  "data": {
    "sku": "TOY-AVNZ-G",
    "month": "2026-05",
    "availability": {
      "1": "AVAILABLE",
      "2": "AVAILABLE",
      "24": "BOOKED",
      "25": "BOOKED",
      "26": "MAINTENANCE"
    }
  }
}

5.5 POST /api/v1/deposits/:deposit_id/release

Melepaskan sisa deposit ke rekening/e-wallet pelanggan setelah penghitungan denda final selesai.

  • Request Body (JSON):
{
  "damage_fee": 350000.00,
  "late_fee": 0.00,
  "notes": "Baret bemper depan panel kiri"
}
  • Response Success (200 OK):
{
  "success": true,
  "data": {
    "deposit_id": "...",
    "amount_held": 500000.00,
    "deducted": 350000.00,
    "refunded": 150000.00,
    "gateway_refund_ref": "XENDIT-REF-XXXXXXXXXXX",
    "deposit_status": "CLAIMED_FOR_DAMAGES"
  }
}