Outbound Webhooks
Customers can register their own webhook endpoints to receive signed, retried event notifications when things happen in WhatsMine — so external systems stay in sync.
This is distinct from inbound webhooks from Meta/Stripe to WhatsMine (covered in the Integrations section).
How it works
Event fires → WebhookDispatchService → DispatchWebhookJob (queued)
├── HTTP POST to the endpoint
└── logs a WebhookDelivery
- A business event occurs (e.g. a subscription is created).
- The dispatcher finds matching endpoints for the user.
- A queued job signs the payload, POSTs it, and records the result.
Managing endpoints (customer UI)
In the app at Webhooks (/webhooks), customers can:
- Create / edit / delete endpoints.
- Choose which events to subscribe to.
- Rotate the signing secret.
- Send a test delivery.
- View the delivery log (status + response body).
Payload signature
Each delivery includes an X-Signature-256 header so receivers can verify authenticity:
X-Signature-256: sha256=<hmac-sha256(secret, raw-body)>
Verify it on your end:
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
hash_equals($expected, $request->header('X-Signature-256')); // must be true
Retry policy
Failed deliveries (non-2xx or connection error) retry with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | 1 minute |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | final failure |
Available events
| Event | Fires when |
|---|---|
subscription.created | A subscription is activated. |
subscription.cancelled | A subscription is cancelled. |
subscription.plan_changed | A plan is changed. |
invoice.paid | A payment is recorded. |
invoice.refunded | A refund is issued. |
Developers extending the app can dispatch new events from their own code:
app(WebhookDispatchService::class)->dispatch(
event: 'subscription.created',
payload: ['subscription_id' => $subscription->id],
user: $user,
);
➡️ Next: Theming.