Phase 16 — Telephony Number Management
A complete DID marketplace inside KaiVox — browse, purchase, manage, and auto-renew phone numbers from Vobiz (India) and Twilio (Global), with full billing lifecycle management.
What It Does
Tenants never need to leave KaiVox to manage their phone numbers. They can browse available numbers by region, purchase with one click (deducted from their wallet), and have webhook URLs auto-configured. Monthly billing runs automatically. Numbers can be released when no longer needed.
Key Routes
| URL | Description |
|---|---|
GET /phone-numbers | My Numbers — list with stats cards, status badges, capabilities |
GET /phone-numbers/marketplace | DID Marketplace — browse Vobiz + Twilio numbers |
GET /phone-numbers/marketplace?provider=vobiz | Browse Vobiz Indian numbers |
GET /phone-numbers/marketplace?provider=twilio | Browse Twilio global numbers |
POST /phone-numbers/purchase | Purchase a number (wallet deduction + webhook auto-config) |
GET /phone-numbers/{id} | Number detail — metadata, billing history |
PUT /phone-numbers/{id} | Edit label and caller ID name |
POST /phone-numbers/{id}/release | Release number — provider API call + status=released |
Key Files
| Type | Path |
|---|---|
| Service | app/Services/PhoneNumberService.php — purchase, release, runMonthlyBilling() |
| Controller | app/Http/Controllers/PhoneNumbersController.php |
| Model | app/Models/PhoneNumber.php |
| Model | app/Models/PhoneNumberBilling.php |
| Command | app/Console/Commands/BillPhoneNumbers.php — phone-numbers:bill |
| Table | phone_numbers — tenant_id, number, provider, provider_number_id, number_type, region, area_code, capabilities, setup_fee, monthly_fee, status, purchased_at, last_billed_at, next_billing_at, caller_id_name, label |
| Table | phone_number_billing — phone_number_id, billing_period, amount, status (paid/failed), failure_reason |
Number Capabilities
| Capability | Icon | Description |
|---|---|---|
| Voice | 📞 | Can receive and make voice calls |
| SMS | 💬 | Can send and receive SMS |
| 🟢 | WhatsApp-enabled number (Twilio only) |
Number Status States
- active — number is in use and billing is current
- suspended — insufficient wallet balance to renew
- released — number released back to provider
Purchase Flow
Tenant browses marketplace → selects a number → clicks "Purchase"
↓
Purchase modal shows: number, setup fee, monthly rent, wallet balance check
↓
If wallet insufficient → "Confirm" button disabled, "Top Up Wallet" shown
↓
Tenant confirms purchase
↓
PhoneNumberService::purchase($tenant, $numberData)
1. Duplicate number guard (prevents re-purchasing same number)
2. Provider API call (Vobiz or Twilio) to provision number
3. Auto-configure webhook URLs (answer/hangup) for tenant slug
4. Deduct setup_fee + first month's monthly_fee from wallet
5. Create phone_numbers record with status=active
6. Create initial phone_number_billing record (paid)
↓
Number appears in "My Numbers" with webhooks pre-configured
Monthly Billing
The BillPhoneNumbers artisan command runs daily at 02:00 AM via the Laravel scheduler:
php artisan phone-numbers:bill
# Equivalent to:
PhoneNumberService::runMonthlyBilling()
# Logic:
foreach (PhoneNumber::dueBilling()->get() as $number) {
if ($number->tenant->wallet_balance >= $number->monthly_fee) {
// Deduct monthly_fee from wallet
// Update last_billed_at + next_billing_at
// Create phone_number_billing record (status=paid)
} else {
// Create phone_number_billing record (status=failed)
// Set number status = suspended
// Low balance automation trigger fires
}
}
Mock Fallback Data
When Vobiz credentials are not configured in Super Admin → Platform Settings, or Twilio credentials are missing from .env, the marketplace shows mock data for testing:
- 6 Vobiz Indian DIDs (Mumbai, Delhi, Bangalore area codes)
- 4 Twilio US numbers (New York, Los Angeles area codes)
This allows the full purchase UI flow to be tested without real provider accounts.
Caller ID Name
Each number can have a "Caller ID Name" (max 15 characters) — shown to people you call. Example: "CITY CARE CLNC". This is set at purchase and editable from the number detail page.
What's Complete
- DID Marketplace: browse Vobiz (India) and Twilio (Global) with region/area code filters
- Provider tabs in marketplace UI
- Mock fallback data when API credentials missing
- Purchase modal with cost breakdown and wallet balance check
- Auto-configure webhook URLs on purchase
- Wallet deduction on purchase (setup fee + first month)
- Duplicate number guard
- My Numbers list with stats cards, status badges, capability icons, next billing date
- Number detail page with metadata and billing history (last 24 records)
- Edit label and caller ID name (max 15 chars)
- Release number flow
- Monthly billing runner + BillPhoneNumbers command registered in scheduler at 02:00
- PhoneNumber model with dueBilling scope, status/type/capability accessors
- Phone Numbers nav item in sidebar (Operations section)
What's Deferred
- Email/notification before billing date (needs email delivery unblocked)
- Prorated billing on mid-month purchase
- Super Admin: platform-wide DID inventory overview
- Number porting (bring your own number)
- Multi-number routing (route by time-of-day, location)