Bills Module
Overview
The Bills module handles the Housr Bills product — a utility bills package for student housing. It covers the full signup flow, pricing calculations, tenant management, and integrations with HubSpot CRM, Huddle (address lookup), and external partners (Oakmans).
Database Connection
Bills models use the dedicated bills database connection (DB_DATABASE_BILLS). This is a separate database from the main Housr database.
Routes
All routes are prefixed with /api/bills (configured in RouteServiceProvider with api middleware and CorsMiddleware).
POST /api/bills/register Register a new tenant
POST /api/bills/signup Complete bills signup
POST /api/bills/update-status Update tenant status
GET /api/bills/quote Get bills pricing quote
POST /api/bills/share-with-housemates Send quote via SMS to housemates
GET /api/bills/quote-prefill Get pre-filled quote data
# Authenticated (requires JWT)
GET /api/bills/tenant-details Get current user's tenant details
POST /api/bills/tenant-details Add/update tenant details
POST /api/bills/request-callback Request a callbackControllers
BillsController
Primary controller handling registration, signup, and SMS sharing.
register(RegisterTenantRequest)— Registers a new tenant with personal details. Returns existing tenant if email matches. Checks for quote prefill data.signup(SignupRequest)— Full bills signup flow. Creates contract, tenants, syncs to HubSpot, creates HubSpot deal, triggers external webhooks for prefill partners.shareWithHousemates(ShareWithHousematesRequest)— Sends SMS messages to housemates via Twilio with quote details.
BillsPriceController
index(BillsPriceRequest)— Returns bills pricing based on bedrooms, city, and optional agent ID. UsesBillsPriceServicefor calculation.
BillsTenantController
show()— Returns authenticated user’s bills contract and tenant details.store(AddTenantDetailsRequest)— Adds a new tenant to an existing contract.
QuotePrefillController
get(GetQuotePrefillRequest)— Returns pre-filled quote data for a tenant (from partner integrations).
BillsCallbackController
store()— Records a callback request for authenticated users.
TenantController
updateTenantStatus()— Updates a tenant’s status in the system.
Models
V2Contract (bills DB)
Bills contract representing a household’s bills agreement.
| Field | Type | Description |
|---|---|---|
id | int | Primary key |
bedrooms | int | Number of bedrooms |
address | string | Property address |
huddle_address_id | string | Huddle address reference |
water | boolean | Water included |
internet_speed | string/null | WiFi speed (400Mbps, 600Mbps, 800Mbps, none) |
start_date | datetime | Tenancy start |
end_date | datetime | Tenancy end |
referral_code | string/null | Referral code |
price | decimal | Price per person per week |
hubspot_deal_id | string/null | Linked HubSpot deal |
V2Tenant (bills DB)
Individual tenant linked to a contract.
| Field | Type | Description |
|---|---|---|
id | int | Primary key |
contract_id | int | FK to V2Contract |
first_name | string | First name |
last_name | string | Last name |
email | string | Email (unique key for upsert) |
phone | string | Phone number |
role | string | LEAD or HOUSEMATE |
status | string | INVITED, COMPLETED, etc. |
student | boolean | Is student |
referral_source | string/null | How they found Housr |
ip_address | string/null | Registration IP |
QuotePrefillHouse / QuotePrefillTenant (bills DB)
Pre-filled quote data from external partners (e.g., Oakmans). Houses and tenants are linked and used to pre-populate the signup form.
BillRegion (bills DB)
Regional billing configuration with postcode prefixes and pricing rules.
BillsPriceSelectable (bills DB)
Pricing matrix by bedrooms and city, with columns for energy, water, wifi at different speeds, and electric-only rates.
AgentReferralCode (bills DB)
Agent referral codes with validation service.
Services
SignupService
Orchestrates the full signup flow:
- Creates or updates a
V2Contract - Creates
V2Tenantrecords (upsert by email) - Creates Housr user accounts via
UserService - Syncs all tenants to HubSpot as contacts
- Creates or updates a HubSpot deal linked to contacts
- Updates deal stage to “Closed Won” when all tenants complete
- Triggers external webhooks for prefill partners (Oakmans)
TenantService
Handles tenant registration:
- Creates or updates tenant records
- Checks for existing housemate contracts
- Loads quote prefill data if available
BillsPriceService
Calculates bills pricing based on bedrooms, city, and agent. Accounts for agents with partially included bills (e.g., electric only, gas only).
BillsRegionService
Resolves regional billing configuration.
BillsCallbackService
Records callback requests.
ExternalWebhookServiceResolver
Factory pattern for resolving external webhook services by partner name.
OakmansExternalWebhookService
Implements ExternalWebhookInterface. Sends signup data to Oakmans via the OakmansConnector Saloon integration when a prefill user completes signup.
Enums
HouseStatus— Contract/house status values (e.g.,AGREEMENT_SIGNED)TenantStatus— Tenant status values (e.g.,AGREEMENT_SIGNED)QuotePrefillSource— Source of quote prefill data
External Integrations
HubSpot
Every signup creates/updates HubSpot contacts and deals. The pipeline and deal stages are configured with specific IDs. Properties tracked include source, lifecycle stage, agreed_to_bills_package, etc.
Twilio
The “share with housemates” feature sends personalised SMS messages with quote details.
Oakmans (Saloon Connector)
OakmansConnector and OakmansBillsSignupRequest send signup confirmations to the Oakmans partner system when a prefill user completes their bills signup.
Tests
Tests are in Modules/Bills/tests/Feature/:
BillsSignupTest.php— Tests tenant details retrieval, tenant addition, and Oakmans prefill webhook triggeringBillsCallbackTest.php— Tests callback request functionality
Tests use FeatureTestCase with RefreshDatabase, JWT auth, and Mockery for external services.