Skip to content

PayPal checkout loops back to /register (sandbox). NVP capture fails with error 10002. #193

@djkolka

Description

@djkolka

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions