Stripe
Integración de Stripe vía webhooks server-side: eventos soportados, verificación de firma, atribución de compras y suscripciones.
Integration Guide
Stripe Webhooks
Connect Stripe to RELO's data backbone for CPA tracking, purchase attribution, and subscription lifecycle monitoring via server-side webhooks.
Overview
RELO's data backbone accepts Stripe webhooks for CPA (Cost Per Action) tracking. When a customer completes a purchase or a subscription event occurs, Stripe sends the event payload to our Go ingest service. These are processed as model.Event records and written to ClickHouse for analytics.
The integration supports one-time purchases, subscription checkouts, and full subscription lifecycle tracking (creation, updates, cancellations).
Supported Events
checkout.session.completed
Fired when a customer completes a Stripe Checkout session. Covers both one-time purchases and initial subscription checkouts. Revenue is extracted from the session's amount_total.
invoice.paid
Fired when a subscription invoice is paid. The handler skips invoices with billing_reason: subscription_create to avoid double-counting the initial checkout (already captured by checkout.session.completed). Only subsequent renewal invoices are processed.
customer.subscription.created / updated / deleted
Subscription lifecycle events. Tracked as custom events for analytics (churn analysis, plan changes, etc.). These events do not carry revenue and do not trigger identity resolution.
Setup
-
Webhook URL
Configure your Stripe webhook endpoint to point to: -
Signing Secret
Retrieve the webhook signing secret from Stripe and set it as theSTRIPE_WEBHOOK_SECRETenvironment variable on the backbone server. Without this, all incoming requests will be rejected. -
Events to Subscribe
Select the following events when configuring the webhook:checkout.session.completedinvoice.paidcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
Important The signing secret must be configured before any events will be accepted. If STRIPE_WEBHOOK_SECRET is empty or missing, the service rejects all Stripe webhook requests with a signature verification failure.
How It Works
Purchase Events
For checkout.session.completed and invoice.paid, the handler extracts revenue from the event payload (amount_total or amount_paid, converted from cents to the base currency unit). Identity resolution links the customer email to a unified device ID via DragonflyDB.
Subscription Lifecycle Events
For customer.subscription.* events, the handler records the plan, status, and billing interval as custom event properties. These events do not include customer email in the subscription object, so identity resolution is skipped.
Identity Resolution
Events with Identity Resolution
checkout.session.completed— Email extracted from the session'scustomer_emailorcustomer_details.emailinvoice.paid— Email extracted from the invoice'scustomer_email
Events without Identity Resolution
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
The Stripe subscription object does not contain the customer's email address. These events are recorded without a linked device ID.
The identity resolution flow for purchase events:
Customer email (from Stripe event)
-> SHA-256 hash
-> DragonflyDB lookup: id:email:{hash} -> unified device_id
-> Event written with resolved device_id
Event Mapping
Stripe events are mapped to RELO's universal event schema as follows:
Stripe Event
RELO event_name
event_type
channel
checkout.session.completed
purchase
purchase
stripe
invoice.paid (subscription_cycle)
subscription_renewal
custom
stripe
invoice.paid (subscription_create)
Skipped — already captured by checkout.session.completed
customer.subscription.created
subscription_created
custom
stripe
customer.subscription.updated
subscription_updated
custom
stripe
customer.subscription.deleted
subscription_cancelled
custom
stripe
Note All events are written to the ClickHouse events table with media_source = 'stripe' and channel = 'stripe'. The order_id field is populated with the Stripe session ID, invoice ID, or subscription ID depending on the event type.
Testing
Stripe CLI (Local Development)
Forward Stripe test events to your local backbone instance:
stripe listen --forward-to localhost:4080/postback/stripe
Then trigger test events from another terminal:
stripe trigger checkout.session.completed
stripe trigger invoice.paid
stripe trigger customer.subscription.created
Stripe Test Mode
You can also configure the webhook endpoint in Stripe's test mode to point to your staging or production URL. Use the Stripe test card for generating purchase events:
Test Card
4242 4242 4242 4242
Any future expiry date, any CVC, any billing postal code.
Verifying Events
After triggering a test event, verify it was ingested by querying ClickHouse:
SELECT event_id, event_name, event_type, revenue, order_id
FROM events
WHERE media_source = 'stripe'
ORDER BY event_time DESC
LIMIT 10;
Security
- HMAC-SHA256 signature verification on every incoming request using the
Stripe-Signatureheader - 5-minute timestamp tolerance — events with a timestamp older than 5 minutes are rejected to prevent replay attacks
- Empty or missing signing secret causes all requests to be rejected — the service never accepts unverified payloads
- No sensitive data stored — customer emails are SHA-256 hashed before being used in identity resolution; raw emails are never persisted