404 on /customer-portal/ (or custom slug)#

Symptoms: Visiting your portal URL returns "Page not found."

Fixes:

  1. Confirm Customer Portal Slug is not empty in Stripe Portal settings.
  2. Go to Settings → Permalinks and click Save Changes (flush rewrite rules).
  3. Confirm pretty permalinks are enabled (not "Plain").
  4. If using caching (page cache, CDN), purge cache after permalink changes.

Permalink settings

Invalid or expired token#

Symptoms: Customer clicks the email link and sees Invalid or expired token.

Causes:

  • Link is older than one hour (token TTL).
  • Link was already used (tokens are one-time).
  • Wrong URL or truncated link in the email client.

Fixes:

  • Request a new login link from the portal form.
  • Ensure email clients are not breaking long URLs.

Stripe API / portal errors#

Symptoms: Error message mentioning Stripe, or blank error after clicking the magic link.

Checks:

  1. Secret API key is correct for Test vs Live mode.
  2. Customer Portal is enabled in Stripe Dashboard → Settings → Billing → Customer portal.
  3. Review wp-content/debug.log if WP_DEBUG_LOG is enabled — Stripe errors may be logged.

Stripe Customer portal settings

Email not received#

Symptoms: Customer submits the form but no email arrives.

Checks:

  1. Test wp_mail() on your host (SMTP plugin recommended).
  2. Check spam/junk folders.
  3. If Only allow existing Stripe customers is on, confirm the email exists in Stripe (no email is sent otherwise).
  4. Verify your host is not blocking outbound mail.

Example login email

Rate limit reached#

Symptoms: After several rapid submissions, the customer sees: “Too many requests. Please wait a few minutes and try again.”

Cause: v1.0.6 enforces a per-email and per-IP rate limiter of 5 requests per 10 minutes. This prevents the form from being abused as a mail relay or enumeration oracle.

Fixes:

  • Ask the customer to wait 10 minutes, then try again.
  • For a stuck legitimate user, an admin can clear the counter with WP-CLI:
wp lscp limiter-reset [email protected]

See Security and Privacy for the full rate-limit model.

Shortcode shows standalone confirmation page#

Symptoms: After submitting the shortcode form, the customer sees a plain page with only the confirmation text instead of the message appearing within your themed layout.

Expected behavior: The plugin uses wp_die() on template_redirect for the confirmation. This is by design, not a misconfiguration — it lets the same handler serve both the dedicated endpoint and the shortcode-on-any-page case.

Mitigation: Use the dedicated endpoint for a full-page experience, or embed the shortcode on a page where a standalone confirmation is acceptable.

Freemius opt-in screen on first visit#

Symptoms: Admin shows Freemius activation/opt-in when opening Stripe Portal.

Fix: Click Skip or complete opt-in. This is the Freemius SDK onboarding flow for the free plugin.

Manually resend a magic link#

If a customer cannot receive the email and you want to verify deliverability or push a fresh link from the server, use the WP-CLI command:

wp lscp send [email protected]

To inspect current settings (Stripe key masked) and outstanding tokens:

wp lscp config
wp lscp purge-tokens   # delete every outstanding magic-link token

Still stuck?#

  1. Note your plugin version (Stripe Portal page or Plugins list). v1.0.6+ requires PHP 7.4+.
  2. Confirm WordPress and PHP versions meet requirements (WP 5.0+, PHP 7.4+, tested to WP 6.9).
  3. Open a support ticket with steps to reproduce and any relevant log excerpts (redact API keys).