# CRM Stack Outside Services Guide

CRM Stack is self-hosted. That means the buyer connects their own outside accounts. Corey does not connect the buyer's CRM to Corey's Stripe, Resend, Cloudflare, or server.

Use this guide when you set up a fresh CRM Stack install.

## The Accounts You Need

- Stripe: takes payments and sends checkout webhooks.
- Resend: sends lead notifications and checkout recovery emails.
- Domain DNS: points the CRM domain to the server.
- Cloudflare Access or another access layer: protects the dashboard and platform admin.
- Server or VPS: runs the app.
- Backup storage: keeps database backups somewhere outside the server.

## Stripe Setup

Stripe has two jobs in CRM Stack:

1. It can sell the CRM Stack license, Launch Setup, and Care Plan if the buyer is reselling the package.
2. It can later support the buyer's own payment flows if they add quote payment links or custom invoice checkout.

The current quote/invoice screen creates CRM records and status tracking. It does not automatically charge the customer's card. If the buyer wants quote payments, they can paste a Stripe Payment Link into their process now or add a custom Stripe invoice/payment-link workflow later.

### Stripe Words In Plain English

- Product: what you sell, such as "CRM Stack License" or "Website Audit."
- Price: the dollar amount attached to a product.
- Checkout Session: the hosted Stripe payment page a customer sees.
- Webhook: Stripe's way of telling CRM Stack that something happened.
- API key: the password your CRM uses to talk to Stripe. Keep it secret.
- Webhook signing secret: a separate secret that proves Stripe sent the webhook.

### Step 1: Create Or Open Your Stripe Account

1. Go to `https://dashboard.stripe.com/`.
2. Create an account or sign in.
3. Finish the business profile, bank account, support email, and tax settings.
4. Stay in test/sandbox mode until you finish a test checkout.

### Step 2: Get The API Key

1. Open Stripe Dashboard.
2. Go to Developers.
3. Open API keys.
4. Copy the secret or restricted server-side key.
5. Put it in the CRM Stack server environment as:

```bash
STRIPE_SECRET_KEY=sk_test_or_live_value_here
```

Use test keys while testing. Use live keys only when you are ready to take real payments.

Never paste a Stripe secret key into GitHub, a public chat, a screenshot, or browser code.

Official reference: `https://docs.stripe.com/keys`

### Step 3: Create Products And Prices

For CRM Stack license sales:

1. Open Stripe Dashboard.
2. Go to Product catalog.
3. Create one product for each sales option.
4. Add a price to each product.
5. Copy each Price ID. It starts with `price_`.
6. Put those Price IDs into the CRM Stack billing setup screen or seed data for the matching plan keys.

For buyer quote payments:

1. Use Stripe Payment Links if you want a no-code payment link.
2. Paste that link into your customer communication or quote notes.
3. If you want one-click quote payment inside CRM Stack, add a custom workflow later that creates Stripe Checkout Sessions or Stripe invoices from quote records.

The important trust point: the buyer's CRM should use the buyer's Stripe account, not Corey's.

### Step 4: Add The Webhook Endpoint

Stripe needs a public URL where it can send payment events.

Use this endpoint:

```text
https://YOUR-CRM-DOMAIN.com/api/billing/webhook
```

In Stripe Dashboard:

1. Go to Developers.
2. Open Webhooks.
3. Add an endpoint.
4. Paste the webhook URL.
5. Select the checkout events CRM Stack needs. At minimum, include checkout completion events.
6. Save the endpoint.
7. Reveal or copy the webhook signing secret.
8. Put it in the CRM Stack server environment as:

```bash
STRIPE_WEBHOOK_SECRET=whsec_value_here
```

Official reference: `https://docs.stripe.com/webhooks`

### Step 5: Test Stripe Before Going Live

1. Keep Stripe in test/sandbox mode.
2. Start CRM Stack.
3. Open the public pricing page.
4. Start a checkout.
5. Use Stripe's test card `4242 4242 4242 4242`.
6. Confirm Stripe sends the customer back to the success page.
7. Confirm Platform Admin shows the buyer record or billing event.
8. Confirm no secret key appears in logs or Git.

Stripe's Checkout docs explain that Checkout redirects customers to the success URL after payment and that webhooks should handle fulfillment. Official reference: `https://docs.stripe.com/checkout/quickstart`

## Resend Setup

Resend sends emails from a verified domain. Do not send from a random Gmail address.

### Step 1: Add The Domain

1. Go to `https://resend.com/`.
2. Sign in.
3. Open Domains.
4. Add the domain or subdomain you want to send from.
5. Resend gives you DNS records.

### Step 2: Add DNS Records

1. Open the DNS provider for the domain.
2. Add the DNS records Resend shows.
3. Wait for DNS to update.
4. Go back to Resend.
5. Click verify.
6. Wait until the domain shows verified.

Resend shows DKIM and SPF records under the domain Records tab. Official reference: `https://resend.com/docs/dashboard/domains/introduction`

### Step 3: Add The Email Environment Variables

Put these in the CRM Stack server environment:

```bash
RESEND_API_KEY=re_value_here
EMAIL_FROM="CRM Stack <noreply@yourdomain.com>"
```

Use a sender address from the verified domain.

### Step 4: Test Email

1. Submit a public form.
2. Confirm the CRM creates the lead.
3. Confirm the notification email arrives.
4. Start a Stripe checkout and abandon it.
5. Confirm the billing admin can send a recovery email.

If the email fails, check the sender domain first.

## Cloudflare Access Setup

Cloudflare Access protects the private dashboard. Public forms, bookings, sites, link pages, and Stripe webhooks must stay public.

### Protect These Private Routes

- `/dashboard*`
- `/platform*`

### Keep These Public Routes Open

- `/forms/*`
- `/api/forms/*`
- `/book/*`
- `/api/book/*`
- `/lp/*`
- `/go/*`
- `/sites/*`
- `/api/billing/*`

If you protect `/api/billing/*`, Stripe cannot reach the webhook. If you protect `/forms/*`, visitors cannot submit leads.

Cloudflare recommends creating an Access application before publishing a self-hosted app through a tunnel. Official reference: `https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-apps/`

## Domain And Server Setup

1. Pick the CRM domain, such as `crm.example.com`.
2. Point DNS to the server or Cloudflare Tunnel.
3. Set this environment variable:

```bash
NEXT_PUBLIC_APP_URL=https://crm.example.com
```

4. Start the app on the server.
5. Open the public domain in a browser.
6. Confirm the public page loads.
7. Open `/dashboard` and confirm the access layer protects it.

## Backup Setup

CRM Stack stores business data in SQLite. Back up the database before real customers use it.

Minimum backup rule:

- One backup on the server is not enough.
- Keep a copy outside the server.
- Test a restore before you trust the backup.

## Final Beginner Checklist

- Stripe account exists.
- Stripe API key is in the server environment.
- Stripe webhook endpoint points to `/api/billing/webhook`.
- Stripe webhook secret is in the server environment.
- Resend domain is verified.
- `RESEND_API_KEY` is in the server environment.
- `EMAIL_FROM` uses the verified domain.
- CRM domain loads in a browser.
- Dashboard routes are protected.
- Public forms and webhooks are not protected.
- A test checkout works.
- A test form creates a lead.
- A test email sends.
- Backups run.

Stop if any item fails. Fix the failed item before taking a real customer payment.
