Payment Page needs three things on a page with a form: its REST routes must be reachable, its scripts must load unchanged, and the page must be served fresh rather than from a cache.
Other Stripe plugins#
No conflict. Payment Page ships its own copy of the Stripe PHP library under a private namespace (PaymentPage\Vendor\Stripe), so another plugin that bundles a different Stripe library cannot replace it. Both can run on the same site.
REST API blocked#
The payment form calls /wp-json/payment-page/v1/ from the visitor's browser without a login, and Stripe and PayPal send webhooks to the same namespace. Anything that disables the REST API for logged-out visitors, or blocks /wp-json/, stops payments.
- Symptom: the form shows an error when the buyer pays, and the browser's Network tab shows a 401, 403 or 404 response for a
/wp-json/payment-page/v1/request. Or the Stripe Dashboard shows failed webhook deliveries. - Fix: turn off "Disable REST API" style settings in security and performance plugins (Perfmatters has one), or allow the
payment-page/v1namespace. Allow Stripe's and PayPal's webhook requests through any firewall or bot protection. If no plugin is responsible, ask your host whether a server rule blocks/wp-json/.
Page caching and CDNs#
Payment Page marks every page that shows a form as not cacheable. It defines DONOTCACHEPAGE and sends Cache-Control: private, no-store, no-cache, must-revalidate, max-age=0 and Surrogate-Control: no-store. Caching plugins that respect these, such as WP Rocket, W3 Total Cache, WP Super Cache and LiteSpeed Cache, need no changes.
- Symptom: a cache that ignores these signals (for example a CDN rule that caches all HTML) serves an old copy of the form. Buyers see "This payment form changed. Please reload the page and try again." or wallet buttons that do not work.
- Fix: exclude your form pages from that cache rule, then purge them.
Script optimization#
The form runs from payment-page/interface/app/app.min.js (which needs jQuery, wp-util and Lodash) and an inline payment_page_data configuration script. That script then loads Stripe.js from js.stripe.com and the PayPal SDK from www.paypal.com/sdk/js. Payment Page tells WP Rocket to leave its inline configuration out of JavaScript optimization automatically.
- Symptom: the form is blank, appears only after the visitor scrolls or clicks, or the browser console shows JavaScript errors.
- Fix: in your optimization plugin, exclude
app.min.js, the inlinepayment_page_datascript, jQuery,js.stripe.comandpaypal.com/sdkfrom minify, combine, defer and delay settings.
Popups, page builders and custom templates#
Payment Page loads its scripts only on pages where it detects a form: a single payment form page, the [payment-page-payment-form] or [payment-page-success-details] shortcode in the page content, or the Payment Page Elementor widget. A form inside a popup, a template part or content loaded after the page may not be detected, so it never appears.
Use the payment_page_force_universal_interface filter to load the scripts on those pages:
add_filter( 'payment_page_force_universal_interface', function ( $force ) {
return $force || is_page( array( 'pricing', 'donate' ) );
} );
Reverse proxies and "Too many requests"#
Payment Page rate-limits its public checkout routes by the visitor's IP address, which it reads from REMOTE_ADDR. Behind a reverse proxy or CDN that does not pass the real visitor IP to WordPress, every buyer appears to share one IP address.
- Symptom: on a busy form, checkout requests fail with HTTP 429 ("Too many requests" or "Too many payment attempts").
- Fix: configure the web server to restore the visitor IP from the proxy's trusted header (for example
mod_remoteipon Apache orreal_ipon nginx). Ask your host if you are not sure.
Theme styling#
Some themes style form labels and inputs in ways that clash with the form layout.
- Switch to a default WordPress theme with no custom CSS and check the form again.
- If the problem goes away, use the browser's inspector to find the exact theme rule that conflicts.
- Write an override scoped to the form and that rule only. Avoid site-wide
!importantoverrides, which can break responsive layouts.
Reporting a conflict#
If disabling one plugin fixes the problem, contact support with the plugin name and version, the setting involved, the failing URL and the response status from the Network tab.