Powered by Smartsupp

Handling Webhooks at Scale

Best practices for processing asynchronous payment notifications reliably.

Webhooks are the backbone of any asynchronous payment system. They notify your application when a payment succeeds, fails, or is refunded. However, handling them at scale presents unique challenges.

The Challenge: Reliability

What happens if your server is down when Lumen Pay sends a webhook? Or if your database locks up? If you miss a "payment.success" webhook, you might never deliver the product to the customer.

Best Practices

1. Idempotency

Always design your webhook handler to be idempotent. This means that processing the same webhook event twice should have the same effect as processing it once. We send a unique `event_id` with every webhook. Store this ID and check it before processing.

if (Event::exists($payload['id'])) {
    return response('Already processed', 200);
}

2. Respond Quickly

Do not perform heavy logic (like sending emails or generating PDFs) inside the webhook controller. Acknowledge receipt with a `200 OK` immediately, and push the actual work to a background queue.

3. Verify Signatures

As mentioned in our security post, always verify the `HTTP_X_LUMEN_SIGNATURE` to ensure the request actually came from us.

4. Handle Retries Gracefully

Lumen Pay uses exponential backoff. If your server returns a 500 error, we will retry sending the webhook after 1 minute, then 5 minutes, then 30 minutes, up to 24 hours. Ensure your logs monitor for these failures.

← Previous The Rise of Mobile Money in West Africa Next → Withdrawing to Mobile Money via Eversend

Read Next