# CRM Finance Invoice and Payment Integration Handoff

## Summary

CRM lead invoice creation now follows the retention-style finance workflow:

1. CRM calculates lead-specific pricing, discounts, promo, referral, deposit, and selected payment method.
2. CRM creates a deferred invoice in Finance through `POST /api/v1/integrations/student-bookings/invoices`.
3. CRM attaches its local lead/course/payment metadata to the returned `finanace_student_invoices` record.
4. CRM creates a pending local `crm_transactions` row for the selected payment method.
5. Online payments generate a PayPal link and only post a Finance payment after PayPal confirms approval/completion.
6. InstaPay payments stay pending until an admin approves the transaction; approval posts a Finance payment as `bank_transfer`.

No destructive commands, database refreshes, or reset-style test commands were used.

## Files Added

- `app/Exceptions/FinanceIntegrationException.php`
- `app/Services/Finance/StudentBookingFinanceClient.php`
- `app/Services/CrmFinanceIntegrationService.php`
- `database/migrations/2026_07_29_000000_add_finance_integration_metadata_to_crm_invoices_and_transactions.php`
- `tests/Unit/CrmFinanceIntegrationServiceTest.php`

## Files Updated

- `config/services.php`
- `app/Http/Controllers/Dashboard/Invoice/InvoiceController.php`
- `app/Helpers/PaypalPayment.php`
- `app/Models/FinanaceStudentInvoice.php`
- `routes/web.php`
- `resources/views/dashboard/leads/edit.blade.php`

## Finance API Contract Used

Create deferred invoice:

```http
POST {FINANCE_BASE_URL}/api/v1/integrations/student-bookings/invoices
Idempotency-Key: crm-service:create-invoice:{booking_reference}
api_key: {FINANCE_API_KEY}
X-API-KEY: {FINANCE_API_KEY}
```

Record confirmed payment:

```http
POST {FINANCE_BASE_URL}/api/v1/integrations/invoices/{invoice_id}/payments
Idempotency-Key: crm-service:payment:transaction:{transaction_id}
api_key: {FINANCE_API_KEY}
X-API-KEY: {FINANCE_API_KEY}
```

## Required Environment

```env
FINANCE_BASE_URL=
FINANCE_API_KEY=
FINANCE_SOURCE_SERVICE=crm-service
FINANCE_CURRENCY=USD
FINANCE_TIMEOUT=30
FINANCE_CONNECT_TIMEOUT=10

PAYPAL_BASE_URL=
PAYPAL_CLIENT_ID=
PAYPAL_CLIENT_SECRET=
```

## Idempotency and References

Booking references:

- Course invoice: `crm-lead-{lead_id}-course-{staff_scheduleds_id}-student-{student_id}`
- Product invoice: `crm-lead-{lead_id}-product-{product_id}-student-{student_id}`

Payment references:

- Online: `paypal-order-{paypal_order_id}`
- InstaPay: `instapay-transaction-{transaction_id}`

Source transaction reference:

- `crm-transaction-{transaction_id}`

## Status Mapping

Finance response status is mapped back to CRM invoice status:

- `unpaid` -> `not_paid`
- `partially_paid` -> `paid_deposite`
- `paid` -> `paid`
- `refunded` -> `refunded`
- `voided` -> `rejected`

## UI Changes

The existing lead transactions modal now shows an `Approve` action for pending InstaPay transactions. Approval calls:

```http
POST /invoices/transactions/{transaction}/approve
```

That route records the payment in Finance before marking the CRM transaction as paid.

## Verification Performed

Passed:

```bash
php -l app\Services\CrmFinanceIntegrationService.php
php -l app\Services\Finance\StudentBookingFinanceClient.php
php -l app\Helpers\PaypalPayment.php
php -l app\Http\Controllers\Dashboard\Invoice\InvoiceController.php
php -l app\Models\FinanaceStudentInvoice.php
php -l routes\web.php
php -l database\migrations\2026_07_29_000000_add_finance_integration_metadata_to_crm_invoices_and_transactions.php
php artisan test --filter=CrmFinanceIntegrationServiceTest
```

Blocked:

```bash
php artisan route:list --path=invoices
```

The route-list command failed because of an existing unrelated string controller reference: `FacebookController`.

## Follow-Ups

- Run the additive migration in the target environment after backing up normally.
- Configure Finance and PayPal environment variables before testing invoice creation.
- Test the full browser flow on staging:
  - create online invoice from lead
  - open copied PayPal link
  - confirm PayPal callback updates Finance and CRM
  - create InstaPay transaction
  - approve pending transaction from the transaction modal
- Consider a fuller UI pass later to consolidate invoice creation, payment links, receipt upload, and transaction history into one invoice workspace instead of multiple modals.
