domain_purchase.failed
Fires when a purchase is rejected or the registrar refuses the registration.
Fires when a purchase couldn't be completed. There are two scenarios:
- Hold failed: your workspace card declined, required 3DS or had no
funds. Status:
failed. No registration attempted. - Registrar refused: we held the funds, then the registrar rejected the
registration. We released the hold and nothing was charged. Status:
failed.
Purchases made before holds were introduced may show refunded with a
stripeRefundId.
Payload
{
"id": "<event-id>",
"type": "domain_purchase.failed",
"createdAt": "2026-05-17T15:42:11.000Z",
"data": {
"purchase": {
"id": "f8a0c1b9-1234-…",
"hostname": "janesbakery.com",
"years": 1,
"totalCents": 1518,
"currency": "USD",
"status": "failed",
"errorMessage": "Namecheap API error: Insufficient funds in reseller account",
"stripePaymentIntentId": "pi_…",
"customerReference": "user_jane_42",
"createdAt": "2026-05-17T15:42:09.000Z",
"updatedAt": "2026-05-17T15:42:12.000Z"
},
"error": "Namecheap API error: Insufficient funds in reseller account"
}
}
| Field | Notes |
|---|---|
data.purchase.status | failed (no charge). Older purchases may show refunded (charged, then refunded). |
data.purchase.errorMessage | Registrar-side reason. Plain text, safe to surface to your support tooling. |
data.purchase.stripeRefundId | Only on older refunded purchases. |
data.error | Same as errorMessage, top-level for convenience. |
Use it for
- Notifying your end-user that the registration didn't go through
- Reversing any optimistic UI state in your app
- Logging into your own support queue with the registrar's error message
What you don't need to do
- Reverse anything with us: your card wasn't charged. If your end-user paid you out-of-band, that's between you and them.
- Retry the call — for the same hostname, retry will hit the same failure. Resolve the underlying issue (card, funds, premium price) and try again.