Twilio is the VoIP provider. The billing platform fetches CDR (Call Detail Records) from Twilio via API, matches them to customers via CLI (phone number), applies pricing, and generates invoices.
| Item | Value |
|---|---|
| Console | https://console.twilio.com |
| Account SID | AC5f6883303b4c430931a66b6cdcd48d92 |
| Auth method | API Key (NOT Auth Token) |
| API Key SID | SKb9ce76e... (Bitwarden: "Twilio API Key — yealin-billing-dev") |
| API Key Secret | 43AX7y... (Bitwarden) |
API Keys are more secure than Auth Tokens:
TWILIO_ACCOUNT_SID=AC5f6883303b4c430931a66b6cdcd48d92
TWILIO_API_KEY_SID=SKb9ce76e...
TWILIO_API_KEY_SECRET=43AX7y...
Celery tasks can sync CDRs directly from Twilio API. Triggered via:
Upload a CSV file exported from Twilio Console:
https://billing.yealin.com.au/cdrCSV format expected:
CallSid,StartTime,EndTime,Duration,From,To,Direction,Price,Status
CDR imported (from API or CSV)
↓
CLI Matcher: from_number or to_number matched against CustomerCLI table
↓
If matched: customer assigned, billable flag set based on CustomerCLI.billable
↓
Destination Classifier: to_number prefix matched against Destination table
↓
If destination found: sell_price calculated
↓
CDR saved with customer, destination, cost_price_aud, sell_price_aud
| State | Description |
|---|---|
| Matched + billable | CLI matched to customer, will be invoiced |
| Matched + non-billable | CLI matched but billable=False (internal trunk etc) |
| Unmatched | No CLI match found — won't be invoiced |
| Invoiced | Already included in an invoice |
After adding new Customer CLIs, reprocess unmatched records:
# Via API
TOKEN=$(...)
curl -s -X POST https://billing.yealin.com.au/api/cdr/reprocess/ \
-H "Authorization: Bearer $TOKEN"
Or via Admin UI: CDR page → Reprocess button.
yealin-billing-prod.env with new SID and secret