Domain Acquisition Hooks
The eight hooks on the path to the domain provider: the gates before a register, transfer or renew call, and the events behind them.
Overview
Getting a domain is a paid and irreversible call. Once the provider opened the registration there is no taking it back, so every step of this path has a gate in front of it and an event behind it.
Gates run before the call and can stop it. Events run after, separately for success and for failure. Below is the full contract of all eight: which values arrive, in what order, and what you have to return.
Reference
Stopping a register or transfer request
Runs immediately before the register or transfer request reaches the provider; the method was checked and the arguments are not built yet.
sld, tld, year, dns, whois, tcode.register or transfer. With a transfer code present it is a transfer.null or an empty string lets it carry on.Hook::add('gate:domain.create', 10, function ($service, $options, $method) {
if ($method === 'transfer') return null; // leave transfers alone
$years = (int) ($options['year'] ?? 1);
if ($years > 5) return 'We register at most 5 years at a time.';
return null;
});Taking the register or transfer result
Runs right after the provider call returned. It is no promise of success: the result value can carry a failure too.
false on failure. This is the value to read first.register or transfer.Hook::add('action:domain.created', 10, function ($service, $result, $method) {
if ($result === false) return; // failure has its own hook
if ($method === 'register') Dns::applyTemplate($service['name'] ?? '');
});Catching a failed registration
Runs where the provider call came back a failure, right after the previous hook.
Hook::add('action:domain.register_failed', 10,
function ($service, $options, $method, $error) {
Ops::alert('domain-provision', [
'name' => $service['name'] ?? '',
'method' => $method,
'error' => $error ?: 'the provider gave no reason',
]);
});Stopping a renewal request
Runs before the renewal request reaches the provider.
sld, tld, year.Hook::add('gate:domain.renew', 10, function ($service, $options) {
// Renewing spends money where the customer already asked to cancel.
if (Acme::cancelRequested((int) ($service['id'] ?? 0)))
return 'A cancellation is open, so the renewal was stopped.';
return null;
});Learning that a renewal landed
Runs after a paid renewal item extended the end date and the provider was updated.
Hook::add('action:domain.renewed', 10, function ($service) {
ExternalDns::syncExpiry($service['name'] ?? '', $service['duedate'] ?? '');
});Catching a failed renewal
Runs where the provider's renewal call came back a failure.
Hook::add('action:domain.renew_failed', 10, function ($service, $options, $error) {
// The customer paid and the domain did not renew: this wants a person.
Ops::page('domain-renew-failed', $service['name'] ?? '', $error);
});Following a transfer through
Runs after the provider reported the transfer done, the service went live and word was sent.
Hook::add('action:domain.transfer.completed', 10, function ($service) {
ExternalDns::provision($service['name'] ?? '');
});Catching a failed transfer check
Runs where the provider's transfer status check failed, right before the error is thrown.
Hook::add('action:domain.transfer.failed', 10, function ($service) {
// The check repeats on a schedule: alert on a streak, not on one failure.
if (Acme::failStreak((int) ($service['id'] ?? 0)) >= 3)
Ops::alert('domain-transfer-stuck', $service['name'] ?? '');
});Following the transfer code being saved
Runs after a customer saves the authorisation code for an incoming transfer. This is where you tell the outside system that drives the transfer.
Hook::add('action:domain.transfer_authcode_saved', 10, function ($service, $code) {
// Carry the fact that a code arrived, NOT the code itself.
Acme::transferReady((int) ($service['id'] ?? 0), $service['name'] ?? '');
});Pitfalls
The register hook runs when the provider call returned, not when it succeeded. Where the second parameter is false the work did not land. Setting up DNS or telling the customer "your domain is ready" without checking treats a record that does not exist as real.
Renewals do not run from an operator's hand alone: the post-payment flow and scheduled jobs pass the same gate. A condition you put there can leave a domain unrenewed with nobody noticing. Record it somewhere when you stop the gate; a silent veto is the costliest kind.
The transfer status is asked on a schedule, and every failed check runs the failure hook again. A listener that alerts on each call produces dozens of messages for one pending transfer. Count the streak rather than reacting to a single failure.
The register and renew gates are the last point before money is spent. Fraud checks, quota limits and premium confirmations belong here. The same check made after the call does not bring the money back.
Related Articles
- Service Lifecycle Hooks
- Invoice and Payment Hooks
- Writing a Hook Listener
Merci pour votre retour !
Notre équipe d'assistance est disponible 24h/24 pour tout ce que vous ne trouvez pas ci-dessus.