Documentation Index
Fetch the complete documentation index at: https://docs.waffo.ai/llms.txt
Use this file to discover all available pages before exploring further.
What Are Webhooks?
Webhooks are automatic notifications that Waffo Pancake sends to your server when something happens — a payment succeeds, a subscription renews, a refund is processed, etc. Why you need them:- Automate delivery: Send download links or grant access immediately after payment
- Keep your system in sync: Update your database when subscription status changes
- React to events: Handle failed payments, cancellations, and refunds in real time
Step 1: Add a Webhook in the Dashboard
Choose a Format
Select how the payload should be shaped for the destination — Raw JSON for your own backend, a chat-platform format (Slack / Discord / Feishu / Telegram) so messages render natively in that tool, or OpenClaw / Hermes (the self-hosted Pancake plugin) for custom routing and downstream logic. See Choose a payload format below.

Set Your Webhook URL
Enter the URL where Waffo Pancake should send event notifications.
- Test mode URL: Your development/staging server (e.g.,
https://staging.yoursite.com/webhooks/waffo) - Production URL: Your production server (e.g.,
https://yoursite.com/webhooks/waffo)
If you picked Telegram in the previous step, you’ll fill in a Bot Token and a Chat ID instead of a URL. See Telegram below for how to obtain them.
Production note: Live Mode webhooks only deliver after your store passes review. While the store is still under review, use Test Mode webhooks against staging code paths.
Choose a payload format
Waffo can deliver each event in the format your destination expects, so you don’t have to write a translator. Pick the format when you add the webhook; you can re-add a webhook with a different format if you change your mind.| Format | Use when… | Endpoint |
|---|---|---|
| Raw (default) | You’re calling your own backend and want the canonical, signed JSON payload. | Any HTTPS URL |
| Feishu / Lark | You want events posted into a Feishu group via a custom bot. | https://open.feishu.cn/open-apis/bot/v2/hook/<hook-id> |
| Slack | You want events posted into a Slack channel via an Incoming Webhook. | https://hooks.slack.com/services/T.../B.../<token> |
| Discord | You want events posted into a Discord channel via a channel webhook. | https://discord.com/api/webhooks/<id>/<token> |
| Telegram | You want events posted into a Telegram chat or group via a bot. | Bot Token + Chat ID (URL is built for you) |
| OpenClaw / Hermes | You’re routing events through the self-hosted Pancake plugin for custom downstream logic. | https://relay.waffo.ai/webhook/<webhook-id> |
Raw
- In your backend, expose an HTTPS endpoint that accepts
POST application/json. - Paste the URL into the Endpoint URL field.
- After saving, open the webhook detail page and copy the Signing Public Key — you’ll use it to verify deliveries (see API Reference — Webhooks).
Feishu / Lark
- In your Feishu group, add a Custom Bot and copy its webhook URL.
- The URL looks like
https://open.feishu.cn/open-apis/bot/v2/hook/<hook-id>(oropen.larksuite.com/...outside China — both work). - Paste it into the Endpoint URL field.
Slack
- In your Slack workspace, install an Incoming Webhook for the destination channel.
- Copy the webhook URL — it looks like
https://hooks.slack.com/services/T.../B.../<token>. - Paste it into the Endpoint URL field.
Discord
- In the destination channel, open Edit Channel → Integrations → Webhooks → New Webhook and copy the URL.
- Format:
https://discord.com/api/webhooks/<id>/<token>. - Paste it into the Endpoint URL field.
Telegram
Telegram needs both a Bot Token and a Chat ID — Waffo builds the TelegramsendMessage URL for you.
- Talk to @BotFather and create (or pick) a bot. Copy its token, e.g.
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11. - Add the bot to the destination chat or channel and grant it permission to send messages.
- Get the chat ID. The easiest way: send a message in the chat, then visit
https://api.telegram.org/bot<TOKEN>/getUpdatesand copy thechat.idfrom the response. - In the Add Webhook modal, choose Telegram, paste the Bot Token and Chat ID, and save.
https://api.telegram.org/bot<TOKEN>/sendMessage with chat_id set to the value you provided.
OpenClaw / Hermes (Pancake plugin)
The Pancake plugin is Waffo’s self-hosted relay. It receives events from Waffo, runs your custom logic (templating, rate-limiting, multi-fan-out), and forwards messages to wherever you want. OpenClaw and Hermes are two ready-to-run flavors of the plugin; pick whichever matches your stack.-
Install the plugin with the matching setup command:
Full setup guide: github.com/waffo-com/waffo-pancake-plugin.
-
After install, the plugin gives you a relay URL of the form
https://relay.waffo.ai/webhook/<webhook-id>. - In the Add Webhook modal, choose OpenClaw / Hermes, paste the relay URL, and save.
Step 2: Understand Event Types
Waffo Pancake sends these webhook events:Order Events
| Event | When It Fires | Common Action |
|---|---|---|
order.completed | Order completed successfully | Deliver product, grant access |
Subscription Events
| Event | When It Fires | Common Action |
|---|---|---|
subscription.activated | Subscription activated | Create account, set limits |
subscription.payment_succeeded | Subscription payment succeeded | Extend access period |
subscription.updated | Subscription details changed | Update access level |
subscription.canceling | Cancellation requested | Notify team, send retention offer |
subscription.uncanceled | Subscription reactivated | Restore full access |
subscription.canceled | Subscription fully ended | Revoke access |
subscription.past_due | Payment failed | Notify customer, retry |
Refund Events
| Event | When It Fires | Common Action |
|---|---|---|
refund.succeeded | Refund processed | Revoke access, update records |
refund.failed | Refund processing failed | Notify merchant, investigate |
Step 3: Set Up Email Notifications
In addition to webhook events, you can configure email notifications for both you and your customers.Merchant Notifications
Go to Settings → Notifications to choose which events trigger email alerts to you:- New orders
- New subscriptions
- Failed payments
- Refund requests

Customer Notifications
Customers automatically receive emails for:- Order confirmation
- Subscription confirmation
- Subscription renewal
- Subscription cancellation
- Payment failure
How Webhooks Work
Retry Policy
If your server doesn’t respond with a 2xx status code, Waffo Pancake retries:| Attempt | Delay |
|---|---|
| 1st retry | 5 minutes |
| 2nd retry | 30 minutes |
| 3rd retry | 2 hours |
| 4th retry | 8 hours |
| 5th retry | 24 hours |
For Developers: Code Integration
If you’re integrating webhooks with your server, here’s how the flow works:1. Create a Webhook Endpoint
Your server needs a POST endpoint to receive events. The specific implementation depends on your tech stack.2. Verify the Signature
Every webhook request includes a signature header for security. Verify it to ensure the request came from Waffo Pancake, not a malicious third party.3. Process Events
Parse the event type and data, then take the appropriate action (deliver product, update subscription status, etc.).4. Respond Quickly
Return a 200 status code as fast as possible. If you need to do heavy processing, do it asynchronously after responding.For detailed code examples and signature verification, see the API Reference — Webhooks.
Testing Webhooks
Make a Test Purchase
Use test mode to create a purchase. This triggers webhook events to your test URL.
Local development with ngrok
When you’re building your webhook handler locally, Pancake’s servers can’t reachhttp://localhost:3000 directly. You need a public HTTPS tunnel that forwards inbound requests to your local port. We recommend ngrok — it’s free for development and preserves all custom headers (including X-Waffo-Signature).
Why a tunnel is required
Webhook delivery is inbound to your server: Pancake POSTs to whatever URL you configure. A localhost URL is only reachable from your own machine, so without a tunnel the requests never arrive. The tunnel gives your local server a public HTTPS hostname for the duration of your dev session.Install and start ngrok
Install
- macOS:
brew install ngrok - Windows / Linux: download from ngrok.com/download
Authenticate (free tier is fine)
Sign up at ngrok.com, grab your authtoken from the dashboard, then run:
Wire it into Pancake
Configure the Test Webhook URL
In the Merchant Dashboard, open your store and go to Settings → Webhooks. Paste the ngrok URL (with your handler path appended, e.g.
https://abc-123.ngrok-free.app/api/webhooks/waffo) into Test Webhook URL and select the events you want to receive. Save.Trigger an event
Either click Send test event in the Dashboard, or perform a real action in test mode (e.g., create a checkout and complete it with a test card).
Inspect the request
Open ngrok’s local web inspector at http://127.0.0.1:4040 — it shows every request that came through, including headers and body. Confirm the
X-Waffo-Signature header is present.Common pitfalls
| Issue | Why it happens | Fix |
|---|---|---|
localtunnel always returns 401 on signature verification | localtunnel strips custom HTTP headers, so X-Waffo-Signature never reaches your handler | Use ngrok or cloudflared instead — both preserve all headers |
| The ngrok URL changed after restart | The free tier issues a new random subdomain on every ngrok http run | Update the Test Webhook URL in the Dashboard each time. For frequent dev, ngrok’s paid tier offers reserved subdomains |
| Events stop arriving after a while | Free ngrok sessions expire after a few hours | Restart ngrok http 3000 and re-paste the new URL |
| Pancake retried the event multiple times | Your handler returned a non-2xx response and the delivery was retried with exponential backoff | Fix the handler, then either wait for the next retry or use Resend in the Dashboard’s webhook delivery log |
Cloudflared as an alternative
If you prefer a no-account option, cloudflared works similarly:*.trycloudflare.com URL you can paste into the Dashboard. The trade-off is no built-in request inspector UI — you’ll rely on your own server logs.
Quick verification checklist
- Local server is running and listening on the expected port
-
ngrok http <port>is running, forwarding URL captured - Test Webhook URL in Dashboard matches the current ngrok URL (with handler path)
- Inbound request visible at http://127.0.0.1:4040 with
X-Waffo-Signatureheader - Local logs show
verifyWebhookreturning success and your event handler running
Best Practices
- Respond quickly: Return 200 immediately, process asynchronously
- Handle duplicates: Events may be sent more than once — make your processing idempotent
- Verify signatures: Always verify the webhook signature before processing
- Log everything: Keep logs of received webhooks for debugging
- Monitor failures: Check your Dashboard for failed webhook deliveries
Checklist
- Webhook URLs configured for test and production
- Email notifications configured for your team
- Customer notification preferences set
- Test webhook received and processed successfully
- Signature verification implemented (if using code integration)
Next Steps
Manage Refunds
Handle refund requests and track refund status
API Reference — Webhooks
Detailed webhook payload format and code examples
