# Integrations · setup &amp; activation

> **TL;DR** Every integration is a feature flag in `assets/integrations.js`. The site works without any of them. Activate one at a time.

This document is the operations manual for every third-party system PETVITY can plug into. Each section gives you the same three things:

1. **What it does** — what activating this integration unlocks
2. **Setup** — concrete steps from zero to working
3. **Code change** — the literal lines to edit in `assets/integrations.js`

The status of each integration is also visible at `/integrations.html` (live, reads the config in real time).

---

## Activation order (if you're going from zero to revenue)

For sales:

1. **Shopify** (90 min) — products and checkout live · see [SHOPIFY_SETUP.md](SHOPIFY_SETUP.md)
2. **Stripe Checkout** (60 min) — memberships and course buys
3. **Klaviyo or Resend** (30 min) — transactional + lifecycle email
4. **Cal.com** (15 min) — vet office hours and partner calls

For scale (members &gt; 100):

5. **Supabase** (30 min) — real auth and DB · see [AUTH_SETUP.md](AUTH_SETUP.md)
6. **Sentry** (10 min) — error tracking
7. **Mux / Vimeo** (1 hour) — Quest and Academy video
8. **Stripe Connect** (2 hours) — partner payouts

---

## 1 · Shopify <a id="shopify"></a>

### What it does
Lists real products on `/shop.html`, handles cart, checkout, payment, shipping, taxes, inventory. Every "Buy" button on the shop routes to Shopify Checkout in a new tab.

### Setup
Full step-by-step in [SHOPIFY_SETUP.md](SHOPIFY_SETUP.md). Short version:

1. Create a Shopify store at [shopify.com/free-trial](https://www.shopify.com/free-trial). Use Basic plan (CHF 27/mo).
2. In Shopify admin → **Apps → Develop apps → Create an app** → "PETVITY website".
3. **Configure Storefront API access** → enable `unauthenticated_read_product_listings`, `unauthenticated_read_product_inventory`, `unauthenticated_write_checkouts`.
4. **Install** the app → copy the **Storefront API access token**.
5. Add your products in Shopify admin (or import via CSV from the existing PETVITY catalogue in `products/`).

### Code change
In `assets/integrations.js`:

```js
shopify: {
  enabled: true,                                    // ← was false
  domain: 'petvity.myshopify.com',                  // ← your real store domain
  storefrontAccessToken: 'shpsa_xxxxxxxxxxxxxxxx',  // ← token from step 4
  apiVersion: '2024-10',
}
```

That's it. Reload `/shop.html` — you'll see the "Shopify · live" badge in the hero. Any element with `data-shopify-buy="product-handle"` will now route through Shopify Checkout.

### To make a card use Shopify
Add `data-shopify-buy="petite-bloom"` to its anchor or button. The script in `shop.html` handles the rest.

---

## 2 · Stripe Checkout (memberships &amp; courses) <a id="stripe"></a>

### What it does
Takes payment for Plus and Premium memberships, course one-offs, the Care Partner programme. Subscription management lives in Stripe Customer Portal.

### Setup
1. Create a Stripe account · [stripe.com](https://stripe.com) · Switzerland entity.
2. Create products in Stripe dashboard for each tier:
   - Plus monthly (CHF 49)
   - Plus annual (CHF 490)
   - Premium monthly (CHF 199)
   - Premium annual (CHF 1,990)
   - Pet Longevity Essentials (CHF 490 one-off)
3. Note each product's **Price ID** (`price_...`).
4. Create a Netlify Function at `netlify/functions/create-checkout-session.js` that creates a Stripe Checkout Session server-side (skeleton below).

```js
// netlify/functions/create-checkout-session.js
const Stripe = require('stripe');
exports.handler = async (event) => {
  const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
  const { priceId, mode, successUrl, cancelUrl } = JSON.parse(event.body);
  const session = await stripe.checkout.sessions.create({
    mode: mode || 'subscription',
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: successUrl,
    cancel_url: cancelUrl,
    customer_email: event.headers['x-petvity-email'] || undefined,
  });
  return { statusCode: 200, body: JSON.stringify({ sessionId: session.id }) };
};
```

5. In Netlify → Site → Settings → Environment variables, add `STRIPE_SECRET_KEY = sk_live_...`.

### Code change
```js
stripe: {
  enabled: true,
  publicKey: 'pk_live_xxxxxxxx',
  priceIds: {
    'plus-monthly':    'price_xxx',
    'plus-annual':     'price_xxx',
    'premium-monthly': 'price_xxx',
    'premium-annual':  'price_xxx',
    'essentials-course': 'price_xxx',
  },
  successUrl: '/dashboard.html?ck=ok',
  cancelUrl:  '/membership.html?ck=cancelled',
}
```

Then on `/membership.html`, any "Choose Plus" button can call:

```js
PetvityIntegrations.stripeCheckout({ priceKey: 'plus-monthly' });
```

---

## 3 · Supabase (real auth + DB) <a id="supabase"></a>

### What it does
Migrates from client-side localStorage auth to real Postgres + JWT auth. Cross-device login, password reset emails, OAuth, RLS-secured tables for pets / profiles / subscriptions.

### Setup
Full guide in [AUTH_SETUP.md](AUTH_SETUP.md). Short version:

1. Create project at [supabase.com](https://supabase.com) · choose EU region (Frankfurt / Zürich).
2. Run the SQL in `supabase-schema.sql` (creates `profiles`, `pets`, `subscriptions` tables with RLS).
3. In Supabase → Authentication → Providers, enable Email + (optional) Google + Apple.
4. Copy the project URL and the **anon public key**.

### Code change
In `assets/integrations.js`:

```js
supabase: {
  enabled: true,
  url: 'https://xxxxx.supabase.co',
  anonKey: 'eyJhbGciOiJIUzI1NiIs...',
}
```

Also flip the same flag in `assets/auth.js` (the older Supabase auth module) — they share the same credentials. The localStorage migration helper in `auth.js` will move existing demo accounts on first sign-in.

---

## 4 · Klaviyo (email marketing) <a id="klaviyo"></a>

### What it does
Welcome flow, day-3 / week-1 / month-2 lifecycle, founder cohort sends, Quest reminders, broadcast newsletters. The 5 templates in `email-templates/` are the seed.

### Setup
1. Create account at [klaviyo.com](https://klaviyo.com) · choose pet/wellness vertical.
2. Create lists: **Members**, **Professionals**, **Partners**, **Founders 500**.
3. In **Settings → API Keys**, copy the **Public API Key** (6 chars).
4. Import the HTML email templates from `email-templates/` into Klaviyo as templates.

### Code change
```js
klaviyo: {
  enabled: true,
  publicApiKey: 'AbCdEf',
  lists: {
    members:       'XYZ123',
    professionals: 'XYZ124',
    partners:      'XYZ125',
    founderCohort: 'XYZ126',
  },
}
```

Then any signup form can call:

```js
await PetvityIntegrations.klaviyoSubscribe({
  email: 'user@example.com',
  listKey: 'members',
  properties: { source: 'home-hero', firstName: 'Manuel' },
});
```

When Klaviyo is dormant, the same call captures the email locally in `localStorage` so we don't lose signups during the gap.

---

## 5 · Resend (lighter alternative to Klaviyo) <a id="resend"></a>

### What it does
Transactional email only — order confirmations, password resets, Quest reminders. Simpler &amp; cheaper than Klaviyo if you don't need lifecycle automations yet.

### Setup
1. Create account at [resend.com](https://resend.com).
2. Verify the `petvity.com` domain (DNS DKIM + SPF records).
3. Get an API key.
4. Add `RESEND_API_KEY` to Netlify environment variables.
5. Send via a Netlify Function that imports `resend` and calls `resend.emails.send({ from, to, subject, html })`.

### Code change
```js
resend: {
  enabled: true,
  from: 'PETVITY <hello@petvity.com>',
}
```

---

## 6 · Calendar — Cal.com or Calendly <a id="calendar"></a>

### What it does
Inline booking widgets for vet office hours, partner intake calls, founder calls, Care Partner application calls. Embeds into pages like `/contact.html` or `/sitter.html#apply`.

### Setup (Cal.com — recommended, EU-hosted, open-source)
1. Create account at [cal.com](https://cal.com).
2. Create event types: "Vet 15-min", "Partner intake 30-min", "Founder 20-min", "Care Partner application".
3. Note each event's slug.

### Code change
```js
calendar: {
  enabled: true,
  provider: 'cal',
  links: {
    vetOfficeHours:    'petvity/vet-15min',
    partnerIntake:     'petvity/partner-30min',
    founderCall:       'petvity/founder-20min',
    sitterApplication: 'petvity/sitter-application',
  },
}
```

Embed anywhere with:

```html
<div id="bookingHere"></div>
<script>
  PetvityIntegrations.mountCalendar({ linkKey: 'vetOfficeHours', target: '#bookingHere' });
</script>
```

---

## 7 · Analytics <a id="analytics"></a>

### What it does
Page views, event tracking, funnel analysis. Already loaded site-wide via `assets/analytics.js`.

### Setup options

**Plausible** (privacy-first, EU-hosted, recommended)
1. Sign up at [plausible.io](https://plausible.io).
2. Add domain `petvity.com`.
3. Replace contents of `assets/analytics.js` with the Plausible script tag.

**GA4** (free, more features, less privacy-friendly)
1. Create a GA4 property at analytics.google.com.
2. Copy the gtag tracking script into `analytics.js`.

**PostHog** (product analytics + session replay + feature flags)
1. Sign up at [posthog.com](https://posthog.com) · choose EU.
2. Get your project token.
3. Set `analytics.provider = 'posthog'` in `integrations.js`.

### Code change
```js
analytics: {
  enabled: true,
  provider: 'plausible',     // or 'ga4' / 'posthog'
  domain: 'petvity.com',
}
```

Track events anywhere:
```js
PetvityIntegrations.track('quest_started', { quest: 'senior-dog' });
PetvityIntegrations.track('partner_signup', { brand: 'The Honest Bowl' });
```

---

## 8 · Tally forms <a id="tally"></a>

### What it does
Lightweight form provider (currently used for sitter applications, contact, partner intake). Already in the site — just needs real form IDs filled in.

### Setup
1. Create forms at [tally.so](https://tally.so).
2. Get each form's ID from the share URL.

### Code change
```js
tally: {
  enabled: true,
  forms: {
    sitterApplication: 'wXxxxX',
    contactGeneral:    'wYyyyY',
    partnerIntake:     'wZzzzZ',
  },
}
```

Replace the placeholder iframes on `sitter.html`, `contact.html`, `partner-register.html`.

---

## 9 · Video — Mux / Vimeo / Cloudflare Stream <a id="video"></a>

### What it does
Plays the 30-day Quest videos and the Academy module videos. Cinema-grade, no buffering, custom branding.

### Provider comparison
| Provider | Pros | Cons | Cost |
|---|---|---|---|
| **Vimeo** | Easiest, beautiful player, brand customization | Pricier, less programmatic | $20+/mo |
| **Mux** | Best player, programmatic, analytics | Newer, less plug-and-play | Pay-per-use |
| **Cloudflare Stream** | Cheapest at scale, EU edge | Less customization | $5/1k min |

### Code change
```js
video: {
  enabled: true,
  provider: 'mux',          // 'mux' | 'vimeo' | 'cloudflare-stream'
  vimeo: { accountUrl: 'https://vimeo.com/petvity' },
}
```

Embed anywhere:
```js
PetvityIntegrations.videoEmbed({ id: 'PLAYBACK_ID', target: '#lessonPlayer' });
```

---

## 10 · Sentry (error tracking) <a id="sentry"></a>

### What it does
Surfaces JavaScript errors and performance regressions in production before members report them.

### Setup
1. Sign up at [sentry.io](https://sentry.io).
2. Create a JavaScript project for `petvity-com`.
3. Copy the DSN.
4. Add the Sentry SDK loader to `<head>` of every page (or via integrations.js).

### Code change
```js
sentry: {
  enabled: true,
  dsn: 'https://xxx@oXXX.ingest.sentry.io/XXX',
  environment: 'production',
}
```

---

## 11 · Stripe Connect (partner payouts) <a id="stripe-connect"></a>

### What it does
Pays brand partners their 70% share monthly, distributes 10% lifetime referral commissions, handles KYC and tax documentation. Required to pay partners legally at scale.

### Setup (advanced — 2 hours)
1. In Stripe dashboard → **Connect → Get started**.
2. Choose **Express accounts** (simplest for partners).
3. Add an onboarding link on `/partner-dashboard.html` (step 5 of the activation checklist).
4. Set up webhook handler at `netlify/functions/stripe-webhook.js` for `account.updated`, `transfer.paid`, etc.
5. For each marketplace order, call `stripe.transfers.create()` to send 70% to the partner's connected account.

### Code change
```js
stripeConnect: {
  enabled: true,
  // Implementation lives in Netlify Functions; this flag toggles the UI.
}
```

---

## 12 · Cloudflare Turnstile (bot protection) <a id="turnstile"></a>

### What it does
Free invisible captcha for `register.html`, `partner-register.html`, `contact.html`. Stops account-creation spam.

### Setup
1. Sign in to Cloudflare → Turnstile.
2. Add site `petvity.com`.
3. Copy the **Site key**.

### Code change
```js
turnstile: {
  enabled: true,
  siteKey: '0x4AAAAAAAxxxxxxxxxxxxxx',
}
```

Then in any form:

```html
<div class="cf-turnstile" data-sitekey="{{siteKey}}"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
```

---

## What lives where

```
/assets/integrations.js     ← config + unified API
/assets/petvity-auth.js     ← client-side auth (talks to integrations later)
/assets/auth.js             ← Supabase drop-in (older module, will merge)
/assets/analytics.js        ← analytics shim
/integrations.html          ← live status dashboard
/SHOPIFY_SETUP.md           ← Shopify deep-dive
/AUTH_SETUP.md              ← Supabase deep-dive
/INTEGRATIONS.md            ← this file
/netlify/functions/         ← server-side bits (Stripe, webhooks)
/netlify.toml               ← redirects + headers + env config
/email-templates/           ← welcome / day-3 / week-1 templates ready for Klaviyo or Resend
```

---

## Cost estimate · all-in monthly

For a fully activated stack at 200 paying members:

| Integration | Cost |
|---|---|
| Shopify Basic | CHF 27 |
| Stripe | 2.9% + 0.30 per txn |
| Supabase Pro | $25 |
| Klaviyo | ~$30 (free tier covers up to 250 contacts) |
| Cal.com | Free (self-host) or $12/mo |
| Plausible | $9/mo |
| Sentry | Free tier covers most |
| Mux | ~$20–50/mo (depends on viewing minutes) |
| Cloudflare Turnstile | Free |
| **Total fixed** | **~CHF 110–150/mo** |
| Stripe variable | 2.9% of revenue |

For ~CHF 150/mo total cost you have a fully functional, scalable, EU-compliant longevity platform. Activate from this list as the business grows — none is required to launch.
