# Provisioning & Service Termination Fix - 2026-02-10

## Issues Fixed

### Issue #1: VPS Not Being Provisioned
**Root Cause:** All provisioning services (VirtFusion, Pterodactyl, SynergyCP, Enhance) were reading credentials from `config('services.*')` which pulls from `.env`, but the actual credentials are stored in the **database** via the `settings` table (configured in Admin → Settings → API).

**What Happened:**
- User configured VirtFusion API URL/token via admin panel settings (stored in DB)
- VirtFusionService was reading from `.env` (empty values)
- HTTP client tried to connect to relative hostnames like `sanctum`, `users`, `servers`
- cURL errors: "Could not resolve host: users"

**Files Updated:**
- `app/Services/Provisioning/VirtFusionService.php`
- `app/Services/Provisioning/PterodactylService.php`
- `app/Services/Provisioning/SynergyCPService.php`
- `app/Services/Provisioning/EnhanceService.php`

**Change:** All services now use `\App\Models\Setting::get('provider_api_url')` instead of `config('services.provider.url')`

### Issue #2: Services Not Terminated on Subscription Cancellation
**Root Cause:** `HandleSubscriptionCancelled` listener only sent a notification - it didn't call the provisioning service's `terminate()` method.

**What Happened:**
- User canceled subscription with "immediate" setting
- Subscription canceled in Stripe
- Service remained active on VirtFusion panel
- No cleanup of provisioned resources

**Files Updated:**
- `app/Listeners/HandleSubscriptionCancelled.php`

**Changes:**
- Made listener implement `ShouldQueue` (background job with retries)
- Added logic to find all active/suspended services for the subscription
- Call `terminate()` on each service via ProvisioningFactory
- Proper error handling and logging
- Service status updated to "terminated" in database

## Current State

### VirtFusion Configuration (Database)
```
virtfusion_api_url: https://cp.vps.ezscale.tech/api/v1
virtfusion_api_token: (encrypted in DB)
```

### How It Works Now

**Subscription Created:**
1. HandleSubscriptionCreated listener queued
2. Reads plan from database
3. Gets provisioning service (VirtFusionService for VPS)
4. **VirtFusionService reads URL/token from settings table**
5. Ensures user exists on VirtFusion panel
6. Creates server (package ID 43)
7. Changes package to match plan specs
8. Updates service record with IP, hostname, etc.
9. Sends credentials email to customer

**Subscription Canceled:**
1. HandleSubscriptionCancelled listener queued
2. Finds all active/suspended services for subscription
3. Gets provisioning service for each
4. Calls `terminate()` on VirtFusion (DELETE /servers/{id})
5. Updates service status to "terminated"
6. Sends cancellation email to customer

## Testing Needed

1. ✅ Horizon restarted to reload code changes
2. ⏳ Create a new VPS subscription and verify:
   - Service is provisioned on VirtFusion
   - Credentials email is sent
   - Service appears in customer dashboard
3. ⏳ Cancel the subscription and verify:
   - Service is terminated on VirtFusion
   - Service status updates to "terminated"
   - Cancellation email is sent

## Environment Variables (No Longer Used)

The following `.env` variables are **no longer used** for provisioning (database settings take precedence):
- ~~VIRTFUSION_API_URL~~
- ~~VIRTFUSION_API_TOKEN~~
- ~~PTERODACTYL_PANEL_URL~~
- ~~PTERODACTYL_API_KEY~~
- ~~SYNERGYCP_API_URL~~
- ~~SYNERGYCP_API_TOKEN~~
- ~~ENHANCE_API_URL~~
- ~~ENHANCE_API_TOKEN~~

**Configure all provisioning credentials in:** Admin Panel → Settings → API Integrations

## Migration Notes

If you have provisioning credentials in `.env`, migrate them to the database:
1. Go to Admin → Settings → API
2. Enter the URL and token for each provider
3. Click "Save" to encrypt and store in database
4. Remove from `.env` (optional, but recommended to avoid confusion)
