Enable Ghost 5.x Paid Memberships with Stripe on a Self-Hosted Server
Configure Ghost 5.x native paid memberships through Stripe, verify webhook delivery, and roll back safely if needed.
15 Aug 2026, 00:38 UTC

Desired outcome
You want to charge readers for access to newsletters and articles without writing custom checkout code. Ghost 5.x includes native memberships powered by Stripe: Ghost stores member records and subscription state in its database, while Stripe handles cards, subscriptions, and payment events. The useful takeaway is that you only need to connect Stripe keys, add the webhook Ghost provides, define tiers, and update your theme to hide paid content.
Prerequisites
- Ghost 5.x installed on a self-hosted Linux server and managed by Ghost CLI.
- A custom domain with SSL already configured for the Ghost publication.
- A Stripe account. Use test keys for staging and live keys for production; they are not interchangeable.
- Ghost Admin access with the Super Admin role.
- File-system access to the Ghost install directory, typically as the user that owns the installation, plus a recent backup of the database and
content/directory.
Procedure
1. Back up the instance before changing state
Enabling memberships writes new tables and registers a webhook listener, so take a snapshot first.
cd /var/www/ghost
ghost backup
Where to run: in the Ghost installation directory. Permissions: run as the system user that owns the Ghost files; if you run as root, Ghost CLI may refuse or create files the Ghost user cannot read later. Expected result: a timestamped backup archive in the current directory. Risk: the command fails if the disk is full or the directory is not writable.
2. Copy Stripe API keys
Open the Stripe Dashboard and go to Developers → API keys. Copy the publishable key and secret key for the mode you intend to use. In test mode, use test keys; in production, use live keys. Do not mix them.
3. Connect Stripe in Ghost Admin
Open Ghost Admin, navigate to Settings > Membership, and click Connect Stripe. Enter:
- Publishable key
- Secret key
Save the connection. Ghost displays the webhook endpoint URL it expects, for example:
https://yourdomain.com/ghost/webhook
Copy that URL. Ghost registers the endpoint automatically when memberships are enabled.
4. Add the webhook endpoint in Stripe
In the Stripe Dashboard, go to Developers → Webhooks → Add endpoint. Enter the Ghost webhook URL and select these events:
- invoice.payment_succeeded
- invoice.payment_failed
- customer.subscription.updated
- customer.subscription.deleted
Copy the webhook signing secret that Stripe displays. Ghost uses it to verify that delivery requests came from Stripe.
5. Create membership tiers
Still in Ghost Admin under Settings > Membership, add a tier. Example:
- Tier name: Pro
- Price: 10.00 USD per month
- Access: Paid members only
Ghost creates the corresponding Stripe product and price when a member subscribes; you do not need to create the product manually in Stripe first.
6. Gate content with theme helpers
The default Casper theme includes the {{#paid}} and {{#member}} Handlebars helpers. Wrap paid-only content in a post template like this:
{{#paid}}
This article is for paying subscribers only.
{{/paid}}
If you use a custom theme, edit post.hbs and other relevant templates to include these helpers. Without them, Ghost cannot hide content from non-paying visitors.
7. Test with Stripe test mode
Switch Ghost Admin to test mode if you are using test keys. Create a test member, then complete a checkout using Stripe's public test card number 4242 4242 4242 4242. After payment, check Ghost Admin under Members to confirm the member now has the Pro tier, and check Stripe Dashboard under Customers to confirm an active subscription.
Expected checks
- Ghost Admin > Settings > Membership shows Stripe as Connected and lists recent successful webhook deliveries.
- Run
ghost healthfrom the install directory; output should report OK for the database, process manager, and SSL. - A test purchase creates a member record in Ghost and a subscription in Stripe with matching status.
- Logged-out visitors and free members cannot see content wrapped in
{{#paid}}; paid members can.
Limitations
- Ghost does not calculate or remit sales tax. You remain responsible for tax collection and compliance.
- Test and live Stripe keys are not interchangeable. Moving to production requires reconnecting Stripe and verifying the webhook signing secret.
- Webhook delivery failures can desync membership status between Ghost and Stripe. If Stripe is temporarily unreachable, payments may succeed in Stripe without updating Ghost.
- Custom themes may require template changes before paid gating works.
- Verify this procedure against your specific Ghost 5.x release and Stripe region before applying to production.
Rollback and recovery
Because this procedure changes the database and registers a webhook, keep the backup from step 1.
- To restore the pre-membership state, stop Ghost, then run:
cd /var/www/ghost
ghost stop
ghost restore <backup-file>
ghost start
Where to run: the Ghost installation directory, as the owning user. After restore, open Ghost Admin and disable memberships under Settings > Membership so Ghost stops processing webhook events.
If only webhook deliveries were missed during an outage, reconcile manually in the Stripe Dashboard by comparing active subscriptions against Ghost member records. You can also review recent webhook deliveries in Ghost Admin under Settings > Membership to identify failed events.
Practical verification
Open an incognito browser window, visit a post wrapped in {{#paid}}, and confirm the paywall message appears. Log in as a paid member and confirm the article body displays. Then run ghost logs to check for Stripe signature errors or database connection warnings after the test.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.