Newsletter and Paywall Strategy
Last updated: 2026-02-09
Purpose
Define a practical path from fully public blog content to a member/premium access model without replatforming away from Wagtail.
Current decision
- Keep Wagtail/Django as the core platform.
- Use a hybrid model:
- Newsletter provider for free/member tier.
- Patreon-first for premium tier.
- Keep architecture Stripe-ready for a later migration if conversion control becomes the priority.
Why this approach
- Faster launch and validation of paid demand.
- Lower initial billing/compliance implementation cost.
- Preserves future flexibility by isolating entitlement logic behind a provider abstraction.
Access model
public: full access for everyone.member: full access for active newsletter members.premium: full access for active Patreon/Stripe premium users.- Non-entitled users: preview + CTA.
Planned interfaces
POST /newsletter/subscribePOST /webhooks/newsletter/<provider>GET /members/loginPOST /webhooks/patreonPOST /webhooks/stripe(future)GET /blog/<slug>/returns full or preview content based on entitlement
Planned data model additions
MemberProfileemailnewsletter_status(pending|active|unsubscribed|bounced)paywall_provider(none|patreon|stripe)entitlement_tier(free|member|premium)- provider IDs + audit timestamps
BlogPageaccess_tier(public|member|premium)preview_mode(none|excerpt|first_n_blocks)is_paid_override
Rollout phases
- Foundation
-
Add entitlement contract and page-level access metadata.
-
Patreon-first premium
- Add Patreon webhook/OAuth entitlement sync.
-
Add premium CTA and guard logic.
-
Newsletter member sync
- Integrate provider (default recommendation: Buttondown).
-
Add subscribe and webhook reconciliation flows.
-
Stripe expansion (optional)
- Implement Stripe billing lifecycle and webhooks without rewriting access control logic.
Test scenarios
- Anonymous user receives previews for member/premium content.
- Member can access member content but not premium content.
- Premium user can access premium content.
- Access revokes correctly on unsubscribe/cancel events.
- Webhook processing is idempotent.
- Section-level and post-level override precedence is deterministic.
Open implementation notes
- This document is a strategy reference; endpoints/models above are planned, not fully implemented yet.
- Keep final contracts in sync with code once implementation starts.
Reference links
- Buttondown API: https://docs.buttondown.com/api-introduction
- Patreon API docs: https://docs.patreon.com/
- Stripe billing docs: https://docs.stripe.com/billing
- Wagtail privacy docs: https://docs.wagtail.org/en/stable/topics/privacy.html