You're building an e-commerce app. A customer completes a payment, and you need to update their order status, send a confirmation email, and notify the warehouse. How does your payment provider tell your app that the payment succeeded?
This is exactly where webhooks come in.
What is a Webhook?
A webhook is an automated HTTP request that one system sends to another when a specific event occurs. Think of it as a "reverse API" - instead of your app asking "Did anything happen?", the other system proactively tells you "Hey, something just happened!"
Traditional API polling works like this:
Your App: "Any new payments?" → Payment API: "No"
Your App: "Any new payments?" → Payment API: "No"
Your App: "Any new payments?" → Payment API: "Yes! Here's the data"
Webhooks flip this around:
Payment API: "A payment just completed!" → Your App: "Got it, thanks!"
This is more efficient, real-time, and reduces unnecessary API calls.
Real-World Webhook Examples
Webhooks are everywhere in modern software:
- Stripe/PayPal sends a webhook when a payment succeeds or fails
- GitHub notifies your CI/CD pipeline when code is pushed
- Slack triggers workflows when messages are posted
- Shopify alerts your inventory system when an order is placed
- Twilio informs your app when an SMS is delivered
Every major platform uses webhooks to enable real-time integrations.
The Webhook Testing Challenge
Here's the problem: webhooks are notoriously difficult to test during development.
Challenge 1: You don't control when they fire
When testing a Stripe integration, you can't just "trigger" a real payment webhook whenever you want. You'd need to make actual payments, wait for processing, and hope the webhook arrives.
Challenge 2: Your local server isn't accessible
Webhooks need a public URL to send requests to. Your localhost:3000 isn't reachable from Stripe's servers. Developers often resort to tunneling tools, which add complexity.
Challenge 3: Inconsistent payloads
Real webhook payloads can vary. A payment webhook might include different fields depending on the payment method, currency, or account settings. Testing all variations is tedious.
Challenge 4: Timing and sequence issues
What happens if a webhook arrives before your database transaction commits? Or if webhooks arrive out of order? These race conditions are hard to reproduce with real services.
Challenge 5: Error handling is blind
When your webhook handler fails in production, you often don't know why. The external service just sees a 500 error. Debugging requires extensive logging and often can't be reproduced locally.
How Mock Servers Solve Webhook Testing
A mock server lets you simulate webhook behavior without depending on external services. Instead of waiting for Stripe to send a webhook, you configure your mock server to send it exactly when and how you need.
This approach gives you:
- Full control over when webhooks fire
- Predictable payloads that match your test scenarios
- Local development without public URLs or tunnels
- Edge case testing for timeouts, failures, and retries
- Reproducible tests that run the same way every time
Webhooks in Mocklantis
Mocklantis provides a complete webhook simulation system. Here's how it works:
Creating a Webhook
In Mocklantis, webhooks are standalone entities that you configure once and bind to multiple endpoints. When any bound endpoint is called, the webhook fires automatically.
You configure:
- Target URL: Where to send the webhook (your app's webhook handler)
- HTTP Method: Usually POST, but supports all methods
-
Headers: Custom headers like
Content-Typeor authentication - Body: The payload to send, with dynamic template support
Template Variables
The real power comes from template variables. Your webhook payload can include data from the original request:
{
"event": "payment.completed",
"orderId": "{{request.body.orderId}}",
"amount": {{request.body.amount}},
"customerId": "{{request.body.customerId}}",
"processedAt": "{{request.timestamp}}",
"transactionId": "{{random.uuid}}"
}
When a request hits your mock endpoint, Mocklantis extracts values from the request and injects them into the webhook payload. This creates realistic, dynamic webhooks that mirror real-world behavior.
Available template variables include:
-
{{request.path.id}}- URL path parameters -
{{request.query.page}}- Query string parameters -
{{request.body.field}}- JSON body fields (supports nested paths) -
{{request.header.X-Custom}}- Request headers -
{{request.timestamp}}- ISO timestamp -
{{random.uuid}}- Generate unique IDs
Webhook Flow
Here's the sequence when a request arrives:
- Client sends request to mock endpoint
- Mocklantis returns the mock response immediately
- Webhook fires asynchronously (doesn't block the response)
- Your webhook handler receives the notification
This "fire-and-forget" approach mirrors how real webhook systems work. The webhook execution never affects your endpoint's response time or success.
Advanced Configuration
For realistic testing, Mocklantis supports:
Delay: Add latency before the webhook fires. Real payment processors don't send webhooks instantly - there's usually a 1-5 second delay. Simulate this to test your app's behavior during that window.
Retry Logic: Configure automatic retries if your handler returns an error. Set retry count (up to 10) and delay between attempts. Test how your app handles webhook redelivery.
Authentication: Support for Basic Auth, Bearer tokens, and API keys. Test that your webhook handler properly validates incoming requests.
Timeout Control: Set how long to wait for your handler's response. Test timeout scenarios without waiting forever.
Binding Webhooks to Endpoints
A single webhook can be bound to multiple endpoints. For example, an "Order Notification" webhook might fire when:
-
POST /api/orders(new order created) -
PUT /api/orders/:id/status(status change) -
DELETE /api/orders/:id(order cancellation)
This models real-world scenarios where the same external system needs to know about multiple types of events.
Practical Testing Scenarios
Testing Payment Flows
Create a mock POST /api/checkout endpoint that returns a success response, bound to a webhook that hits your POST /webhooks/payment handler. Now you can test your entire payment flow locally, including the webhook processing.
Testing Failure Handling
Configure a webhook with a short timeout and point it at a slow endpoint. Verify your app handles webhook timeouts gracefully. Then test retry behavior by returning 500 errors and checking that retries occur.
Testing Race Conditions
Add a 2-second delay to your webhook. Make a request and immediately query your database. Is the order in a "pending" state? Does your UI handle this correctly? These timing issues are nearly impossible to test with real services.
Testing Idempotency
Webhooks can be delivered multiple times. Configure retries and verify your handler doesn't create duplicate records or send duplicate emails when the same webhook arrives twice.
Best Practices
Always verify webhook signatures in production. While testing, you can skip this, but your production handler should validate that webhooks come from the expected source.
Make handlers idempotent. Use unique identifiers to detect and ignore duplicate deliveries.
Respond quickly. Return a 200 response immediately and process asynchronously. Webhook senders often have short timeouts.
Log everything. Webhook debugging is hard without detailed logs of what was received and how it was processed.
Test error scenarios. Don't just test the happy path. Simulate network failures, invalid payloads, and authentication errors.
Conclusion
Webhooks are fundamental to modern application architecture, enabling real-time communication between services. But their asynchronous, external nature makes them challenging to test during development.
By using a mock server with webhook support, you gain full control over the testing process. You can simulate any webhook scenario, test edge cases, and build confidence in your webhook handlers before deploying to production.
The next time you're integrating with a webhook-based service, consider setting up mock webhooks first. Your future self will thank you when debugging that mysterious production issue.
For this and more features: mocklantis.com
Download mocklantis: mock server
Top comments (0)