Webhooks
Receive real-time notifications when events happen in Orbiill. Configure an endpoint, select events, and Orbiill will POST a signed JSON payload to your server.
Overview
When subscriptions change, invoices are paid or fail, or billing configs are deployed, Orbiill sends outbound webhook events to your registered endpoints. This lets your application react in real time without polling the API.
How it works: Stripe → Orbiill (processes event) → Your app (outbound webhook). Your app does not need to handle Stripe webhooks directly. Orbiill normalizes the payload into a clean, consistent format.
Setup
- Navigate to Settings → Webhooks in your dashboard.
- Click Add Endpoint and enter your HTTPS URL.
- Select the events you want to receive.
- Copy the signing secret to verify incoming payloads.
- Click Send Test to send a
test.pingevent and confirm your endpoint is receiving events.
Events
| Event Type | Triggered When |
|---|---|
subscription.created | A new subscription is created |
subscription.updated | Subscription status, plan, or period changes |
subscription.deleted | Subscription is canceled |
invoice.payment_succeeded | Payment is successfully collected |
invoice.payment_failed | Payment attempt fails |
billing_config.deployed | A billing config is deployed to Stripe |
test.ping | Manually triggered test event |
Payload Format
Every webhook delivery uses this envelope format:
{
"id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"type": "subscription.created",
"created_at": "2026-04-08T18:30:00.000Z",
"data": {
"subscription_id": "sub_1234567890",
"customer_email": "[email protected]",
"customer_name": "Jane Doe",
"status": "active",
"plan_name": "Pro",
"plan_amount": 2900,
"plan_currency": "usd",
"current_period_end": "2026-05-08T18:30:00.000Z"
}
}Signature Verification
Each delivery includes an X-Orbiill-Signature header containing an HMAC-SHA256 signature of the raw request body, signed with your endpoint secret. Always verify signatures to prevent spoofed payloads.
Using the SDK
import { verifyWebhook } from '@orbiill/sdk';
app.post('/webhooks/orbiill', (req, res) => {
const event = verifyWebhook(
req.body, // raw string body
req.headers['x-orbiill-signature'], // signature header
process.env.ORBIILL_WEBHOOK_SECRET // your endpoint secret
);
switch (event.type) {
case 'subscription.created':
// Grant access to the user
break;
case 'subscription.deleted':
// Revoke access
break;
case 'invoice.payment_failed':
// Notify the customer
break;
}
res.json({ received: true });
});Manual verification (any language)
expected = "sha256=" + HMAC-SHA256(raw_body, endpoint_secret)
valid = timing_safe_compare(expected, x_orbiill_signature_header)Important: Always use a timing-safe comparison function to prevent timing attacks when verifying signatures.
Retries
If your endpoint returns a non-2xx status or times out (10 second limit), Orbiill retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | ~1 minute |
| 2nd retry | ~4 minutes |
| 3rd retry | ~9 minutes |
After 3 failed attempts, the delivery is marked as permanently failed. You can view delivery history and errors in Settings → Webhooks.
Best Practices
- Return 2xx quickly — Process the event asynchronously. Orbiill times out after 10 seconds.
- Verify signatures — Always validate the
X-Orbiill-Signatureheader to prevent spoofing. - Handle duplicates — Use the event
idfield for idempotency. The same event may be delivered more than once during retries. - Use HTTPS — Always use HTTPS endpoint URLs in production.
- Roll secrets periodically — Use the roll-secret feature in the dashboard to rotate credentials without downtime.