Skip to main content

Pastor cancels chatbot subscription

Persona​

A pastor on Starter Chat who has decided to cancel — congregation didn't engage, switching tools, or budget cut. They want a clean, self-serve exit. They need to know when service stops, whether their data is safe, and whether they can come back. They should feel respected, not retained.

Entry points​

  1. Billing section — /admin/[token]?tab=settings → Billing → "Cancel Plan" link.
  2. Stripe Customer Portal — "Manage Subscription" link in Stripe emails.
  3. Exit interview email — "You can cancel anytime" link to cancel flow.

Click-through flow​

Steps​

  1. Navigate to Billing section — "Cancel Plan" text link (not a prominent button — cancellation is accessible but not encouraged).

  2. See cancellation terms — Inline note: "Your plan will continue until the end of your current billing period. No refunds for the current period. All your data is safely preserved. You can reactivate anytime." Button: "Manage My Subscription →" (Stripe portal).

  3. Stripe Customer Portal — Subscription details visible. Pastor clicks "Cancel subscription," confirms in Stripe's native modal.

  4. Cancellation confirmation (webhook processing) — customer.subscription.updated with cancel_at_period_end=true enqueued to inbox. Cron processes within ~60 seconds. processCancellation() sends confirmation email (see Acceptance Spec CX-12 for full text).

  5. Dashboard during cancelling period — Amber "Cancelling" banner on every tab. Status badge shows "Cancelling." All tabs remain functional: Training, Requests, Website, Calls. Service runs normally until period-end. premium_churches.status stays 'active'; UI reads cancel_at_period_end from Stripe for banner.

  6. Service ends — Billing cycle ends; Stripe fires customer.subscription.deleted. Cron sets premium_churches.status = 'cancelled'. Dashboard goes read-only: inputs disabled, data visible. Public /chat/[slug] shows fallback: "Hi! [Church Name]'s chatbot is not currently available. Please contact the church at [phone/email]." Service ended email sent with "Come back anytime" reactivation link.

Acceptance spec​

Canonical: knowledge/acceptance/cancelled.md

Key touchpoints:

  • Self-serve via Stripe Customer Portal (CX-1 through CX-4)
  • Full features through period-end (CX-5 through CX-6)
  • Read-only dashboard with export (CX-7)
  • Email sequence: confirmation + service ended + win-back at 7 and 30 days (CX-12 through CX-15)
  • Data preserved indefinitely (no auto-delete)

Success criteria​

  • Cancellation processed immediately by Stripe.
  • Confirmation email within 5 minutes.
  • Chatbot continues working through end of billing period.
  • After period-end, chatbot shows friendly fallback (not 404 or error).
  • Dashboard remains accessible with all data in read-only mode.
  • "Export My Data" button available post-cancellation.
  • Can reactivate via /pricing at any time.

Known failure modes​

  • Webhook loss on cancellation. Pastor gets charged but no "Cancelling" banner. Inbox pattern retries; cron checks cancel_at_period_end on every sync. Source: memory/project_stripe_webhook_inbox.md.

  • Chatbot still responds after period-end. /api/chatbot/stream must check premium_churches.status on every request (no cache). Source: memory/feedback_offline_check_missing.md.

  • Export data fails. If ZIP is corrupted or empty, pastor feels data is lost. Export job must have error handling and P1 alert. Source: memory/feedback_data_export_failure.md.

  • Export includes sensitive data without security gate. Download link should be short-lived (24h expiry). Phone numbers in callback requests are PII — flagged in 2026-04-17 security review. Source: memory/feedback_data_export_privacy.md.

  • Reactivation forces same plan. /pricing on reactivation should allow any plan — no forced pre-selection. Source: memory/feedback_reactivation_choice.md.