Webhooks
leadmaps hosts inbound webhook receivers for third-party event sources. Stripe is available today, and the receiver supports adding more sources over time.
Endpoint
Section titled “Endpoint”POST /webhooks/:adapter/:siteIdFor each inbound webhook the receiver:
- Verifies the inbound signature (per the source’s spec).
- Maps matched events to the leadmaps event shape.
- Forwards each mapped event into your site’s analytics.
Stripe adapter
Section titled “Stripe adapter”POST /webhooks/stripe/:siteIdStripe-Signature: t=...,v1=...Verifies via Stripe’s official spec, HMAC-SHA256 with a 5-minute tolerance window.
Event mapping
Section titled “Event mapping”| Stripe event | Mapped event |
|---|---|
charge.succeeded | purchase |
customer.subscription.created | subscription_created |
customer.subscription.updated | subscription_updated |
customer.subscription.deleted | subscription_canceled |
Unmapped Stripe types verify successfully and return 200 with zero events
forwarded. This is deliberate. Stripe will not retry, and the mapping table
can grow over time without breaking existing customers.
Per-(site, adapter) secret
Section titled “Per-(site, adapter) secret”Each (site, adapter) pair has its own shared signing secret used to verify
inbound signatures. A request for a site with no configured webhook returns
401 with the same generic envelope as everything else, so an attacker
cannot enumerate tenants by status-code difference.
Status codes
Section titled “Status codes”| Status | When |
|---|---|
200 { ok: true, forwarded: <n> } | Verified successfully. |
400 | Invalid signature OR malformed body. Stripe will not retry. |
401 | Webhook is not configured for this site. |
404 | Unknown adapter name. |
500 | Event forwarding failed. Stripe will retry. |
Configuring webhook secrets
Section titled “Configuring webhook secrets”Webhook signing secrets are configured per site. Reach out at hello@leadmaps.nl to set up or rotate a secret for a source. Rotation keeps the previous secret valid for a short overlap window so in-flight webhooks are not dropped.
Ingesting from a custom source
Section titled “Ingesting from a custom source”If you need to ingest from a source leadmaps does not have an adapter for, do
it directly via the /s2s/events endpoint with your own server-side
normalization. That bypasses the adapter layer entirely.