# Mobile API - Payment & Billing Integration

## Overview

The mobile API includes subscription and payment endpoints for companies to manage their billing directly from the app.

## Endpoints

### Get Subscriptions

**Endpoint:**
```
GET /api/subscriptions
```

**Headers:**
```
Authorization: Bearer {jwt_token}
Content-Type: application/json
```

**Response (200 OK):**
```json
{
  "data": [
    {
      "id": 1,
      "user_id": 1,
      "package_id": 1,
      "status": "active",
      "payment_status": "completed",
      "started_at": "2026-01-01T00:00:00Z",
      "ends_at": null,
      "next_billing_date": "2026-02-01T00:00:00Z",
      "amount_paid": 240.00,
      "package": {
        "id": 1,
        "name": "Startup Package",
        "driver_limit": 5,
        "truck_limit": 2,
        "base_price": "30.00",
        "price_per_driver": "10.00",
        "billing_cycle": "monthly"
      }
    }
  ]
}
```

---

### Get Subscription Details

**Endpoint:**
```
GET /api/subscriptions/{id}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "user_id": 1,
  "package_id": 1,
  "status": "active",
  "payment_status": "completed",
  "started_at": "2026-01-01T00:00:00Z",
  "ends_at": null,
  "next_billing_date": "2026-02-01T00:00:00Z",
  "amount_paid": 240.00,
  "stripe_customer_id": "cus_...",
  "stripe_subscription_id": "sub_...",
  "billing_cycle": "monthly",
  "package": {
    "id": 1,
    "name": "Startup Package",
    "description": "Perfect for small operations",
    "driver_limit": 5,
    "truck_limit": 2,
    "base_price": "30.00",
    "price_per_driver": "10.00",
    "billing_cycle": "monthly",
    "features": ["Feature 1", "Feature 2"]
  }
}
```

---

### Get Invoice Summary

**Endpoint:**
```
GET /api/subscriptions/{id}/invoice
```

**Response (200 OK):**
```json
{
  "package_name": "Startup Package",
  "billing_cycle": "monthly",
  "next_billing_date": "2026-02-01T00:00:00Z",
  "base_price": 30.00,
  "driver_count": 3,
  "price_per_driver": 10.00,
  "driver_charges": 30.00,
  "total_amount": 60.00
}
```

**Usage Example:**
```
Current subscription has 3 drivers:
- Base: $30
- Drivers: 3 × $10 = $30
- Next billing: $60 on Feb 1, 2026
```

---

### Create Subscription

**Endpoint:**
```
POST /api/subscriptions
```

**Request:**
```json
{
  "package_id": 1
}
```

**Response (201 Created):**
```json
{
  "id": 2,
  "user_id": 1,
  "package_id": 1,
  "status": "pending",
  "payment_status": "pending",
  "started_at": null,
  "ends_at": null,
  "next_billing_date": null,
  "amount_paid": 0.00,
  "message": "Subscription created. Please complete payment."
}
```

---

### Get Payment Methods

**Endpoint:**
```
GET /api/payment-methods
```

**Response (200 OK):**
```json
{
  "data": [
    {
      "id": 1,
      "name": "Stripe",
      "provider": "stripe",
      "description": "Stripe recurring billing",
      "is_active": true
    }
  ]
}
```

---

### Initiate Checkout

**Endpoint:**
```
POST /api/payments/checkout
```

**Request:**
```json
{
  "subscription_id": 2,
  "payment_method_id": 1
}
```

**Response (200 OK):**
```json
{
  "checkout_url": "https://yourapp...checkout/2",
  "subscription_id": 2,
  "amount": 60.00,
  "currency": "usd",
  "payment_method": "stripe",
  "message": "Proceed to checkout"
}
```

---

### Process Payment

**Endpoint:**
```
POST /api/payments/process
```

**Request:**
```json
{
  "subscription_id": 2,
  "payment_method_id": 1,
  "payment_token": "tok_..." // From Stripe
}
```

**Response (201 Created):**
```json
{
  "payment_id": 1,
  "subscription_id": 2,
  "status": "pending",
  "amount": 60.00,
  "transaction_id": "in_...",
  "message": "Payment initiated"
}
```

**Response Error (422):**
```json
{
  "success": false,
  "message": "Payment failed: Card was declined"
}
```

---

### Get Payment Status

**Endpoint:**
```
GET /api/payments/{id}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "subscription_id": 2,
  "payment_method_id": 1,
  "amount": 60.00,
  "invoice_amount": 60.00,
  "driver_count": 3,
  "billing_period_start": "2026-02-01T00:00:00Z",
  "billing_period_end": "2026-02-28T23:59:59Z",
  "status": "completed",
  "transaction_id": "in_...",
  "processed_at": "2026-02-01T08:30:00Z",
  "failure_reason": null
}
```

---

### Get Payment List

**Endpoint:**
```
GET /api/payments
```

**Query Parameters:**
- `page` (optional, default: 1)
- `per_page` (optional, default: 15)

**Response (200 OK):**
```json
{
  "data": [
    {
      "id": 1,
      "subscription_id": 2,
      "amount": 60.00,
      "status": "completed",
      "processed_at": "2026-02-01T08:30:00Z"
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 15,
    "total": 10
  }
}
```

---

## Payment Status Codes

| Status | Meaning | Next Action |
|--------|---------|-------------|
| `pending` | Payment initiated, awaiting Stripe confirmation | Wait for webhook |
| `completed` | Payment succeeded | Subscription activated |
| `failed` | Payment declined | Retry with different card |
| `refunded` | Payment refunded | Contact support |

---

## Driver Limit Errors

### When Adding Driver Over Limit

**Endpoint:**
```
POST /api/fleet/drivers
```

**Error Response (422):**
```json
{
  "success": false,
  "message": "Driver limit reached for your current package.",
  "current_drivers": 5,
  "package_limit": 5
}
```

**Mobile App Handling:**
```javascript
if (response.status === 422 && response.body.message.includes("Driver limit")) {
  // Show upgrade dialog
  showAlert(
    "Driver Limit Reached",
    `You have ${response.body.current_drivers} drivers and can have ${response.body.package_limit} maximum.`
  );
  // Offer upgrade option
  this.goToUpgradePackage();
}
```

---

## Billing Example Workflow

### 1. User subscribes to Startup Package
```
POST /api/subscriptions
{
  "package_id": 1  // Startup: $30 + $10/driver
}
```

### 2. Get next billing amount
```
GET /api/subscriptions/{id}/invoice
// Returns: $30 + (3 drivers × $10) = $60
```

### 3. Process payment
```
POST /api/payments/process
{
  "subscription_id": {id},
  "payment_method_id": 1,
  "payment_token": "tok_..."
}
```

### 4. Webhook confirms
```
// Stripe sends webhook with invoice.payment_succeeded
// User's subscription status changes to 'active'
```

### 5. Add driver (mid-cycle)
```
POST /api/fleet/drivers
// System detects driver count: 3 → 4
// Pro-rated adjustment calculated
// Next billing date may need adjustment
```

### 6. Next billing (monthly)
```
// Scheduled command runs
// Charges: $30 + (4 drivers × $10) = $70
// Creates payment record
// Sends to Stripe
// Webhook confirms completion
```

---

## Error Responses

### 400 Bad Request
```json
{
  "message": "Invalid request parameters",
  "errors": {
    "package_id": ["The package_id field is required."]
  }
}
```

### 401 Unauthorized
```json
{
  "message": "Unauthenticated"
}
```

### 422 Unprocessable Entity
```json
{
  "message": "The given data was invalid.",
  "errors": {
    "subscription_id": ["This subscription is already active."]
  }
}
```

### 404 Not Found
```json
{
  "message": "Subscription not found"
}
```

### 500 Server Error
```json
{
  "message": "Payment processing failed",
  "error": "Stripe API error"
}
```

---

## Rate Limiting

Payment endpoints are rate limited:
- 10 requests per minute (authenticated)
- 2 requests per minute (webhook endpoints)

**Rate Limit Headers:**
```
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 8
X-RateLimit-Reset: 1712092800
```

---

## Mobile App Implementation Tips

### 1. Invoice Display
```javascript
const subscription = await api.get(`/subscriptions/${subId}`);
const invoice = await api.get(`/subscriptions/${subId}/invoice`);

displayInvoice({
  basePrice: invoice.base_price,
  drivers: invoice.driver_count,
  costPerDriver: invoice.price_per_driver,
  total: invoice.total_amount,
  nextBilling: invoice.next_billing_date
});
```

### 2. Handle Driver Limit
```javascript
try {
  const response = await api.post('/fleet/drivers', driverData);
  showSuccess('Driver added successfully');
} catch (error) {
  if (error.status === 422 && error.message.includes('limit')) {
    showUpgradeCTA(
      `You're using ${error.current_drivers}/${error.package_limit} drivers`
    );
  }
}
```

### 3. Payment Processing
```javascript
const stripe = new Stripe(STRIPE_PUBLIC_KEY);

// Get client secret
const response = await api.post('/payments/process', {
  subscription_id: subId,
  payment_method_id: 1,
  payment_token: token
});

// Handle success
if (response.status === 201) {
  navigateTo('payment-success', { paymentId: response.payment_id });
}
```

### 4. Monitor Payment Status
```javascript
// Poll for completion
const pollPaymentStatus = setInterval(async () => {
  const payment = await api.get(`/payments/${paymentId}`);
  
  if (payment.status === 'completed') {
    clearInterval(pollPaymentStatus);
    showSuccess('Payment completed!');
  } else if (payment.status === 'failed') {
    clearInterval(pollPaymentStatus);
    showError('Payment failed. Please retry.');
  }
}, 2000); // Check every 2 seconds
```

---

## WebSocket Updates (Optional)

For real-time updates:

```javascript
// Subscribe to billing updates
socket.on('payment:completed', (payment) => {
  showNotification(`Payment of $${payment.amount} confirmed`);
  refreshSubscription();
});

socket.on('subscription:activated', (subscription) => {
  showNotification('Subscription activated!');
  enableDriverManagement();
});

socket.on('driver:limit-reached', (subscription) => {
  showAlert('You\'ve reached your driver limit', 'Upgrade to add more');
});
```

---

## FAQ

**Q: What if payment fails?**  
A: Payment status stays on 'failed' and user can retry with different card via `POST /payments/{id}/retry`

**Q: How are pro-rated charges applied?**  
A: Automatically calculated by BillingService when drivers added/removed. Adjustment applies to next billing cycle.

**Q: Can users change their package?**  
A: Yes, cancel current subscription and create new one with different package.

**Q: When do charges occur?**  
A: According to billing_cycle (monthly/weekly) starting from subscription activation date.

**Q: Is there a free trial?**  
A: Implement in admin Package creation - not yet in core system.

---

**Last Updated:** April 2, 2026  
**Status:** Ready for Integration
