domain_purchase.failed
Fires when a purchase is rejected or the registrar refuses after charging.
Fires when a purchase couldn't be completed. There are two scenarios:
- Charge failed — your workspace card declined / required 3DS / had no
funds. Status:
failed. No registration attempted. No refund needed. - Registrar refused after the charge succeeded — we charged your card,
the registrar then rejected the registration. We automatically
refunded the Stripe charge. Status:
refunded.
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": "refunded",
"errorMessage": "Namecheap API error: Insufficient funds in reseller account",
"stripePaymentIntentId": "pi_…",
"stripeRefundId": "re_…",
"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) or refunded (charge made + refunded) |
data.purchase.errorMessage | Registrar-side reason. Plain text, safe to surface to your support tooling. |
data.purchase.stripeRefundId | Present when the registrar failed after the charge. Look up in Stripe for full refund details. |
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
- Surfacing refund status in your own dashboard
What you don't need to do
- Issue your own refund — it's already done. 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.