What this problem looks like
PayPal orders marked on-hold after customers paid usually mean instant payment notification or webhooks failed. The money is in PayPal but WooCommerce never got the message.
Sandbox and live credentials are separate. Connecting sandbox on a live domain confuses customers and breaks reconciliation.
Step 1: Use one modern PayPal integration
Deactivate PayPal Standard, old express checkout plugins, and duplicate PayPal Payments installs. Keep WooCommerce PayPal Payments maintained by PayPal. Run the setup wizard under WooCommerce → Settings → Payments and connect your business account with OAuth.
Step 2: Currency and locale requirements
- Store currency must be in PayPal supported list for your region.
- Multi-currency plugins may send amounts PayPal rejects.
- UK sellers need a UK business account for GBP settlements.
Step 3: Smart buttons and checkout flow
If buttons do not render, JavaScript conflicts and CSP rules mirror Stripe issues. Disable minification on checkout. Test PayPal only with card fields disabled temporarily to see redirect flow clearly.
Step 4: IPN and webhook troubleshooting
Legacy IPN URLs still appear on older setups. Modern plugin uses webhooks. In PayPal developer portal, open Webhooks, resend failed events, and read HTTP response codes from your store.
Step 5: Account holds and risk reviews
PayPal can block transactions while reviewing new merchants. Customers see generic payment errors unrelated to WordPress. Check PayPal Resolution Centre and email for account limitation notices before debugging code further.
When to stop DIY and hire help
PayPal plus subscriptions, marketplace vendors, or custom capture flows crosses multiple plugins. BugShield connects PayPal Payments cleanly and fixes stuck on-hold orders at a confirmed price without hourly billing surprises.