Billing: fatture manuali, profilo obbligatorio e piani Stripe mensile/annuale.

Rimuove link al portale Stripe in area cliente, aggiunge flusso admin per PDF
fattura e email, blocca checkout senza dati di fatturazione, allinea prezzi
a €4,90/€39,90 e €9,90/€69,90, locale italiano e documentazione deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 17:10:12 +02:00
parent 148402a97c
commit a5e781729c
78 changed files with 2457 additions and 424 deletions

View File

@@ -29,12 +29,14 @@ Esigenze custom: contatto `info@matchlive.it`.
## Stripe
```bash
STRIPE_PREMIUM_LIGHT_PRICE_ID=price_...
STRIPE_PREMIUM_FULL_PRICE_ID=price_...
STRIPE_PREMIUM_LIGHT_MONTHLY_PRICE_ID=price_...
STRIPE_PREMIUM_LIGHT_YEARLY_PRICE_ID=price_...
STRIPE_PREMIUM_FULL_MONTHLY_PRICE_ID=price_...
STRIPE_PREMIUM_FULL_YEARLY_PRICE_ID=price_...
STRIPE_WEBHOOK_SECRET=whsec_...
```
Checkout (PCI-safe, redirect Stripe Hosted): `GET /clubs/:id/checkout?plan=premium_light|premium_full`
Checkout: `GET /clubs/:id/checkout?plan=premium_light|premium_full&interval=monthly|yearly`
**Sicurezza pagamenti:** non inviare mai `card[number]`, CVC o scadenza all'API Stripe dal backend.
Usare solo Checkout/Customer Portal. I test locali vanno fatti con carta `4242…` **sulla pagina Stripe**, non con `PaymentMethod.create` in `rails runner`.

87
docs/STRIPE_PRODUCTION.md Normal file
View File

@@ -0,0 +1,87 @@
# Stripe in produzione — guida rapida
## 1. Stripe Dashboard (modalità Test per prove, poi Live)
### Prodotti e prezzi
Crea **2 prodotti** in Stripe, ciascuno con **2 prezzi ricorrenti**:
| Piano app | Prodotto Stripe (Dashboard) | Mensile | Annuale | Variabile `.env` |
|-----------|------------------------------|---------|---------|------------------|
| Premium Light | **Match Live TV** | €4,90 | €39,90 | `STRIPE_PREMIUM_LIGHT_MONTHLY_PRICE_ID` / `..._YEARLY_...` |
| Premium Full | **Match Live TV PRO** | €9,90 | €69,90 | `STRIPE_PREMIUM_FULL_MONTHLY_PRICE_ID` / `..._YEARLY_...` |
In Stripe apri ogni prezzo e copia l**ID prezzo** (`price_...`), non lID prodotto.
In Dashboard: Prodotto → **Aggiungi prezzo** (non serve un prodotto per ogni intervallo).
### Webhook (obbligatorio)
**Developers → Webhooks → Aggiungi endpoint**
| Campo | Valore |
|--------|--------|
| URL | `https://www.matchlivetv.it/webhooks/stripe` |
| Eventi | `checkout.session.completed`, `customer.subscription.created`, `customer.subscription.updated`, `customer.subscription.deleted`, `invoice.paid`, `invoice.payment_failed` |
Copia il **Signing secret** (`whsec_...`) — **non** usare il secret di `stripe listen` (solo per locale).
### Chiavi API
- Test: `sk_test_...` + price test
- Live: `sk_live_...` + price live (prodotti creati in modalità Live)
## 2. Server (`/opt/matchlivetv/infra/.env`)
> **Non usare** `~/matchlivetv/infra/.env` — è una copia vecchia (bootstrap).
> Docker in produzione legge solo **`/opt/matchlivetv/infra/.env`**.
> Per aggiungere chiavi mancanti dal template: `./scripts/merge_production_env.sh` con `REMOTE=1`.
```bash
STRIPE_SECRET_KEY=sk_test_... # o sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_... # dal webhook Dashboard (URL produzione)
STRIPE_PREMIUM_LIGHT_MONTHLY_PRICE_ID=price_...
STRIPE_PREMIUM_LIGHT_YEARLY_PRICE_ID=price_...
STRIPE_PREMIUM_FULL_MONTHLY_PRICE_ID=price_...
STRIPE_PREMIUM_FULL_YEARLY_PRICE_ID=price_...
```
Da PC (senza incollare chiavi in chat):
```bash
./scripts/setup_stripe_production.sh
# oppure, se il webhook è nuovo:
./scripts/setup_stripe_production.sh --webhook-secret whsec_...
```
## 3. Test end-to-end
```bash
# Test scelta mensile/annuale (Docker avviato)
chmod +x scripts/test_billing_intervals.sh
./scripts/test_billing_intervals.sh
# Smoke HTTP su produzione
BASE_URL=https://www.matchlivetv.it ./scripts/test_stripe_e2e.sh
# Test locale completo (Docker avviato)
./scripts/test_billing_flow.sh
```
Checkout: `/clubs/:id/checkout?plan=premium_light&interval=yearly` oppure `interval=monthly`
### Test manuale browser
1. Login titolare società → **Abbonamento**
2. **Completa dati di fatturazione** (P.IVA/CF, SDI o PEC, indirizzo)
3. **Attiva Premium Light** → pagina `checkout.stripe.com`
4. Carta test `4242 4242 4242 4242` (solo con `sk_test_`)
5. Ritorno su `/clubs/.../billing?checkout=success`
6. Verifica in Stripe → Webhooks: risposta **200** su `/webhooks/stripe`
## 4. PCI
- Mai `PaymentMethod.create` con `card[number]` sul server
- Prima attivazione: solo **Stripe Checkout**
- Cambio piano (già abbonato): **Subscription.update** Stripe (carta già salvata da Checkout)
## 5. Passaggio a Live
1. Crea prodotti/prezzi in modalità **Live**
2. Nuovo webhook endpoint (stesso URL, modalità Live) → nuovo `whsec_`
3. Sostituisci `sk_live_` e price live in `.env` produzione
4. `./scripts/setup_stripe_production.sh` e ri-test con carta reale