-
-
Notifications
You must be signed in to change notification settings - Fork 68
Description
Environment
WP Ultimo: [vX.Y.Z]
WordPress: [v6.8.x]
PHP: [7.4/8.x]
CDN/Proxy: Cloudflare (SSL/TLS Full (strict))
Multisite: Subdomain mode (WaaS)
Gateway in use
WP Ultimo – PayPal (Standard/Express – NVP) with Sandbox ON
(Settings show API Username / API Password / API Signature — not REST/PPCP.)
Observed behavior
Customer goes to /register, chooses a plan, clicks Finish Payment.
Redirects to sandbox.paypal.com, buyer approves.
After clicking “Pay now,” PayPal returns to:
https://example.com/register/?payment=[PAYMENT_CODE]&wu-confirm=paypal&token=EC-[...]&PayerID=[...]
The page loops/stays on /register; payment/subscription is not completed.
Expected
After the return, WP Ultimo should capture the payment and activate the subscription/site.
What I already verified
Return handler DOES run (mu-plugin log on init):
[UTC timestamp] WU PayPal RETURN: {"payment":"[PAYMENT_CODE]","wu-confirm":"paypal","token":"EC-[...]","PayerID":"[...]"}
IPN endpoint is reachable (for Standard/Express):
POST https://example.com/?wu-listener=paypal returns 200.
Log:
[UTC timestamp] WU PayPal LISTENER HIT (legacy IPN): {"wu-listener":"paypal"}
Server can reach PayPal NVP, but PayPal rejects the capture with 10002
(test call to https://api-3t.sandbox.paypal.com/nvp from the server):
ACK=Failure&L_ERRORCODE0=10002&L_SHORTMESSAGE0=Security error&L_LONGMESSAGE0=Security header is not valid
Log excerpt:
[UTC timestamp] WU NVP TEST CODE: 200
[UTC timestamp] WU NVP TEST BODY: ... ACK=Failure ... 10002 ... Security header is not valid
Cloudflare exclusions in place (so CF is not the cause):
Cache bypass + Rocket Loader/Minify OFF for: /register, /wp-json/*, /wp-admin/admin-ajax.php
WAF “Skip” for webhooks/listeners
Tested with Development Mode as well
Control tests on same server:
WooCommerce PayPal Payments (PPCP/REST) completes successfully (no loop).
Stripe in WP Ultimo completes successfully.
Interpretation
The loop occurs after the return, so the plugin’s capture step (NVP DoExpressCheckoutPayment) appears to fail.
PayPal’s 10002 means invalid NVP credentials or mode mismatch. I entered the sandbox seller account’s NVP Username/Password/Signature in WP Ultimo with Sandbox ON. If the gateway also requires a specific merchant email or PDT token, please confirm.
Questions
Please confirm this gateway is NVP/Express and list the exact required fields (NVP trio only? merchant email? PDT?).
Where can I enable verbose logging to capture the raw NVP response inside WP Ultimo instead of silently looping?
Are there known conditions that cause a redirect loop when NVP capture fails (e.g., missing admin-ajax call, nonce/session), or should the PayPal error be surfaced to the user/admin?
If the recommended path is PayPal Commerce (PPCP/REST), how do I enable that in WP Ultimo?
Hitting https://example.com/wp-json/wp-ultimo/v1/paypal/webhook currently returns 404, suggesting the PPCP route is not registered in my build.
Please provide the exact fields (Client ID/Secret, Webhook ID) and required webhook URL for PPCP in WP Ultimo.
Extras
Domain redacted: using https://example.com for all references.
Happy to provide a temporary admin login or full debug log if needed.
Thanks!