180 lines
5.7 KiB
Markdown
180 lines
5.7 KiB
Markdown
# SunScope Extra — Stripe Subscription Setup
|
||
## Step-by-step guide to wiring up the £2/month paywall
|
||
|
||
SunScope is a static site with no backend server, so this guide uses
|
||
**Stripe Payment Links** — a no-code/no-server approach where Stripe
|
||
hosts the checkout page for you. You get a URL, you paste it into the
|
||
app. Done.
|
||
|
||
---
|
||
|
||
## STEP 1 — Create a Stripe account
|
||
|
||
1. Go to **https://stripe.com** and sign up (free).
|
||
2. Complete the identity verification (required before going live).
|
||
3. You'll land in the Stripe Dashboard. Make sure you're in **Test mode**
|
||
first (toggle in the top-left) — you can do the whole setup in test
|
||
mode and flip to live when ready.
|
||
|
||
---
|
||
|
||
## STEP 2 — Create the £2/month product
|
||
|
||
1. In the Stripe Dashboard sidebar, go to **Product catalogue → + Add product**.
|
||
2. Fill in:
|
||
- **Name:** `SunScope Extra`
|
||
- **Description:** `Full 14-day forecast, specialist profiles, custom columns`
|
||
- **Pricing model:** `Recurring`
|
||
- **Price:** `£2.00`
|
||
- **Billing period:** `Monthly`
|
||
3. Click **Save product**.
|
||
|
||
---
|
||
|
||
## STEP 3 — Create a Payment Link
|
||
|
||
This is the URL you'll drop into the app — Stripe hosts the whole
|
||
checkout, card capture, and subscription management for you.
|
||
|
||
1. In the product you just created, click **Create payment link**.
|
||
2. Settings to check:
|
||
- **Quantity:** 1 (fixed)
|
||
- **Collect customer email:** Yes (you'll need this to verify subscribers)
|
||
- **Allow promotion codes:** Up to you (handy for early adopters)
|
||
- **After payment:** set the redirect URL to `https://sunscope.net/?pro=1`
|
||
(we'll use this query param to activate Pro — see Step 5)
|
||
3. Click **Create link**.
|
||
4. Copy the URL — it looks like: `https://buy.stripe.com/test_xxxxxxxxxxxxxxxx`
|
||
|
||
---
|
||
|
||
## STEP 4 — Update the upsell card in app.js
|
||
|
||
Open `assets/js/app.js`. Find **line ~913** and **line ~923**. You need
|
||
to change two things:
|
||
|
||
### 4a — Update the pricing line (line ~913)
|
||
|
||
Find this:
|
||
```
|
||
£2 / month · launching soon
|
||
```
|
||
Change it to:
|
||
```
|
||
£2 / month · cancel any time
|
||
```
|
||
|
||
### 4b — Replace the mailto: button with the Stripe link (line ~923)
|
||
|
||
Find this block (starts around line 923):
|
||
```javascript
|
||
href=${`mailto:fraxle@yahoo.co.uk?subject=${encodeURIComponent('SunScope Extra — notify me at launch')}&body=${encodeURIComponent('Hi — please let me know when SunScope Extra launches. (Triggered by ' + dayLong + ')')}`}
|
||
```
|
||
|
||
Replace the entire `href=` value with your Stripe Payment Link:
|
||
```javascript
|
||
href="https://buy.stripe.com/YOUR_ACTUAL_LINK_HERE"
|
||
```
|
||
|
||
Also change the button label on line ~938 from:
|
||
```
|
||
Notify me at launch
|
||
```
|
||
To:
|
||
```
|
||
Subscribe — £2/month
|
||
```
|
||
|
||
And add `target="_blank" rel="noopener noreferrer"` so it opens in a
|
||
new tab (the user stays on the forecast page):
|
||
```javascript
|
||
<a
|
||
href="https://buy.stripe.com/YOUR_ACTUAL_LINK_HERE"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
style=${{ ...existing styles... }}
|
||
>
|
||
Subscribe — £2/month
|
||
</a>
|
||
```
|
||
|
||
---
|
||
|
||
## STEP 5 — Activate Pro after payment (simple URL param method)
|
||
|
||
When Stripe redirects back to `https://sunscope.net/?pro=1` after a
|
||
successful payment, the app needs to detect that and set `isPro = true`.
|
||
|
||
Open `assets/js/app.js` and find the `isPro` state (line ~116):
|
||
```javascript
|
||
const [isPro, setIsPro] = useState(false);
|
||
```
|
||
|
||
Replace that single line with:
|
||
```javascript
|
||
const [isPro, setIsPro] = useState(() => {
|
||
// Check URL param first (just returned from Stripe checkout)
|
||
const params = new URLSearchParams(window.location.search);
|
||
if (params.get('pro') === '1') {
|
||
localStorage.setItem('sunscope_pro', '1');
|
||
// Clean the URL so the param doesn't stay visible
|
||
window.history.replaceState({}, '', window.location.pathname);
|
||
return true;
|
||
}
|
||
// Check localStorage (returning Pro subscriber)
|
||
return localStorage.getItem('sunscope_pro') === '1';
|
||
});
|
||
```
|
||
|
||
That's it. After subscribing, the user lands back on the site as Pro,
|
||
and localStorage remembers them on future visits.
|
||
|
||
> **Important caveat:** This is a trust-based system — it stores Pro
|
||
> status in the user's browser. Anyone who knows the trick can set
|
||
> `localStorage.setItem('sunscope_pro','1')` in their console. For a
|
||
> £2/month product with a small audience this is probably fine. When
|
||
> you want proper enforcement, see Step 6.
|
||
|
||
---
|
||
|
||
## STEP 6 — (Optional) Proper server-side verification
|
||
|
||
When you're ready to properly enforce subscriptions (no console tricks):
|
||
|
||
1. **Stripe Customer Portal** — enable it in the Stripe Dashboard so
|
||
subscribers can manage/cancel their own subscriptions.
|
||
2. **Webhook → backend** — Stripe fires a `checkout.session.completed`
|
||
event when someone subscribes. You'd need a tiny serverless function
|
||
(Cloudflare Worker, Vercel Edge Function, or Netlify Function) to:
|
||
- Receive the webhook
|
||
- Store the subscriber's email + Stripe customer ID in a small DB
|
||
(or even Airtable/Supabase free tier)
|
||
- Issue a signed token (JWT) back to the browser
|
||
3. **Replace localStorage** with checking that JWT against your backend
|
||
on page load.
|
||
|
||
This is a future step — the localStorage approach is perfectly fine for
|
||
launch.
|
||
|
||
---
|
||
|
||
## STEP 7 — Go live
|
||
|
||
When you're happy with testing:
|
||
|
||
1. In Stripe Dashboard, flip the **Test mode** toggle to **Live mode**.
|
||
2. Repeat Steps 2–3 in live mode to get a live Payment Link URL.
|
||
3. Replace the test URL in `app.js` with the live URL.
|
||
4. Deploy.
|
||
|
||
---
|
||
|
||
## Quick reference — files changed
|
||
|
||
| File | What changed |
|
||
|------|-------------|
|
||
| `assets/js/app.js` line ~116 | `isPro` state reads from localStorage + URL param |
|
||
| `assets/js/app.js` line ~913 | Pricing copy: "cancel any time" |
|
||
| `assets/js/app.js` line ~923 | `href` → Stripe Payment Link URL |
|
||
| `assets/js/app.js` line ~938 | Button label → "Subscribe — £2/month" |
|