Retry Logic
PayMongo automatically retries webhook deliveries that fail — so temporary downtime or an unavailable endpoint won't cause you to miss critical events. Understanding how retries work helps you build a handler that recovers gracefully and avoids processing the same event twice.
What counts as a failed delivery
PayMongo considers a delivery attempt failed if any of the following occur:
- Your endpoint returns a non-2xx HTTP status code.
- Your endpoint does not respond within 30 seconds.
- The connection is refused or cannot be established.
Returning an HTTP status code between 200 and 209, along with a JSON response, tells PayMongo the event was received successfully, and no retry is needed.
Retry schedule
When a delivery fails, PayMongo retries using an exponential backoff schedule. Retries are not guaranteed to land at exact intervals — slight delays may occur depending on system load.
After 12 retries, PayMongo stops attempting delivery. The event is marked as failed and will not be retried.
Handling downtime
If your endpoint experiences planned or unplanned downtime, here's what to keep in mind.
Missed events are not replayed automatically. Once the retry schedule is exhausted, PayMongo will not attempt delivery again. To recover missed events, use the Webhook Dashboard to perform a resend.
Disable your endpoint during extended maintenance. If you know your server will be unavailable for an extended period, disable the endpoint from the Dashboard or via the API. This pauses delivery without losing endpoint configuration. Re-enable it when your server is back — note that events that exhausted their retry schedule while the endpoint was disabled will not be re-delivered.
Respond fast, process async. Your handler should acknowledge receipt immediately by returning a 2xx before doing any processing. If your handler takes too long to respond, PayMongo will treat it as a timeout and retry — potentially resulting in duplicate processing. Offload any database writes, downstream calls, or business logic to a background job after acknowledging the event.
Idempotency
When a payment event occurs, PayMongo sends an HTTP POST request to your registered webhook URL. PayMongo considers a delivery successful only when your server responds with a success status (any HTTP code between 200 and 209).
If your server doesn't respond successfully — because it's temporarily down, responding too slowly, or returning an error — PayMongo will try again automatically.
Because PayMongo retries failed deliveries, there are situations where your server may receive the same notification more than once — for example, if your server received the event but was too slow to respond before PayMongo's timeout, causing a retry.
This is normal behavior for webhook systems. The important thing is that your system is built to handle it gracefully.
What you need to set up
To prevent duplicate notifications from triggering duplicate actions, you should implement the following:
- Acknowledge events immediately Your server should respond with a 200 OK as soon as it receives the event, before doing anything else. This tells PayMongo the delivery was successful and stops further retries. Any business logic — like updating your database or sending a confirmation email — should happen after sending that response.
- Track which events have already been processed
Every event PayMongo sends includes a unique event ID (for example,
evt_xxxxxxxxxxxxxxxxxxxxxxxx). You can store these IDs and check whether an incoming event has already been handled before acting on it. If it has, the event is safely ignored. - Use HTTPS Your webhook URL must use HTTPS with a valid SSL certificate. PayMongo will not deliver events to HTTP endpoints or endpoints with expired or self-signed certificates.
Updated about 3 hours ago