Your Stripe Account and API Keys
Two Benecaster features use Stripe: Listener Support donations and built-in membership subscriptions. Both need the same things from your Stripe account — an account, a pair of API keys, and a webhook endpoint — and the steps for getting them are identical.
This page covers that shared half: what to do inside the Stripe Dashboard. Where the keys go afterwards, and which webhook events to subscribe to, depends on which feature you are setting up:
| Setting up | Configure it in | Guide |
|---|---|---|
| Listener Support donations | Settings → Listener Support | Setting Up Listener Support (Stripe Mode) |
| Built-in membership subscriptions | Settings → Membership → Payments | Connecting Stripe for Subscriptions |
If you are setting up both, do this page once and then follow both guides.
What You Need
- A Stripe account. If you don’t have one, create it at stripe.com. Use a Business account, not a personal account — this is what processes payments on behalf of your podcast.
- Your Stripe API keys, generated in the Stripe Dashboard and pasted into Benecaster.
- A webhook endpoint registered in Stripe, so Stripe can tell your site when a payment happens.
Getting Your API Keys
- Log in to your Stripe Dashboard.
- In the top-right corner, make sure you’re in Test mode if you’re setting this up for the first time. You’ll switch to live keys when you’re ready to accept real money.
- Go to Developers → API keys.
- You’ll see two keys:
- Publishable key — starts with
pk_test_(test) orpk_live_(live). This one is safe to expose; it appears in client-side code. - Secret key — starts with
sk_test_orsk_live_. Never share this key. It has full access to your Stripe account.
- Publishable key — starts with
- Copy both. Keep them in a password manager until you paste them into Benecaster.
Restricted keys will not work. Stripe also offers restricted keys with narrowed permissions. Benecaster requires standard secret keys.
Whichever panel you paste them into, secret keys are stored encrypted and are never shown back to you — the panel indicates only that a key is saved. To inspect or rotate one, do it in the Stripe Dashboard.
Changing or Removing a Saved Key
To change a key, paste the new one over it and save. You do not need to clear anything first.
Leaving a secret key field blank and pressing Save keeps the key you already have. Blank means “no change” — it does not erase. That is deliberate, because the field is always blank when the screen loads: the secret is stored encrypted and never shown back to you, so a blank field is the normal state rather than an empty one.
To remove a key, use the Clear control. Each mode with something saved gets a Clear test keys / Clear live keys button, on Settings → Membership → Payments and on a show’s own Payments tab. It asks first — “Remove the saved test keys?” — and removes only after you confirm.
Clearing removes both keys for that mode, publishable and secret, and cannot be undone: the secret was stored encrypted and is not recoverable from Benecaster, so you would need to copy it from Stripe again. The other mode is untouched.
You never need WP-CLI or database access to disconnect a Stripe account.
The site-wide panels genuinely are interchangeable: Settings → Membership → Payments and Settings → Listener Support write the same site-wide keys, so saving in either is reflected in the other. Membership → Payments is the fuller of the two — it shows test and live side by side and is the only place to switch which is active. Per-show keys are a separate store and live at Shows → [show] → Settings → Payments; nothing you enter site-wide changes them.
Registering a Webhook Endpoint
Stripe notifies your site by POSTing events to a URL you register. Without a working webhook, payments succeed at Stripe and your site never finds out — donations go unrecorded, subscriptions go unprovisioned.
-
In the Stripe Dashboard, go to Developers → Webhooks.
-
Click Add endpoint.
-
Paste the webhook URL shown in the Benecaster settings panel you are configuring. Both site-wide panels display it as a read-only field with a copy button, and both show the same endpoint:
https://yoursite.com/wp-json/benecaster/v1/stripe-webhookA show on its own Stripe account has a different endpoint, shown on that show’s Settings → Payments tab:
https://yoursite.com/wp-json/benecaster/v1/stripe-webhook/{show-uuid}The UUID is that show’s own identifier — you do not need to look it up, because the tab builds the full URL and gives you a Copy button. Register it in that show’s Stripe account, not your main one. Registering the site-wide URL in a different Stripe account produces events that can never verify, because each account signs with its own secret.
-
Select the events to listen for. This is the part that differs by feature — see the guide for the feature you’re setting up. Subscribe only to what you need; extra events add load and noise for no benefit.
-
Save, then copy the Signing secret Stripe shows you — a string starting with
whsec_. Paste it back into the Benecaster settings panel.
Benecaster validates the signature on every incoming webhook request. Without the signing secret configured, requests are rejected.
One endpoint per Stripe account. Benecaster receives all Stripe events for an account at a single URL and routes them internally, so if you already registered the endpoint for one feature you do not need a second one — add the new events to the existing endpoint instead.
The dividing line is the account, not the feature and not the site. One Stripe account for everything means one endpoint. A show on its own Stripe account means one more endpoint, registered in that account, with its own signing secret pasted into that show’s Payments tab.
Test Mode
Test the full flow before accepting real payments. With test keys active, no real money moves, test activity stays out of your live Stripe dashboard, and a TEST MODE badge appears on Benecaster’s payment screens.
On a staging site cloned from production, you cannot do this — billing calls are refused whatever mode the keys are in. Test the full flow on your production install before going live, or on a staging site that was installed separately rather than copied. See If You Have a Staging Site.
Test cards — use any future expiry date and any 3-digit CVC:
| Card number | What it simulates |
|---|---|
4242 4242 4242 4242 |
Payment succeeds |
4000 0000 0000 9995 |
Payment declined |
4000 0000 0000 3220 |
Requires 3D Secure authentication |
4000 0000 0000 0341 |
Card attaches but a later payment fails — tests dunning behaviour |
Stripe’s full list is at docs.stripe.com/testing.
Testing webhooks locally. On a local environment Stripe cannot reach your site, so use the Stripe CLI to forward events:
stripe listen --forward-to https://yoursite.local/wp-json/benecaster/v1/stripe-webhook
Testing a show that is on its own Stripe account? Forward to that show’s URL instead:
stripe listen --forward-to https://yoursite.local/wp-json/benecaster/v1/stripe-webhook/{show-uuid}
This matters more than it looks. Events forwarded to the site-wide URL are checked against the site-wide signing secret, so every forwarded event fails signature verification — and the failure looks like broken webhook handling rather than a misdirected test. Copy the URL from the show’s Settings → Payments tab.
The CLI can also fire specific events on demand — stripe trigger payment_intent.succeeded. This is the recommended way to test webhook handling locally.
Switching to Live Mode
Stripe keeps test and live completely separate, and this is where most setups go wrong. Live keys, live webhook endpoints, and live customers are a different world from their test counterparts — nothing carries over.
When you’re ready to take real payments:
-
Get your live keys from the Stripe Dashboard (Developers → API keys, with the Test mode toggle off) and enter them in Benecaster.
✅ Your existing tiers are handled for you. Saving a complete key set sweeps your active paid tiers and creates the matching Stripe Products and Prices for that mode. You do not need to set keys up before creating tiers, and you do not need to re-save each tier afterwards — build your tiers whenever suits you and add the keys when you are ready. The same applies to giving a show its own Stripe account: its tiers are provisioned into that account on save.
-
Check whether your webhook endpoint exists under Live mode, not just Test mode. It usually does not — you will need to add it again and copy the new signing secret, which is different from the test one.
-
Update the signing secret in Benecaster to match the live endpoint.
-
Check the payment mode banner at the top of your Benecaster admin screens. It is the surface
that answers “is any show on this site taking real money through Stripe?”, and on a multi-show
install it is the only one that answers it correctly — a show with its own Stripe account keeps
whatever mode it has set, so switching the site to live does not move it. See
Payment Test Mode.The banner is scoped to Stripe. Its headline follows the Stripe install default and its
states name shows by their Stripe keysets. It is the right check for this go-live step, which is a
Stripe go-live — but it says nothing about a non-Stripe payment gateway add-on. The TEST MODE badge
is the surface that aggregates gateways.Do not use the disappearance of the TEST MODE badge as your go-live check. It reports
payment gateways, not shows: it stays up if a gateway add-on is still in test, and it goes away
even while a show of yours is still rehearsing on its own test keys. -
Run one small real transaction end to end before announcing anything.
Step 2 is the one people miss. Live keys with a test-only webhook produce the worst failure mode available: the customer is charged for real, and your site never hears about it.
Two limits on the automatic back-fill
The sweep fills in what is missing. It does not correct what is already there, and there are two cases where that matters.
Repointing a mode at a different Stripe account does not re-mint anything. If a tier already has live Product and Price IDs and you replace your live keys with a different Stripe account’s, the old account’s IDs stay on the tier — the sweep sees IDs present and leaves them alone. Those IDs do not exist in the new account, so checkout fails against them. This is a real scenario when a podcaster moves to a new Stripe account or switches a show from the site account to its own. If you repoint a mode at a different account, clear the affected tiers’ Stripe IDs so they can be minted fresh, and contact support if you are unsure which are affected.
Buy-ups are not swept. Individual episode buy-ups get their Stripe Products and Prices when the buy-up itself is created or edited, not when a key set is saved. After adding a key set, open and re-save any existing buy-ups so they are provisioned for the new mode.
“Stripe keys need re-entering”
If you see this warning in your WordPress admin, payments are not working right now and the notice is telling you why:
This site has Stripe keys saved in an old format that Benecaster can no longer identify as test or live, so they are not being used and payments will not work.
The fix takes a minute. Open Settings → Membership → Payments and paste your keys into the Test or Live fields — whichever you are running. You are not re-doing setup; you are moving keys you already have into the slots that identify which mode they belong to. Copy them from your Stripe Dashboard under Developers → API keys if you no longer have them to hand.
Why it happens. Very early versions stored one Stripe key pair with no test-or-live label attached. On upgrade, Benecaster sorts that pair into the right mode by reading the key prefix — but if the prefixes do not identify a mode, it deliberately leaves the pair alone rather than guessing. Guessing wrong in one direction would charge real cards from a test environment, so it does not guess. That leaves the keys unusable until you tell Benecaster which mode they are.
This is rare, and old keys on their own do not cause it. If you have leftovers from an older version but a working key set for the mode you are in, you will never see this notice — the working keys are used and the leftovers are ignored. The warning appears only when there is nothing usable to fall back on.
You can dismiss it. Payments are already not working, so it is a diagnosis rather than a guard — dismissing it is the right move if you have deliberately stopped using Stripe.
If You Have a Staging Site
A staging site is a copy of production, which means your live Stripe keys may be sitting in the copied database. Always use test keys on staging.
Benecaster enforces this at the point of entry. Saving live Stripe keys is refused outright on an install it detects as a staging environment, and on an install it detects as a copy of another one — recognised by comparing the URL the install first recorded against the URL it is running at now, which catches a clone sitting at an ordinary domain that no hostname pattern would match. Nothing is written, and the error names the reason. This applies to the site-wide keyset and to a show’s own keys alike. Test keys are never refused, and clearing a keyset always works.
There is a second guard, and it is the one that changes what you can do on a clone. The refusal above happens when someone saves keys. Separately, on an install detected as a copy of another one, the outbound calls themselves are refused — new subscriptions, cancellations, resumes, renewal retries, buy-ups added or removed, and donation intents — whatever mode the keys are in, test included.
That is the part most likely to surprise you: test keys do not lift it. A clone carries production’s real Stripe subscription IDs, and those stay real no matter which keys are loaded, so an automated path could cancel or re-tier a paying subscriber without moving money. The point-of-entry refusal cannot see that; only knowing the install is a copy can. A refused call reports “Billing changes are temporarily unavailable on this site.”, and the operator’s explanation goes to the debug log.
If a genuine production site trips a detector, there is exactly one way back: add
define( 'BENECASTER_IS_PRODUCTION', true );
to your wp-config.php. This is the realistic case for production hosted at a domain that carries a staging label, or for a production site that has legitimately changed domain — the second being the more common of the two. It must live in wp-config.php rather than a setting, because a database-stored override would be wiped by the next staging refresh and would travel onto a copy if a staging database were ever restored the other way. Do not add it to a staging site to get past the refusal.
See Setting Up a Staging Site for Benecaster for the full workflow, including the warning Benecaster shows if it detects live keys on a site it believes is staging — which still matters, because a clone inherited its live keys with the database rather than saving them, so no save ever happened for the refusal to catch.
See Also
Need this built rather than just documented? See our services →