Ajijic Membership Platform Decision
Private. Enter the hub password to continue.
That's not right. Try again.
Ajijic Membership Platform Decision
The recommendation, up top
Go with Option C: Outseta ($39/mo Founder plan + 2% fee), dropped into the existing ajijic.org static site. It handles the $399/yr membership, the $297 one-time Digital Discovery, and future concierge tiers in one dashboard, with CRM and email built in, and it launches in 1-2 sessions with no content migration. Fallback if you want zero monthly cost: Option B (Stripe + our own Worker), slower and we own auth security forever. Ghost (Option A) is out: it forces member content into a second CMS on a second subdomain.
What's already cleared: the legal gate (attorney sign-off + Jalisco license, 2026-07-12). What still gates launch: the site's preview wall, membership can't go live until you call the public launch.
Companion: Ajijic Member Content Map (exactly what $399/yr buys).
Created: 2026-07-12 by Charlie (PLAN-membership-payments-prep) Status: DECISION DOC for Annette. One decision converts to execution from the runbooks below. Companion: Ajijic Member Content Map (what the membership gates)
Gates (read first)
- Legal gate: CLEARED 2026-07-12. Annette confirmed the attorney cleared the ToS and Privacy Policy, and her Jalisco license is reactivated. The
legal/docs can be promoted from DRAFT. - Public-launch gate: STILL OPEN. The site is soft-launch gated (
static-site/_worker.jspreview cookie). Membership cannot go live behind a preview wall. Sequence: Annette calls public launch (remove preview gate, redeploy) → then membership goes live. This is the only remaining sequence gate.
The decision: three ways to run a $399/yr membership
| Option A: Ghost(Pro) | Option B: Stripe + our own Worker gating | Option C: Outseta drop-in | |
|---|---|---|---|
| Monthly cost | $29/mo Publisher plan, billed annually ($35 monthly). Starter ($15) no longer allows paid subscriptions. Ghost takes 0% of member revenue | $0 platform. Stripe fees only (2.9% + $0.30) | $39/mo Founder plan + 2% transaction fee, plus Stripe fees |
| Cost on $399 sale | ~$11.87 Stripe only | ~$11.87 Stripe only | ~$19.85 (Stripe + $7.98 Outseta) |
| What it is | Hosted membership CMS at members.ajijic.org; content moves INTO Ghost | Stripe Checkout links + a Cloudflare Worker that checks a session cookie against D1 (extends the existing worker/index.js stack) | Auth, payments, CRM, and email widgets dropped into the existing static HTML pages |
| Annette effort to operate | Low (Ghost dashboard) | Medium (Charlie maintains; she has no dashboard beyond Stripe) | Low (Outseta dashboard covers members, billing, email, CRM) |
| Time to launch | 2-3 sessions (content migration into Ghost is the long pole) | 3-5 sessions (build + security review of auth) | 1-2 sessions (no content migration) |
| Migration risk | Two stacks forever: static site + Ghost. Member content maintained in a second CMS | None (one stack) but we own auth security forever | Low; member data exportable, content never leaves our repo |
| $297 Digital Discovery fit | Ghost tiers are subscriptions; one-time products are awkward (workaround: Stripe Payment Link on the side, so two systems anyway) | Native: just another Checkout link | Native: Outseta supports one-time charges alongside subscriptions |
| Content gating strength | Strong (server-side) | Strong (server-side, Worker-enforced) | Widget gating is client-side by default (hide-in-browser); needs the hybrid hardening in the runbook to be real |
| Renewal dunning | Built in | We build it (Stripe Smart Retries + Resend emails) | Built in |
Pricing sources (verified 2026-07-12): Ghost(Pro) pricing and Ghost forum pricing announcement; Memberstack pricing (Basic $25/mo + 4% fee, Professional $39/mo + 2%, considered and rejected: 4% fee at entry tier and Webflow-first tooling); Outseta pricing (Founder $39/mo + 2%, Start-up $79/mo + 1%); Ghost custom-domain help.
Recommendation: Option C (Outseta), with Option B as the zero-monthly-cost fallback
The May "Ghost $29/mo" recommendation predates the site we actually built. We now have 50+ finished static pages on ajijic.org with locked branding, a live D1 + Resend worker, and a working funnel. Ghost's whole value is its CMS, which forces the member content into a second system on a second subdomain (members.ajijic.org), a permanent two-stack tax and a domain seam at the exact moment of purchase. Ghost also handles the $297 one-time product poorly. Outseta drops into the pages we already have, handles the $399/yr, the $297 one-time, and the future monthly concierge tiers in one dashboard, and throws in CRM and email (which trims the planned ConvertKit/Beehiiv spend from product-lineup-v1). The 2% fee costs about $8 per membership sale, roughly one sale per month pays the difference vs Ghost. The one real weakness, client-side gating, is fixed by the hybrid Worker check in Runbook C. Choose Option B only if zero monthly cost matters more than launch speed and than not owning an auth security surface.
Stripe object model (applies to A and B; Outseta creates equivalents in its own dashboard on top of Stripe)
Five products, five prices, USD:
| # | Product | Price object | Type |
|---|---|---|---|
| 1 | Ajijic Guide Membership | $399/year | Recurring, annual |
| 2 | Digital Discovery Package | $297 | One-time |
| 3 | Concierge Light | $150/month | Recurring, monthly (HOLD) |
| 4 | Concierge Regular | $250/month | Recurring, monthly (HOLD) |
| 5 | Concierge Absentee/Snowbird | $400/month | Recurring, monthly (HOLD) |
HOLD note: strategy/monthly-concierge-tiers.md flags Regular and Absentee as margin-negative at $30/task Ava economics (-$10 and -$60 per client per month). Launch Membership + Digital Discovery first; do not open concierge checkout until the Ava pricing review closes.
Rules that apply to every option:
- Sell Membership and Digital Discovery as separate checkout links; do not mix one-time and recurring in a single Checkout session (tax and receipt complications).
- Test mode before live mode, always: create products in TEST, wire the webhook/receiver, fire Stripe CLI test events, complete a full test purchase and a test renewal-failure, and only then create the live products.
- No keys in git, ever. Secret keys live only in
wrangler secret put(Worker) or the platform's dashboard. Publishable keys (pk_) are the only class allowed in page HTML..gitignoreany.env. - Dunning or year-2 revenue halves silently: enable Stripe Smart Retries + a reminder email 7 days before renewal and on each failed charge (Resend for B, built-in for A and C).
Indexing and AI-crawler note
robots.txt and llms.txt were opened to SEO + AI crawlers on 2026-07-11, which is right for the free tier but wrong for member content. Whichever option wins: member-only URLs must be excluded from sitemap.xml, carry <meta name="robots" content="noindex">, and, decisively, be enforced server-side (Ghost and the Worker do this natively; Outseta needs the hybrid step in Runbook C). Client-side hiding alone means every AI crawler ingests the paid content and answers questions from it for free. Free teaser pages stay indexed on purpose; they are the funnel.
Runbook A: Ghost(Pro) at members.ajijic.org
- Gate check: Legal CLEARED 2026-07-12 (attorney sign-off received; Jalisco license reactivated). Confirm public launch has happened (preview gate removed from
static-site/_worker.jsand redeployed). If the site is still gated, STOP. - ANNETTE + card required: Create Ghost(Pro) account, Publisher plan ($29/mo billed annually). Starter does not allow paid subscriptions.
- ANNETTE: Connect her Stripe account to Ghost (Ghost admin → Settings → Membership). If she has no Stripe account: ANNETTE + card/bank required to create one at stripe.com (identity + bank details, Charlie must not enter these).
- DNS: in Cloudflare, add
CNAME members -> [target Ghost provides in admin], DNS-only (grey cloud) per Ghost's Cloudflare guidance. Never touch the apex record: ajijic.org's apex is Cloudflare Pages; pointing it at Ghost takes the site down. The membership lives at members.ajijic.org and visitors cross domains at signup (accept this UX seam or pick another option). - Activate the custom domain in Ghost admin → Domain settings; wait for SSL.
- In Ghost TEST/Stripe test mode: create the Membership tier at $399/yr. Digital Discovery: create a separate Stripe Payment Link ($297 one-time) outside Ghost and link it from the site (Ghost does not do one-time products well).
- Migrate member content per the Member Content Map: 10 book chapters + 3 member relocation docs into Ghost posts tagged members-only. Apply brand fonts/colors to the Ghost theme (bright, light, no dark backgrounds, no sticky elements).
- Set Ghost posts to members-only visibility; verify logged-out access is refused server-side; confirm noindex on member posts; remove member URLs from any sitemap we control.
- Test-mode checklist: test signup, test $399 charge, member login, gated page access, cancel flow, failed-renewal email. All green before step 10.
- ANNETTE: flip Stripe to live mode in Ghost; do one real $399 purchase herself and refund it.
- Wire the static site: "Join" CTAs point to members.ajijic.org/#/portal/signup; add member callout blocks to the 13 category pages.
- Enable dunning: Ghost handles retries; verify the renewal-reminder email is on.
Runbook B: Stripe Checkout + Cloudflare Worker gating (own stack)
- Gate check: Legal CLEARED 2026-07-12 (attorney sign-off received; Jalisco license reactivated). Confirm public launch has happened (preview gate removed and redeployed). If still gated, STOP.
- ANNETTE + card/bank required: Create the Stripe account (identity + bank onboarding). Charlie never enters financial credentials.
- In Stripe TEST mode (Charlie, via dashboard access Annette grants or pair-session): create the 5 products/prices from the object model. Create Payment Links for Membership ($399/yr) and Digital Discovery ($297). Concierge products created but links NOT published (margin HOLD).
- Build the webhook receiver FIRST, before any checkout goes live: extend
worker/index.js(or a sibling worker on the same account/D1) withPOST /api/stripe-webhookhandlingcheckout.session.completed,customer.subscription.updated,customer.subscription.deleted,invoice.payment_failed. Verify signatures with the webhook signing secret. Write member status to a new D1memberstable (email, stripe_customer_id, status, current_period_end). - Secrets:
wrangler secret put STRIPE_SECRET_KEYandSTRIPE_WEBHOOK_SECRET. Nothing key-shaped in git; publishable key only in HTML if Checkout is embedded (Payment Links need none). - Build auth: magic-link email sessions at minimum.
POST /api/member-login→ look up active member in D1 → Resend a signed one-time link → set an HttpOnly signed session cookie (30 days). This is Charlie-built auth and a real security surface: HMAC-signed tokens, expiry, rate limiting on the login endpoint, constant-time comparison. Adversarial review (Gemini + Codex + Grok) REQUIRED before live. - Gate the member paths: extend
static-site/_worker.jsso/members/*(chapters + member docs per the content map) requires a valid session cookie, else redirect to the join page. Server-side enforcement, plus noindex meta on member pages, and exclude/members/*from sitemap.xml. - Test-mode checklist: Stripe CLI test events against the webhook; full test purchase; magic-link login; gated page access logged-in and logged-out; subscription-cancel removes access at period end;
invoice.payment_failedtriggers the Resend dunning email. All green before step 9. - Dunning: enable Stripe Smart Retries in dashboard settings; Resend reminder 7 days pre-renewal (cron trigger on the worker) and on each failed charge.
- ANNETTE: switch keys to live mode (
wrangler secret putwith live keys), publish live Payment Links, make one real purchase and refund it. - Wire the static site CTAs to the live Payment Links; add member callouts to category pages.
Runbook C: Outseta on the existing static site (RECOMMENDED)
- Gate check: Legal CLEARED 2026-07-12 (attorney sign-off received; Jalisco license reactivated). Confirm public launch has happened (preview gate removed and redeployed). If still gated, STOP.
- ANNETTE + card required: Create Outseta account, Founder plan ($39/mo, 2% transaction fee). During onboarding, ANNETTE + bank required: connect/create the Stripe account (Outseta bills through Stripe).
- In Outseta (test mode): create plans mirroring the object model: Membership $399/yr (recurring annual), Digital Discovery $297 (one-time), the 3 concierge plans created but hidden (margin HOLD).
- Drop the Outseta script + signup/login embeds into the static site: join page gets the $399 signup widget, a new login link in the nav (not sticky), and an account page. Keep all styling on-brand: bright, light, magenta CTAs only, no dark backgrounds, no sticky elements.
- Publish member content at
/members/*paths (chapters + the 3 member relocation docs per the Member Content Map) using the existing page template. - Hardening (required, do not skip): Outseta's default content protection is client-side. Add server-side enforcement in
static-site/_worker.js: on/members/*, validate the Outseta JWT/access token (Outseta issues one at login) before serving; invalid or absent → redirect to join. Also add noindex meta to all/members/*pages and exclude them from sitemap.xml. Without this step the open robots.txt/llms.txt policy hands the paid content to every AI crawler. - Configure Outseta email: welcome email on signup, renewal reminder, failed-payment dunning sequence (built in; turn them on and put them in Annette's voice, contractions, no em-dashes).
- Test-mode checklist: test signup + $399 test charge, login, gated page served with valid token, gated page refused without token (curl, not browser), cancel flow, failed-renewal email fires. All green before step 9.
- ANNETTE: flip Outseta/Stripe to live mode; make one real $399 purchase herself and refund it.
- Wire funnel: homepage and category-page CTAs to the join page; Digital Discovery checkout link on its sales page; import existing D1 subscriber emails into Outseta CRM (export from D1, import CSV; no credentials in git).
- Register the renewal/dunning emails in
~/memory/ROUTINES.md(what/when/where/how-to-disable) since they are recurring automation.
Legal footnote
Governing law is decided (Jalisco, Guadalajara arbitration, USD pricing) and the attorney packet covered the PROFECO / US-Canada consumer angle. Attorney review is complete as of 2026-07-12. Nothing here re-opens governing law.
🔒 Private · annettethompson.com/hub/ajijic-membership-platform-decision