Overview
Clients search for domain names at /domain-search — no login required. When they find an available domain, the registration flow guides them through checkout. On invoice payment, a job fires to register the domain at the registrar.
Search Page (/domain-search)
- Client enters a name — e.g.
mysite(no extension needed). - Commerce calls
checkBulkAvailability('mysite', [...all active TLDs...])on the active registrar module. - Results appear as a grid of TLD rows:
- Green / Available — shows TLD, price per year, and a Register button.
- Red / Taken — shown but not actionable.
- Bulk availability is one API call for modules that support it (ResellerClub, Namecheap); others may use sequential calls.
Domain search is public. No login required to search.
Registration Flow (Step by Step)
Step 1 — Select Domain
Client clicks Register next to an available TLD. If not logged in, they are redirected to /login with a return URL. After login, they land on /client/order/domain with domain and TLD pre-filled.
Step 2 — Order Form
The registration form collects:
| Field | Notes |
|---|---|
| Domain | Pre-filled; read-only |
| Registration years | Dropdown, constrained to TLD min_years–max_years |
| Registrant contact | Pre-filled from client profile; editable |
| Admin / Tech / Billing contacts | Defaulted to registrant; can be set separately |
| Agree to Terms | Checkbox; required |
Step 3 — Submit Order
On submit:
- An Order record is created.
- An Invoice is generated for the registration fee.
- Client is redirected to the invoice payment page.
Step 4 — Invoice Payment
Client pays the invoice. InvoiceService::markPaid() fires:
RegisterDomainJobis dispatched to the queue.- Domain record is created with
status = pending.
Step 5 — RegisterDomainJob
The job runs and:
- Looks up or creates registrant contact at the registrar:
- If a contact ID is cached in
domain_contactsfor this client, reuse it. - Otherwise, call the registrar's contact create API; cache the returned contact ID.
- If a contact ID is cached in
- Calls
register(domain, tld, contacts, years)on the active registrar module. - On success: sets
domains.status = active, storesexpiry_date,registered_at. - On failure: sets
status = pending, logs the error, retries up to 3 times with 60s backoff.
After Registration
- Client sees the domain in their portal at
/client/domains. - Admin sees it at Admin → Domains.
- Renewal invoice is generated 30 days before expiry by
commerce:check-expiring-domains.