# STK Push Implementation Summary

## What Was Done
Successfully implemented M-Pesa STK Push (Daraja Sandbox) integration for repayment payments in LendCore.

## API Endpoints
The following M-Pesa callback endpoints are integrated in `routes/api.php` and handled by `app/Http/Controllers/Api/MpesaCallbackController.php`:

- `POST /api/payment/callback` — STK Push callback and manual payment callback handler
- `POST /api/payment/c2b/validation` — C2B validation handler
- `POST /api/payment/c2b/confirmation` — C2B confirmation handler
- `POST /api/payment/b2c/result` — B2C result callback handler
- `POST /api/payment/b2c/timeout` — B2C timeout callback handler
- `POST /api/payment/register-callbacks` — Admin route to register C2B callback URLs with Safaricom (requires auth:sanctum and admin middleware)

## Changes Made

### 1. Config Update (`config/mpesa.php`)
- Added `stkpush` endpoint configuration for sandbox and production environments
- Added dedicated `callback_url` configuration value for STK callback delivery
- Endpoint: `https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest`

### 2. MpesaService Enhancement (`app/Services/MpesaService.php`)
- Implemented `sendStkPush()` method that:
  - Accepts phone number, amount, account reference, and transaction description
  - Generates timestamp-based password using base64(shortcode + passkey + timestamp)
  - Sends STK Push request to M-Pesa Daraja API
  - Includes the dedicated STK callback URL in `CallBackURL`
  - Returns `CheckoutRequestID` and `MerchantRequestID`

### 3. RepaymentController Update (`app/Http/Controllers/Web/RepaymentController.php` and `app/Http/Controllers/Api/RepaymentController.php`)
- `processPayment()` now:
  - Creates a pending payment transaction first
  - Uses a unique STK payment reference for clearer callback tracking
  - Calls `MpesaService::sendStkPush()` with user's phone and amount
  - Stores `CheckoutRequestID` in the transaction for callback matching
  - Returns a user-friendly response when the STK prompt is sent
  - Handles failures by marking transactions as failed and storing callback data

### 4. Unique STK Payment Naming
- Added `TransactionService::makeStkRepaymentReference()`
- New reference format: `STK Callback Loan #<loan_id> Repayment #<repayment_id>-<sequence>`
- Account reference sent to M-Pesa is now `STK-RP-<repayment_id>`

### 5. Callback Handler Flow (`app/Http/Controllers/Api/MpesaCallbackController.php`)
- Detects STK callback by `Body.stkCallback` in payload
- Extracts `CheckoutRequestID`, `MerchantRequestID`, `ResultCode`, `Amount`, `MpesaReceiptNumber`, and `CallbackMetadata`
- Finds the pending transaction using `TransactionService::findByCheckoutRequestId()`
- Adds explicit STK callback metadata fields: `callback_type: 'stkcallback'` and `stk_callback: true`
- For payment transactions, calls `RepaymentService::processMpesaPaymentCallback()` to complete the payment
- Updates transaction status, M-Pesa details, and callback data
- Logs the callback processing in the audit trail with loan and transaction context

## Test Results
All existing tests pass:
- ✓ M-Pesa STK callback updates payment transaction by `CheckoutRequestID`
- ✓ M-Pesa disbursement callback activates approved loan
- ✓ Admin can register C2B callback URLs

## Payment Flow (End-to-End)
1. User navigates to repayment pay page
2. User enters amount and phone number
3. `processPayment()` creates a pending transaction and sends STK Push
4. M-Pesa sends prompt to the user's phone
5. User enters M-Pesa PIN
6. M-Pesa sends callback to `/api/payment/callback`
7. Handler finds the transaction by `CheckoutRequestID`
8. Handler completes the payment and updates the repayment
9. Transaction is marked completed with M-Pesa details

## Key Data Mapping
- Transaction `checkout_request_id`: used to match callbacks to pending transactions
- Transaction `mpesa_code`: stores `MerchantRequestID` from STK response
- Transaction `mpesa_transaction_id`: populated with `MpesaReceiptNumber` from callback
- Unique STK reference: `STK Callback Loan #<loan_id> Repayment #<repayment_id>-<sequence>`

## Notes
- Ensure `.env` includes `MPESA_CALLBACK_URL` pointing to the STK callback endpoint (e.g. `https://<ngrok>/api/payment/callback`).
- `CallBackURL` in the STK push request is now sourced from `config('mpesa.callback_url')`, making the callback endpoint explicit in the payload.
