HarborFM

Stripe Payments (BYOK)

HarborFM does not process payments with a platform Stripe account. Eligible show owners connect their own Stripe keys (bring your own key), publish plans, and sell access. Listeners pay via Stripe Checkout and receive a private RSS access token.

Secrets are encrypted with the same secrets key used for exports (HARBORFM_SECRETS_KEY / SECRETS_DIR). For restricted-key permissions, webhook event tables, and local Stripe CLI setup, see the main README "Stripe payments" section.

Who Can Use It

  • defaultCanStripe (Settings > Default Limits): whether newly registered users get Stripe access. Default is on. See Admin and settings.
  • canStripe (Users admin): per-user flag. When off, that user cannot open Stripe Payments or call Stripe API routes.
  • On a show, managers can attach an existing owner credential pack and toggle payments. Only the owner can create, edit, or delete credential packs.

Stripe access is an account flag, not a show role. See Podcasts: Collaborators.

Credential Packs (Test and Live)

Under the show’s Payments UI, create a Stripe account pack:

  1. Display name
  2. Mode: test or live (fixed for that pack; create a second pack to use the other mode)
  3. Restricted secret key (rk_test_… / rk_live_… preferred), publishable key, and webhook signing secret (whsec_…)
  4. Optional verify step that probes Write permissions HarborFM needs

Attach one pack to the show and enable Accept Stripe payments on this show. Use Pause new subscriptions to block Checkout while you edit plans or coupons (existing subscribers keep access). The same pack can be reused on multiple shows owned by that user. Test and live plans/coupons are separate.

Webhook URL (copy from Payments):

https://<your-host>/api/public/stripe/webhook/<credentialsId>

Locally, use the Stripe CLI (pnpm stripe:listen from the repo) and paste the printed whsec_… into the pack. Without valid webhooks, Checkout success may still claim once, but renewals and cancellations will not stay in sync.

The credential wizard lists the restricted-key Write permissions and the webhook events HarborFM needs (select only those events in Stripe, not Select all). Full tables are in the main README.

Plans and Billing Cycle

Plan kinds: Monthly, Yearly, and One-time. At most one active plan per kind per show mode. To change a price, deactivate the current plan and add a new one for that kind (existing subscribers stay on their Stripe price). You can reactivate a deactivated plan only when no other active plan of that kind exists.

Recurring plans support auto-renew by default. Deleting a recurring plan cancels its active subscriptions in that mode and revokes access. Deleting a one-time plan archives the Stripe product but does not revoke past one-time purchases.

Billing cycle (per show):

  • Anniversary (default): renews on the signup anniversary (Stripe default).
  • Month Start: Checkout anchors recurring billing to the 1st of the month (Stripe may prorate the first stub period).

Active-subscriber stats in Payments show per-kind revenue.

Checkout and Access Tokens

Listeners subscribe from the public feed (Subscribe). Checkout creates a Stripe session; after payment, HarborFM fulfills via webhook (checkout.session.completed) and/or the success page claim.

  • Success URL reveals the access token and private RSS URL once (/feed/{slug}/subscribe/success?session_id=…).
  • Private feed path is under /api/public/podcasts/{slug}/private/{token}/rss (token prefix from SUBSCRIBER_TOKEN_PREFIX, default hfm_sub_).
  • Refreshing or reclaiming the same session does not show the full token again; listeners can use Manage Subscription > Recover token (email) if needed.
  • Active coupons enable promotion codes on Checkout.

See Public feeds and embed.

Manage Subscription (Listeners)

From the feed Manage Subscription dialog (cookie or pasted token / private RSS URL):

Action Notes
Manage billing Stripe Customer Portal (recurring)
Turn off auto-renew Cancel at period end; access continues until period end
Renew / keep auto-renewing Undo cancel-at-period-end, or pay a past-due invoice
Regenerate access token Issues a new token (cooldown applies); old token stops working
Request refund Owner reviews under Payments > Refund requests
Recover token Emails access details when email delivery is configured (cooldown applies)

Owners approve or deny refund requests in the show Payments UI. Approving refunds in Stripe and revokes the subscriber token.

Coupons

Per show and mode: create percent or fixed-amount coupons with duration once, repeating, or forever. Optional start/end times and max redemptions. Activate or deactivate without deleting. Discount shape is fixed after create. Synced to Stripe Coupons and Promotion Codes.

See Also