# Pesapal 3.0 Payment Gateway & Finance Architecture

Pesapal is the primary digital payment gateway for online direct bookings and contactless guest payments at Calian Hotel.

---

## 1. Pesapal 3.0 API Architecture

```text
[ Guest Browser ]
        │ 1. Submits Booking & Selects Pesapal
        ▼
[ Calian Server: PesapalV3PaymentService ]
        │ 2. Obtains Bearer Token (Cached 4.5 minutes) via /api/Auth/RequestToken
        │ 3. Submits Order Request via /api/Transactions/SubmitOrder-json
        ▼
[ Pesapal Gateway API ]
        │ 4. Returns redirect_url and order_tracking_id
        ▼
[ Guest Completes Payment on Pesapal Modal/Page (MTN/Airtel MoMo, Visa, Mastercard) ]
        │
        ▼
[ Pesapal IPN Notification Endpoint: POST /api/payments/pesapal/ipn ]
        │ 5. Validates IPN signature & queries transaction status via /api/Transactions/GetTransactionStatus
        │ 6. Updates Payment record idempotently (marks Completed, updates Folio & Booking)
        ▼
[ Guest Redirected to /booking/confirmation?tracking_id=xxx ]
```

---

## 2. Security & Idempotency Rules

1. **Never trust return redirect URLs blindly:** The return URL only initiates a backend status check. A booking is ONLY marked `Paid` upon verified IPN receipt or verified backend API query.
2. **Idempotent processing:** IPN handlers check `pesapal_transactions.is_verified` and existing ledger entries to guarantee duplicate notifications do not double-credit guest folios.
3. **Environment switching:** Admin panel supports seamless toggling between Sandbox (`https://cybqa.pesapal.com/pesapalv3`) and Live (`https://pay.pesapal.com/v3`).

---

## 3. Offline Payment & Cashier Shifts

- Staff can record offline settlements: `Cash`, `MTN Mobile Money`, `Airtel Money`, `Bank Wire Transfer`, `Physical POS Card`, and `Corporate Credit`.
- All offline entries are attached to the logged-in staff member's active `CashierShift`.
- Shifts calculate opening float, expected collection vs actual counted cash, and log variances with supervisor sign-off.
