Skip to main content

Knowledge > Runbooks > Customer Ops > Onboard New Church

Onboard a New Church After Checkout

Verify that automated onboarding completed correctly after a church finishes checkout. The webhook handles most of this automatically — this runbook covers the verification steps and manual fallback when automation fails.

Prerequisites

Automated Flow (what should happen automatically)

  1. Church completes Stripe checkout
  2. Stripe fires checkout.session.completed webhook to [domain]/api/stripe/webhook
  3. Webhook handler creates a premium_churches row with plan, tier, and stripe_subscription_id
  4. Welcome email sent via Resend with magic link to admin dashboard
  5. Church added as subscriber in MailerLite

Verification Steps

  1. Confirm the Stripe webhook fired

    stripe events list --limit 10

    Look for a checkout.session.completed event with the church's email. Confirm status: delivered (not failed).

  2. Verify the premium_churches row was created

    SELECT pc.*, c.name, c.email
    FROM premium_churches pc
    JOIN churches c ON c.id = pc.church_id
    ORDER BY pc.created_at DESC
    LIMIT 5;

    Confirm: correct plan (starter/pro/suite), correct tier (chat/voice/both), and a valid stripe_subscription_id starting with sub_.

  3. Verify the admin session / magic link was sent Check church_admin_sessions for a new row for this church:

    SELECT * FROM church_admin_sessions
    WHERE church_id = '[church-uuid]'
    ORDER BY created_at DESC LIMIT 3;

    Also check Resend logs (via the Resend dashboard) for a sent email to the church's address.

  4. Verify MailerLite subscriber was added Use the MailerLite API or check via churchwiseai-web MailerLite integration logs.

  5. Test admin dashboard access Visit https://churchwiseai.com/admin/[their-token] (token is in church_admin_sessions.token). Confirm the dashboard loads with the church name in the header and correct plan shown.

Manual Fallback

If any automated step failed:

Re-create the premium_churches row

INSERT INTO premium_churches (church_id, plan, tier, stripe_subscription_id, created_at)
VALUES (
'[church-uuid]',
'pro', -- starter | pro | suite | pro_website
'chat', -- chat | voice | both
'sub_xxxxxxxxxxxx',
now()
);

Get church_id from churches table by email or name. Get stripe_subscription_id from stripe subscriptions list --customer [cus_id].

Call the magic link API:

curl -X POST https://churchwiseai.com/api/onboard/resend-link \
-H "Content-Type: application/json" \
-d '{"church_id": "[church-uuid]", "email": "[church-email]"}'

Or insert into church_admin_sessions directly:

INSERT INTO church_admin_sessions (church_id, token, created_at, expires_at)
VALUES (
'[church-uuid]',
gen_random_uuid()::text, -- use this as the token
now(),
now() + interval '30 days'
);

Then send the magic link URL: https://churchwiseai.com/admin/[token]

Verification

After manual steps:

  • Church can log in at their admin dashboard URL
  • Plan and tier display correctly in the dashboard header
  • If voice plan: verify church_voice_agents row exists (or create it — see add-voice-number.md)

See Also

  • cancel-subscription.md — if they need to cancel
  • add-voice-number.md — if they purchased a voice plan
  • C:\dev\churchwiseai-web\src\app\api\stripe\webhook\route.ts — webhook handler code
  • C:\dev\PRICING.md — plan/tier definitions and Stripe price IDs