Setting up Ghost Members (Subscriptions/Paywall)
Ghost Members — built-in subscriber system without external plugins. Integrates with Stripe for paid tiers. Supports free subscribers (email list), paid tiers with monthly/yearly billing, and paywall content.
Activation and Basic Setup
In Ghost Admin: Settings → Memberships:
- Enable Members: yes
- Default post access: Members only / Paid-members only / Free
- Portal: configure signup button and forms
Connecting Stripe
Admin → Settings → Memberships → Connect with Stripe
Requires Stripe account (Standard or Connect). Ghost creates Products and Prices in Stripe automatically. Webhooks configured by Ghost CLI automatically.
Access Levels (Tiers)
Admin → Settings → Memberships → Tiers
Each Tier has:
- Monthly/yearly prices in Stripe
- Benefits list (displayed on subscription page)
- Description
Paywall in Content
In Koenig editor insert Members divider:
[Open part of article]
⚡ Members Only [insert "Members Only" card]
[Premium content — available only to subscribers]
In Handlebars theme:
{{! post.hbs}}
{{#post}}
{{#if access}}
{{! User has access — show content}}
<div class="gh-content">{{content}}</div>
{{else}}
{{! No access — paywall}}
<div class="gh-content">{{content}}</div>
{{! Ghost automatically cuts content at marker}}
<div class="paywall" data-members-only>
{{#if @member}}
{{! Authorized, but no needed tier}}
<h3>This article is for paid subscribers</h3>
<a href="#/portal/upgrade" data-portal="upgrade">Upgrade subscription</a>
{{else}}
{{! Not authorized}}
<h3>Read without limits</h3>
<a href="#/portal/signup" data-portal="signup/free">Subscribe for free</a>
<a href="#/portal/signup" data-portal="signup">Become paid subscriber</a>
{{/if}}
</div>
{{/if}}
{{/post}}
Ghost Portal
Portal — built-in authentication widget (iframe), embedded in theme:
{{! In footer.hbs or before </body>}}
{{#if @labs.members}}
<script defer src="{{asset "js/portal.min.js"}}"></script>
{{/if}}
Control Portal opening via data-attributes:
<a href="#/portal" data-portal>Sign in</a>
<a href="#/portal/signup" data-portal="signup">Register</a>
<a href="#/portal/account" data-portal="account">My account</a>
Custom Signup Flow
{{! Form with specific Tier and period}}
<a href="#/portal/signup?plan=monthly" data-portal="signup/monthly">
Subscribe for {{price currency="USD" numberFormat="short"}}/month
</a>
Checking Subscriber Status
{{! Personalized content}}
{{#if @member}}
<p>Hi, {{@member.name}}!</p>
{{#if @member.paid}}
<span class="badge">Premium</span>
{{! Show subscription data}}
{{#foreach @member.subscriptions}}
Subscription active until {{date current_period_end format="DD.MM.YYYY"}}
{{/foreach}}
{{/if}}
{{/if}}
Webhook for External Systems
Ghost Admin → Settings → Integrations → Custom Integrations → Add webhook:
Events: member.added, member.updated, member.deleted, member.payment.succeeded.
// Webhook handler (Node.js)
app.post('/ghost/webhook', express.json(), async (req, res) => {
const event = req.body;
if (event.member?.current?.subscribed && !event.member.previous?.subscribed) {
// New subscriber — add to CRM
await addToCrm(event.member.current);
}
if (event.member?.current?.status === 'paid') {
// New paid subscriber — grant Discord access
await grantDiscordAccess(event.member.current.email);
}
res.sendStatus(200);
});
Members setup with one paid tier and basic paywall — 1–2 days. Multiple tiers, custom Portal UI, webhook integrations — 3–5 days.







