# Multi-Gateway Payment Architecture & Ghanaian Commerce

This document details the multi-gateway payment subsystem, Mobile Money integrations, Paystack card processing, public invoice lookup, and transactional reconciliation guarantees implemented across the Eniceberny platform.

---

## 1. Architectural Strategy & Gateway Abstraction

Payment gateways in Eniceberny are designed using the Driver / Manager pattern, ensuring that adding new payment aggregators (e.g. Hubtel, Slydepay, ExpressPay) requires zero changes to core checkout or POS workflows:

```mermaid
sequenceDiagram
    autonumber
    actor Patron as Patron / Cashier
    participant Store as Checkout / POS Controller
    participant Manager as PaymentManager
    participant Driver as PaymentGatewayDriver
    participant Gateway as Paystack / MoMo Network
    participant DB as Relational Database

    Patron->>Store: Submit Order & Choose Payment Method
    Store->>Manager: driver($method)
    Manager->>Driver: initiatePayment($order, $payload)
    alt Paystack / MoMo Redirect
        Driver->>Gateway: Initialize Transaction API
        Gateway-->>Driver: Return Auth URL / USSD Prompt
        Driver-->>Store: Return Redirect / Instructions
        Store-->>Patron: Forward to Payment Screen
        Gateway-->>Driver: Webhook Event (charge.success)
        Driver->>DB: Verify Signature & Mark Order 'paid'
    else Physical Cash / Counter MoMo
        Driver->>DB: Log Transaction 'pending' (or 'success' for POS)
        DB-->>Store: Order Confirmed
        Store-->>Patron: Display Receipt & QR Code
    end
```

### Gateway Contract:
All payment providers adhere strictly to `App\Services\Payments\PaymentGatewayInterface`:

```php
namespace App\Services\Payments;

use App\Models\Order;

interface PaymentGatewayInterface
{
    /**
     * Initiate payment processing with the gateway.
     */
    public function initiatePayment(Order $order, array $payload = []): array;

    /**
     * Query gateway to verify settlement status.
     */
    public function verifyPayment(string $reference): array;

    /**
     * Process full or partial refund.
     */
    public function refund(Order $order, ?float $amount = null, ?string $reason = null): bool;
}
```

---

## 2. Supported Payment Methods in Ghana

### 2.1 Cash on Delivery & Counter Cash (`cash`)
- **Online Checkout**: Customer chooses "Cash on Delivery" or "Pay upon In-Store Collection".
  - Order is placed with `payment_status: 'pending'`.
  - Upon delivery by the dispatch rider or patron pickup, staff marks the order paid via the Admin Order console.
- **In-Store POS**: Cashier tenders physical notes, calculates change, and completes the sale atomically with `payment_status: 'paid'`.

### 2.2 Mobile Money Direct & USSD Push (`momo`)
Mobile Money is the primary consumer payment rail in Ghana:
- **Networks Supported**: MTN Mobile Money, Telecel Cash, AT Money.
- **Storefront Checkout**:
  - The patron enters their 10-digit Ghanaian mobile number.
  - The system records a unique payment reference (`EB-MOMO-XXXXXX`) and instructs the patron to authorize the USSD prompt on their handset.
  - Verification occurs either automatically via network callback or manually by entering the telecom transaction ID.

### 2.3 Paystack Cards & Digital Wallets (`paystack`)
- **Payment Instruments**: Visa, Mastercard, Verve, and instant Paystack Mobile Money.
- **Server-Side Security**: Orders are **never** marked paid simply because a user's browser redirected to a success URL. All settlements require cryptographic verification.

---

## 3. Webhook Architecture & Cryptographic Signature Verification

Paystack dispatches automated HTTP POST notifications when transactions are completed.

### Webhook Verification Workflow:
1. Paystack sends a POST request to `/api/v1/payments/webhook` with the header `X-Paystack-Signature`.
2. The middleware computes the HMAC SHA512 hash of the raw incoming request body using the configured secret key:
   ```php
   $computedSignature = hash_hmac('sha512', $request->getContent(), config('services.paystack.secret_key'));
   if (!hash_equals($computedSignature, $request->header('X-Paystack-Signature', ''))) {
       Log::warning('Paystack webhook rejected: Invalid signature');
       return response()->json(['error' => 'Invalid signature'], 401);
   }
   ```
3. **Idempotency Guarantee**: If the webhook references an order that is already marked `paid`, the system acknowledges HTTP 200 without executing duplicate inventory or notification side-effects.
4. **Order Status Progression**:
   - Order `payment_status` updates to `paid`.
   - `PaymentTransaction` record created with provider reference and fee breakdown.
   - An immutable audit trail entry is logged.
   - Order confirmation email with attached PDF receipt is automatically dispatched.

---

## 4. Public Invoice Lookup & Balance Settlement (`/invoices`)

For corporate catering clients, custom cake orders, and telephone bookings, the platform provides a self-service public invoice lookup portal:

- **Lookup URL**: `GET /invoices`
- **Search Parameters**: Patrons can look up any order or proposal using either:
  1. Official Order / Invoice Number (e.g. `EB-20260927-1402`)
  2. Customer Telephone Number (e.g. `0532342126` or `+233532342126`)
- **Detailed Invoice View (`/invoices/{order_number}`)**:
  - Displays business branding crest, hotlines, and address.
  - Shows line items, itemized rates, delivery fees, and discounts.
  - Real-time payment status badge (`PAID`, `PARTIALLY PAID`, `UNPAID`).
  - Single-click **"Pay Online Now"** button launching instant Paystack checkout for outstanding balances.
  - Bank and Mobile Money remittance instructions for direct offline bank wire transfers.

---

## 5. Automated PDF Invoicing & QR Code Engine

Receipts and invoices can be downloaded or emailed as high-resolution PDF documents:

### Technical Stack:
- **DomPDF (`barryvdh/laravel-dompdf`)**: Renders HTML/Blade templates into crisp PDF documents.
- **Standalone QR Code Generator (`chillerlan/php-qrcode`)**: Generates offline base64 PNG QR code data streams embedded directly into the PDF:
  ```php
  $qrCodeData = (new QRCode)->render(route('orders.receipt', $order->order_number));
  ```

### Automated Dispatch:
- An automated PDF receipt (`Receipt-EB-*.pdf`) is attached to:
  - `OrderPlacedReceiptMail`: Dispatched immediately upon order placement.
  - `OrderStatusUpdatedMail`: Dispatched whenever an order status transitions to `completed` or `delivered`.
- Store managers can also dispatch receipts on demand via the **"Send Email Receipt (PDF Attached)"** action in `/admin/orders/{id}`.

---

## 6. Financial Integrity & Decimal Precision

To eliminate floating-point rounding errors and ensure compliance with accounting standards:
1. **Database Types**: All monetary columns (`orders.subtotal`, `orders.delivery_fee`, `orders.tax_amount`, `orders.discount_amount`, `orders.total`, `payment_transactions.amount`) use `DECIMAL(10, 2)`.
2. **Display Helper**: Amounts are formatted consistently across templates using `format_currency($amount)` (e.g. `GH₵ 125.00`) with `font-sans font-bold tabular-nums` to ensure scannable visual alignment.
3. **Database Transactions**: All financial modifications are enclosed within `DB::transaction()` to guarantee atomicity.
