n8n Webhook Integration
Use n8n's built-in Webhook node with LostChurn outbound webhooks for self-hosted workflow automation.
LostChurn sends real-time outbound webhooks that work directly with n8n's built-in Webhook node. No custom node installation required — just configure a Webhook trigger and start building workflows.
Prerequisites
- An n8n instance (self-hosted or n8n Cloud)
- A LostChurn account with webhook access (any paid plan)
- A configured outbound webhook endpoint in Settings > Webhooks
Step-by-Step Setup
1. Create the n8n Webhook Trigger
- Open your n8n instance and create a New Workflow.
- Click the + button and search for Webhook.
- Add the Webhook node as your trigger.
- Set HTTP Method to
POST. - Set Path to something descriptive, e.g.,
lostchurn-events. - Under Authentication, select None (we verify signatures in a separate step).
- Click Listen for Test Event to activate the webhook temporarily.
2. Register the Webhook in LostChurn
- Copy the Test URL from the n8n Webhook node (e.g.,
https://your-n8n.example.com/webhook-test/lostchurn-events). - In your LostChurn dashboard, go to Settings > Webhooks.
- Click Add Endpoint.
- Paste the n8n webhook URL.
- Select the event types you want to receive.
- Click Create Endpoint.
- Copy the Signing Secret shown on creation — you will need it for signature verification.
The signing secret is only shown once at creation time. Copy it immediately and store it securely in n8n's credentials.
3. Add Signature Verification (Recommended)
Add a Code node after the Webhook trigger to verify HMAC-SHA256 signatures:
- Add a Code node connected to the Webhook output.
- Set the language to JavaScript.
- Paste the following code:
const crypto = require('crypto');
// Store your signing secret in n8n Credentials or environment variables
const secret = 'whsec_your_signing_secret_here';
const signature = $input.first().headers['x-lostchurn-signature'];
const body = JSON.stringify($input.first().json);
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
if (signature !== expected) {
throw new Error('Invalid LostChurn webhook signature — rejecting event');
}
// Signature valid — pass through
return $input.all();For production workflows, store the signing secret as an n8n credential or environment variable rather than hardcoding it.
4. Filter by Event Type
Add an IF node or Switch node to route events by type:
Using a Switch node:
- Add a Switch node after the Code node.
- Set the Value to
{{ $json.event }}. - Add cases for each event type you want to handle:
recovery.succeededrecovery.failedpayment.failedcampaign.completed
5. Test the Integration
- In n8n, ensure your Webhook node is in Listen for Test Event mode.
- In LostChurn, go to Settings > Webhooks and click Send Test Event on your endpoint.
- The test payload should appear in n8n.
- Once confirmed, switch the n8n Webhook to Production URL and activate the workflow.
Remember to update your LostChurn webhook endpoint URL from the test URL to the production URL before going live.
Example Workflow: Webhook to Slack Notification
This workflow receives a LostChurn recovery event and sends a formatted Slack notification.
Workflow JSON
Import this JSON into n8n via Workflow > Import from JSON:
{
"name": "LostChurn Recovery to Slack",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "lostchurn-recovery",
"responseMode": "onReceived",
"responseCode": 200
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.event }}",
"operation": "equals",
"value2": "recovery.succeeded"
}
]
}
},
"name": "Filter Recoveries",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [470, 300]
},
{
"parameters": {
"channel": "#revenue-recovered",
"text": "={{ '💰 Payment Recovered!\\n' + 'Customer: ' + $json.data.customer_email + '\\n' + 'Amount: $' + ($json.data.amount / 100).toFixed(2) + '\\n' + 'Decline Code: ' + $json.data.decline_code + '\\n' + 'Retry Attempts: ' + $json.data.retry_count }}",
"otherOptions": {}
},
"name": "Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [690, 280]
}
],
"connections": {
"Webhook": {
"main": [
[{ "node": "Filter Recoveries", "type": "main", "index": 0 }]
]
},
"Filter Recoveries": {
"main": [
[{ "node": "Slack", "type": "main", "index": 0 }],
[]
]
}
}
}How It Works
- Webhook node receives the LostChurn event payload via POST.
- Filter Recoveries checks if the event type is
recovery.succeeded. - Slack node sends a formatted message to
#revenue-recoveredwith the recovery details.
Webhook Payload Format
All LostChurn outbound webhooks follow this structure:
{
"event": "recovery.succeeded",
"merchant_id": "550e8400-e29b-41d4-a716-446655440000",
"payment_event_id": "660e8400-e29b-41d4-a716-446655440001",
"timestamp": "2026-03-13T10:30:00Z",
"data": {
"recovery_id": "rec_abc123",
"customer_email": "jane@example.com",
"customer_name": "Jane Doe",
"amount": 4999,
"currency": "usd",
"decline_code": "insufficient_funds",
"retry_count": 2,
"recovered_at": "2026-03-13T10:30:00Z"
}
}Headers
| Header | Description |
|---|---|
X-LostChurn-Signature | HMAC-SHA256 hex digest of the request body |
X-LostChurn-Event | Event type (e.g., recovery.succeeded) |
Content-Type | application/json |
User-Agent | LostChurn-Webhook/1.0 |
Available Event Types
| Event | Description |
|---|---|
payment_failed | A payment charge was declined |
retry_started | A retry attempt has been initiated |
retry_succeeded | A retry attempt succeeded |
retry_failed | A retry attempt was declined |
payment_recovered | A payment has been fully recovered |
dunning_started | A dunning campaign has begun |
terminal | Recovery exhausted — all attempts failed |
Common Workflow Patterns
High-Value Recovery Alert
Webhook → IF (amount > 10000) → Slack / Email / PagerDutyFailed Payment to CRM
Webhook → Filter (payment_failed) → HTTP Request (HubSpot API) → Update ContactDaily Recovery Digest
Schedule Trigger (daily) → HTTP Request (LostChurn API) → Aggregate → Email SummaryEscalation on Terminal
Webhook → Filter (terminal) → Create Zendesk Ticket → Assign to CS TeamTroubleshooting
Webhook not receiving events
- Ensure n8n is publicly accessible (not behind
localhostwithout a tunnel). - Verify the workflow is Active (toggle in the top-right corner).
- Check LostChurn webhook delivery logs at Settings > Webhooks > Deliveries.
- If using n8n Cloud, ensure you are using the Production URL, not the Test URL.
Signature verification failing
- Confirm the signing secret matches exactly (no trailing whitespace).
- Ensure the Code node receives the raw JSON body, not a transformed version.
- Check that the
x-lostchurn-signatureheader is accessible in the Webhook node output.
Events arriving but workflow not executing
- Verify the Webhook node's HTTP method is set to
POST. - Check the IF/Switch node conditions match the event types you expect.
- Look at the n8n execution log for errors in individual nodes.
Next Steps
- n8n Integration Overview — community node, actions, and searches
- Zapier Integration — managed alternative to n8n
- Outbound Webhooks — full webhook API reference
- CRM Settings — native HubSpot/Salesforce sync