# Stripe Payment System Implementation

## Overview

The True Trucker platform now supports recurring Stripe payments for driver packages. The system:

- **Charges companies** monthly or weekly based on their driver package selection
- **Calculates billing** using: `base_price + (driver_count * price_per_driver)`
- **Handles pro-rated charges** when driver count changes mid-billing cycle
- **Manages subscriptions** with automatic billing and retry logic

## System Architecture

### Core Services

#### 1. `StripeService` (app/Services/StripeService.php)
Handles all Stripe API interactions:
- `createCustomer()` - Create Stripe customer for subscription
- `createSubscription()` - Create recurring Stripe subscription
- `chargeSubscription()` - Create invoice and process payment
- `updateSubscriptionForDriverChange()` - Update charges when drivers added/removed
- `handlePaymentSuccess()` - Process successful payment webhooks
- `handlePaymentFailure()` - Process failed payment webhooks
- `retryPayment()` - Retry failed payments
- `cancelSubscription()` - Cancel Stripe subscription

#### 2. `BillingService` (app/Services/BillingService.php)
Handles billing logic:
- `calculateBillingAmount()` - Calculate total billing amount
- `calculateProratedAmount()` - Calculate pro-rated adjustments for mid-cycle changes
- `getNextBillingDate()` - Determine next billing date based on cycle
- `isSubscriptionDueForBilling()` - Check if subscription needs billing
- `getSubscriptionsDueForBilling()` - Get all subscriptions due for this billing cycle
- `processBilling()` - Process a single subscription billing
- `handleDriverCountChange()` - Handle driver count changes and proration
- `generateInvoiceSummary()` - Generate invoice summary data

### Database Schema

#### Packages Table (New Fields)
```sql
- base_price (decimal) - Base cost per billing cycle
- price_per_driver (decimal) - Cost per driver per billing cycle
- billing_cycle (string) - 'monthly' or 'weekly'
```

#### Subscriptions Table (New Fields)
```sql
- stripe_customer_id (string) - Stripe customer ID
- stripe_subscription_id (string) - Stripe subscription ID
- next_billing_date (datetime) - Next scheduled billing date
- billing_cycle (string) - 'monthly' or 'weekly'
- last_driver_count (integer) - Last recorded driver count (for tracking changes)
```

#### Payments Table (New Fields)
```sql
- invoice_amount (decimal) - Invoiced amount based on actual driver count
- driver_count (integer) - Number of drivers charged for
- billing_period_start (datetime) - Billing period start date
- billing_period_end (datetime) - Billing period end date
```

### Scheduled Commands

#### 1. `billing:process-recurring-payments` (Daily at 2 AM)
- Finds all subscriptions due for billing
- Calculates amount based on current driver count
- Creates invoice and payment records
- Processes with Stripe

**Usage:**
```bash
php artisan billing:process-recurring-payments
```

#### 2. `billing:update-driver-charges` (Daily at 1 AM)
- Checks for driver count changes in active subscriptions
- Updates Stripe subscription metadata
- Calculates pro-rated adjustments

**Usage:**
```bash
php artisan billing:update-driver-charges
```

## Billing Calculation

### Basic Formula
$$\text{Monthly Amount} = \text{Base Price} + (\text{Driver Count} \times \text{Price Per Driver})$$

### Example
- Package: Professional
- Base Price: $50/month
- Price Per Driver: $15/driver/month
- Current Driver Count: 5
- **Monthly Charge: $50 + (5 × $15) = $125**

### Pro-rated Charges
When driver count changes mid-billing cycle:

$$\text{Prorated Amount} = \frac{\text{Driver Difference} \times \text{Price Per Driver} \times \text{Days Remaining}}{\text{Days in Cycle}}$$

**Example:**
- 2 new drivers added on day 15 of 30-day cycle
- Price per driver: $15
- Days remaining: 15
- **Prorated charge: $(2 × $15 × 15) / 30 = $15**

## Payment Flow

### 1. Package Selection
```
User selects package → Package has billing_cycle, base_price, price_per_driver
```

### 2. Subscription Creation
```
POST /subscriptions
- Creates database subscription record
- Sets status = 'pending', payment_status = 'pending'
- Stores package_id and billing_cycle
```

### 3. Create Stripe Subscription
```
POST /payments/subscription/{subscription}/create-stripe
- Creates Stripe customer
- Gets/creates Stripe product for package
- Creates recurring Stripe subscription
- Updates subscription with stripe_customer_id and stripe_subscription_id
- Sets next_billing_date
```

### 4. Automatic Billing (Daily)
```
Command runs: billing:process-recurring-payments
- Finds subscriptions where next_billing_date <= now()
- Calculates amount = base_price + (driver_count × price_per_driver)
- Creates invoice via Stripe
- Records Payment in database
- Updates next_billing_date
```

### 5. Webhook Handling
```
Stripe sends webhook → /payments/webhook/stripe
- Parses Stripe event signature
- Handles 'invoice.payment_succeeded' events
- Updates Payment status to 'completed'
- Updates Subscription payment_status and amount_paid
```

### 6. Retry Failed Payments
```
POST /payments/{payment}/retry
- Updates payment status to 'pending'
- Stripe retries payment on next retry cycle
```

## Driver Count Changes

### When Driver is Added
1. Driver created in database
2. Subscription checks if over driver_limit - blocks if needed
3. Next billing cycle uses new driver count
4. OR: Pro-rated charge applied immediately if mid-cycle

### Update Charges For Driver Changes
```
POST /payments/subscription/{subscription}/update-driver-changes
- Gets current driver count
- Compares to last_driver_count in subscription
- Calculates prorated adjustment
- Updates Stripe subscription metadata
- Updates subscription.last_driver_count
```

## Environment Configuration

Add to `.env`:

```env
STRIPE_PUBLIC_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
```

## Controller Methods

### PaymentController

#### `createStripeSubscription(Request $request, Subscription $subscription)`
- Creates Stripe subscription for a pending subscription
- Updates subscription status to 'active'
- Sets next billing date

**Route:** `POST /payments/subscription/{subscription}/create-stripe`

#### `updateSubscriptionDriverChanges(Subscription $subscription)`
- Updates Stripe subscription when driver count changes
- Handles pro-rated calculations

**Route:** `POST /payments/subscription/{subscription}/update-driver-changes`

#### `retryPayment(Payment $payment)`
- Retries a failed payment

**Route:** `POST /payments/{payment}/retry`

#### `stripeWebhook(Request $request)`
- Handles Stripe webhooks
- Processes: `invoice.payment_succeeded`, `invoice.payment_failed`

**Route:** `POST /payments/webhook/stripe`

## Error Handling

### Failed Payments
- Payment status set to 'failed'
- Failure reason recorded
- Subscription payment_status updated
- Retry can be triggered manually or automatically by Stripe

### Subscriptions Over Driver Limit
- Driver creation returns 422 error
- Message: "Driver limit reached for your current package"
- User cannot add more drivers until:
  - Subscription upgraded to higher tier
  - Current drivers removed

## Admin Dashboard

Admin can:
- View all payments in `/admin/payments`
- View payment details
- Update payment status manually
- View payment method connections
- Test payment method connectivity

## API Integration

### Mobile App
```javascript
// Check subscription status
GET /api/subscriptions/{id}

// Get invoice summary
GET /api/subscriptions/{id}/invoice

// Driver creation (returns 422 if limit reached)
POST /api/fleet/drivers
```

### Response Format
**Success (201):**
```json
{
  "id": "driver-uuid",
  "user_id": "user-uuid",
  "company_id": "company-uuid",
  "first_name": "John",
  "last_name": "Doe"
}
```

**Error - Limit Reached (422):**
```json
{
  "success": false,
  "message": "Driver limit reached for your current package."
}
```

## Monitoring & Logs

Check logs for:
```bash
# Billing command logs
tail -f storage/logs/laravel.log | grep "Billing\|billing"

# Stripe errors
tail -f storage/logs/laravel.log | grep "Stripe"

# Failed payments
tail -f storage/logs/laravel.log | grep "Payment\|payment"
```

## Testing

### Test Stripe Subscription Creation
```bash
# In Laravel Tinker:
$subscription = Subscription::find(1);
$stripeService = app(\App\Services\StripeService::class);
$stripeId = $stripeService->createSubscription($subscription);
```

### Test Billing Calculation
```bash
$billingService = app(\App\Services\BillingService::class);
$package = Package::find(1);
$amount = $billingService->calculateBillingAmount($package, 5); // 5 drivers
```

### Manual Billing Run
```bash
php artisan billing:process-recurring-payments
php artisan billing:update-driver-charges
```

## Future Enhancements

1. **Dunning Management** - Automatic retry strategies for failed payments
2. **Usage Reports** - Monthly invoice PDFs
3. **Promotional Codes** - Discount calculation logic
4. **Bulk Invoice Export** - For accounting systems
5. **Payment Methods** - PayPal and Wise integration
6. **Subscription Management UI** - Upgrade/downgrade packages
7. **Usage Analytics** - Track driver additions/removals
