SKILLMERC tools

PayFast says paid, WooCommerce order still pending

The shopper paid, PayFast shows the money, but the order in WooCommerce is still Pending payment or On hold. This almost always means one thing: PayFast's payment notification (the ITN, Instant Transaction Notification) never reached your store, or it reached it and your PayFast plugin rejected it.

WooCommerce does not learn about a PayFast payment from the shopper's browser. It learns from a server-to-server POST that PayFast sends to your store's notify URL. If that POST fails, the order never moves.

First: fix the order that is stuck

  1. Log in to PayFast and confirm the payment really completed (the amount and the order number in the item description).
  2. In WooCommerce, open the order, set the status to Processing (or Completed), and add a private note with the PayFast payment ID. Stock is reduced and emails go out as normal.

Then find the cause, or the next order gets stuck too.

Step 1: turn on your plugin's debug log

Most PayFast plugins for WooCommerce have a debug or log setting. Turn it on, place a small test order (sandbox mode is fine), then read WooCommerce > Status > Logs and pick the PayFast log for today.

Step 2: the ITN never arrives

PayFast's own help centre lists the usual reasons:

curl -i -X POST "https://yourstore.co.za/?wc-api=YOUR_GATEWAY_ID" -d "test=1"

You want a 200 or a plain error from the plugin, not a 301, 302, 403 or a firewall challenge page. The exact URL is in your gateway's settings or documentation.

PayFast retries a notification that does not get a 200 back: again immediately, then after 10 minutes, then at longer and longer intervals until it gives up. So once you fix the cause, recent stuck orders may update on their own. In the sandbox, notifications are sent only once, so a failed sandbox test will not retry.

Step 3: the ITN arrives but is rejected

The log message tells you which check failed:

Log message Cause Fix
Invalid signature / signature mismatch The salt passphrase in PayFast and in the plugin differ See PayFast ITN invalid signature
Bad source IP / invalid source Your site is behind Cloudflare or another proxy, so the request seems to come from the proxy See PayFast bad source IP behind Cloudflare
Amount mismatch The order total changed after checkout (a plugin edited the order, or currency rounding) Check for plugins that change the order total after payment starts
Bad access of page / validation failed Your server could not call PayFast back to confirm the data (outgoing HTTPS or cURL blocked) Ask your host to allow outgoing HTTPS to www.payfast.co.za

If you want a plugin that tells you the reason

We make a free PayFast gateway, Skillmerc Payment Gateway for PayFast. It logs every rejected ITN with the exact reason (signature, amount, source host, server confirmation), has a reverse proxy setting for Cloudflare, supports the checkout block and HPOS, and does refunds from the order screen. It is independent and not made by PayFast. The fixes above work with any PayFast plugin.


More PayFast and WooCommerce fixes