self-hosted payment gateway software

Trace webhook failures from payment event to PHP endpoint

A practical fault-isolation path for signed callbacks, queue retries and PHP servers—without assuming every gateway exposes the same controls.

By Dietrich Rust·October 26, 2026·4 min read
What matters here
  1. A failed webhook delivery does not by itself mean the payment failed.
  2. Verify signed callbacks against the exact request body and the documented signing method.
  3. Make webhook handlers safe to run more than once before increasing retry volume.

A payment can succeed while the callback that updates an order fails. Treat those as separate events. First establish what happened to the payment; then trace the notification from its source to your PHP endpoint and determine whether a retry is safe.

OwnPay is self-hosted payment gateway software for PHP servers. It provides cryptographically signed webhooks and a double-entry bookkeeping ledger. The exact queue controls, delivery logs and signature details available depend on the installation and its gateway integration. Check the documentation for your version rather than assuming a particular dashboard, header name or retry setting exists.

Start with one failed delivery

Pick a single payment and record its transaction identifier, amount, currency, event type and approximate time. Compare the gateway’s payment record with OwnPay’s ledger and the state in your application. That separates a payment problem from a notification problem. If the payment is recorded but your order is stale, focus on delivery and handling; do not trigger a second charge to test the callback.

Next, trace the delivery through the records available to you. Look for the event being created, an outbound attempt, the destination response and any subsequent attempt. If your setup does not expose a particular stage, note that gap and inspect the relevant gateway or server logs. The goal is to identify the last confirmed step, not to infer delivery from the payment state alone.

Classify the failure before changing retries

  • No request reached the endpoint: Check the configured destination, DNS resolution, TLS certificate validity, firewall rules and whether the PHP server was reachable at the event time. Review web-server access logs as well as application logs.
  • The endpoint returned an error or timed out: Check PHP error logs, request limits, process capacity and any proxy timeout. A handler that waits on slow downstream work can fail even when the server is otherwise healthy.
  • The request arrived but signature verification failed: Compare the verification procedure with the documentation for that integration. Confirm the correct secret and key rotation state. Verify against the exact raw request body before parsing or re-encoding it; middleware that changes bytes can break verification.
  • The endpoint accepted the request but the order did not change: Inspect application validation, event-to-order mapping and database errors. A successful HTTP response only confirms what your endpoint chose to acknowledge.

Do not “fix” signature errors by turning verification off. Avoid logging signing secrets or unrestricted customer data while debugging. If you need to retain a sample, limit access and redact sensitive fields.

Make retries safe before replaying events

Webhook delivery is commonly at-least-once in practice: a sender may repeat an event when it cannot confirm a successful response. Your handler should therefore tolerate the same event arriving again. Store a durable record of processed event identifiers where available, and make order transitions conditional so a duplicate notification cannot create a second fulfillment, credit or refund.

Acknowledge only after the event has been validated and accepted durably by your application. If you acknowledge before saving the work, a process crash can lose it while the sender believes delivery succeeded. For longer jobs, persist the validated event to an application-controlled work queue before returning success, then process that job separately.

For retry policy, inspect the settings and documentation for the specific queue or gateway integration in use. Establish what the system actually configures: retryable response conditions, delay or backoff, maximum attempts, and how exhausted events are surfaced or replayed. OwnPay’s confirmed product details do not specify particular retry controls, so do not copy a setting name or schedule from another integration. If the installation exposes no control, use its documented behavior and monitor failed deliveries instead of assuming a setting exists.

Replay deliberately and verify the outcome

After correcting the cause, replay one known failed event if the integration supports it. Check the endpoint response, application logs and resulting order state. Then verify that processing the same event a second time does not duplicate the business action. Keep a record of the event identifier and outcome so future operators can distinguish a replay from a new payment.

For OwnPay installations, cryptographically signed webhooks provide a basis for authenticating callbacks, but they do not make endpoint code reliable by themselves. Confirm the documented signature procedure, preserve the request body needed for verification, and keep the handler’s response path short. If the callback updates another billing system, map the event and invoice state carefully; the sequence in the WHMCS callback setup guide is useful background.

Close the incident with a small operational check: one successful delivery, one controlled duplicate, and an alert or review process for events that remain unprocessed. That is more useful than raising retry volume before you know whether the fault is reachability, signature verification or application logic.

More from OwnPay News

Put a self-hosted checkout on your own domain

A practical sequence for mapping a checkout domain, setting up TLS, and applying merchant branding without assuming controls your installation may not expose.

By Zaid Hammad·October 26, 2026