Guide: Domain hosting (HostCo)
HostCo is a domain registrar and cloud provider. This guide shows how to use Driptab
for flat-fee domain billing (register, renew, transfer) and recurring VPS billing —
entirely driven by driptab.yaml and dtab sync.
This scenario covers:
- Project-scoped pricing catalog
- Flat-fee charges with
immediateandarrearsinvoice timing - Yearly and monthly plan intervals
- Transfer add-ons (one-time charges)
- Dunning via webhooks
The billing model
HostCo's billing is entirely flat-fee. There are no metered metrics.
| Product | Interval | Invoice timing | Price |
|---|---|---|---|
| .com registration | yearly | immediate (pay upfront) | $12.00 |
| .com renewal | yearly | immediate | $20.75 |
| .com transfer | one-time add-on | immediate | $12.96 |
| VPS CX11 | monthly | arrears (pay after use) | $4.15/mo |
| VPS CX21 | monthly | arrears | $8.30/mo |
Domain billing uses immediate because HostCo charges the customer before the
registration is active. VPS uses arrears because HostCo bills after the compute
is consumed.
Step 1 — Write driptab.yaml
Save the following as driptab.yaml in your project root (see the full example at
docs/examples/hostco.yaml):
version: "1"
org: hostco
workspace: default
project: billing
catalog:
- code: tld.com.register
name: ".com Registration"
amount_cents: 1200
currency: USD
metadata: { tld: com, operation: register }
- code: tld.com.renew
name: ".com Renewal"
amount_cents: 2075
currency: USD
metadata: { tld: com, operation: renew }
- code: tld.com.transfer
name: ".com Transfer"
amount_cents: 1296
currency: USD
metadata: { tld: com, operation: transfer }
- code: vps.cx11
name: "VPS CX11 — 2 vCPU / 4 GB / 40 GB SSD"
amount_cents: 415
currency: USD
metadata: { vcpu: 2, ram_gb: 4, disk_gb: 40 }
metrics: []
addons:
- code: domain-transfer-com
name: ".com Transfer"
catalog_ref: tld.com.transfer
invoice_timing: immediate
plans:
- code: domain-register-com
name: ".com Register"
interval: yearly
amount_cents: 0
currency: USD
charges:
- type: flat_fee
catalog_ref: tld.com.register
invoice_timing: immediate
- code: domain-renew-com
name: ".com Renew"
interval: yearly
amount_cents: 0
currency: USD
charges:
- type: flat_fee
catalog_ref: tld.com.renew
invoice_timing: immediate
- code: vps-cx11-monthly
name: "VPS CX11 Monthly"
interval: monthly
amount_cents: 0
currency: USD
charges:
- type: flat_fee
catalog_ref: vps.cx11
invoice_timing: arrears
webhooks:
- url: https://hostco.example.com/driptab-webhooks
events:
- invoice.created
- subscription.suspend_requested
- subscription.terminate_requested
- addon.applied
Step 2 — Apply the configuration
dtab sync driptab.yaml --dry-run # preview changes
dtab sync driptab.yaml # apply
Output:
Syncing to hostco/default/billing...
catalog: 4 upserted (0 skipped)
metrics: 0 (none defined)
addons: 1 upserted
plans: 3 upserted (0 skipped)
webhooks: 1 registered
Done.
dtab sync is idempotent. Run it in CI on every merge to main.
Step 3 — Register a domain for a customer
When a customer registers example.com:
# Create the customer (once per account, if not already created)
dtab cust create \
--external-id hostco-account-789 \
--name "Bob Johnson" \
--email bob@example.com \
--currency USD
# Start a registration subscription
dtab subs create \
--external-id hostco-domain-com-789 \
--customer ext:hostco-account-789 \
--plan domain-register-com
ext:hostco-account-789 resolves through customers.external_id, and
domain-register-com resolves through the plan code. The API receives UUIDs after
the CLI resolves those friendly references.
Current hosted behavior: subscription creation starts the subscription. Immediate subscription-start invoicing for flat-fee charges is a billing-engine feature and should be verified in your deployment before charging live customers.
Step 4 — Process the payment
HostCo's webhook handler:
app.post('/driptab-webhooks', async (req, res) => {
const sig = req.headers['x-driptab-signature'];
if (!verify(secret, req.rawBody, sig)) return res.status(401).end();
const { event, data } = req.body;
if (event === 'invoice.created') {
const invoice = data.invoice;
await chargeCard(data.customer.external_id, invoice.total_cents, invoice.currency);
// On success:
await driptab.payments.record({
invoice_id: invoice.id,
amount_cents: invoice.total_cents,
currency: invoice.currency,
provider: 'stripe',
provider_payment_id: charge.id,
paid_at: new Date().toISOString(),
});
}
});
Step 5 — Apply a domain transfer add-on
A transfer is a one-time charge, not a subscription. When a customer transfers a domain:
dtab addons apply domain-transfer-com \
--customer ext:hostco-account-789
Or via API:
POST /v1/addons/<addon_id>/apply
{
"customer_id": "<customer_id>"
}
The API accepts UUIDs. If you want to use the add-on code and customer external ID,
use dtab addons apply so the CLI can resolve both references first.
This generates an immediate invoice for the transfer fee and fires addon.applied.
To mark the invoice paid after your payment provider succeeds:
dtab payments record \
--invoice <invoice_id> \
--amount 1296 \
--method stripe
Step 6 — Subscribe to a VPS
dtab subs create \
--external-id hostco-vps-cx11-001 \
--customer ext:hostco-account-789 \
--plan vps-cx11-monthly
VPS uses arrears billing. No invoice is generated at subscription start. At the
end of the month, the SubscriptionMeter alarm fires and generates an invoice for
$4.15. HostCo receives invoice.created, collects payment, and records it.
Step 7 — Dunning
HostCo defines dunning in driptab.yaml:
dunning:
enabled: true
steps:
- days_after_due: 3
webhook_event: invoice.payment_overdue_reminder_1
- days_after_due: 14
webhook_event: subscription.suspend_requested
- days_after_due: 30
webhook_event: subscription.terminate_requested
HostCo's webhook handler:
if (event === 'invoice.payment_overdue_reminder_1') {
await sendEmail(data.customer.email, 'Payment reminder: ...', ...);
}
if (event === 'subscription.suspend_requested') {
// Disable the domain/VPS in HostCo's systems
await suspendService(data.subscription.external_id);
// Tell Driptab
await driptab.subscriptions.suspend(data.subscription.id);
}
if (event === 'subscription.terminate_requested') {
await terminateService(data.subscription.external_id);
await driptab.subscriptions.terminate(data.subscription.id);
}
Updating prices
To update the .com registration price from $12.00 to $12.99:
- Edit
driptab.yaml: changetld.com.register.amount_centsfrom1200to1299. - Commit and merge.
- Run
dtab sync.
All future invoices for .com registration plans pick up $12.99. Issued invoices
are unaffected — each fee row already has the pricing snapshot from when it was issued.