Plugin version: 5.8.5
WooCommerce version: 11.1.0
PHP version: 8.3
Summary:
In includes/class-wc-gateway-paystack.php, process_webhooks() calls sleep(10) immediately after validating the webhook signature, before making any response to Paystack and before calling get_paystack_transaction() to verify the payment. No response of any kind (not even a 200) is sent to Paystack until after this 10-second sleep plus the subsequent verification API call completes.
Impact:
On our site we've measured actual webhook response times of 10.5+ seconds (confirmed via server access logs) for charge.success events, specifically on Bank Transfer payments. We believe Paystack's webhook delivery system (or an intermediate proxy) has a shorter response timeout than this, causing it to occasionally disconnect before the 10+ second processing completes. Because the function does not call ignore_user_abort(true), PHP's default behavior kills the script the moment the client disconnects — stopping execution before the order status is ever updated.
This results in a small but consistent percentage (~4% in our case) of successfully paid orders remaining stuck at "Pending payment" and later being auto-cancelled by WooCommerce's unpaid-order-cancellation cron, even though Paystack has already confirmed the payment. This is especially damaging for Bank Transfer payments, which don't have a redirect-based "verify on return" fallback the way card payments do — the webhook is the only confirmation path.
Evidence:
- Order/reference: 1002351_1789127668 — Paystack paid_at 2026-09-11T11:55:34Z, charge.success event confirmed with gateway_response "Approved"
- Server access log shows the corresponding webhook POST to /wc-api/Tbz_WC_Paystack_Webhook/ with a response time of 10,583ms
- Server PHP max_execution_time is 480s, ruling out a PHP-side execution timeout as the cause
- Order was auto-cancelled by WooCommerce ~99 minutes after payment confirmation, well after ample processing time had passed, and had to be manually corrected
- A second similar occurrence (10.6s response time) was found on a separate date
Suggested fix:
Respond to the webhook immediately after signature/event validation (before the sleep and verification call), using ignore_user_abort(true) plus fastcgi_finish_request() where available, so the sleep/verify/order-update logic runs safely in the background regardless of how quickly the client connection is closed on Paystack's end. Happy to share the exact patch we're testing on our own site if useful.
Plugin version: 5.8.5
WooCommerce version: 11.1.0
PHP version: 8.3
Summary:
In includes/class-wc-gateway-paystack.php, process_webhooks() calls sleep(10) immediately after validating the webhook signature, before making any response to Paystack and before calling get_paystack_transaction() to verify the payment. No response of any kind (not even a 200) is sent to Paystack until after this 10-second sleep plus the subsequent verification API call completes.
Impact:
On our site we've measured actual webhook response times of 10.5+ seconds (confirmed via server access logs) for charge.success events, specifically on Bank Transfer payments. We believe Paystack's webhook delivery system (or an intermediate proxy) has a shorter response timeout than this, causing it to occasionally disconnect before the 10+ second processing completes. Because the function does not call ignore_user_abort(true), PHP's default behavior kills the script the moment the client disconnects — stopping execution before the order status is ever updated.
This results in a small but consistent percentage (~4% in our case) of successfully paid orders remaining stuck at "Pending payment" and later being auto-cancelled by WooCommerce's unpaid-order-cancellation cron, even though Paystack has already confirmed the payment. This is especially damaging for Bank Transfer payments, which don't have a redirect-based "verify on return" fallback the way card payments do — the webhook is the only confirmation path.
Evidence:
Suggested fix:
Respond to the webhook immediately after signature/event validation (before the sleep and verification call), using ignore_user_abort(true) plus fastcgi_finish_request() where available, so the sleep/verify/order-update logic runs safely in the background regardless of how quickly the client connection is closed on Paystack's end. Happy to share the exact patch we're testing on our own site if useful.