docs(deploy): the installer's Stripe steps match what phase 5 actually needs

It still named two webhook events; the application handles six, and the four
new ones are the billing cycle itself — renewals, failed payments, status
changes and endings. It also said nothing about stripe:sync-catalogue, without
which Stripe has no prices and nothing can be sold at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
feat/portal-design
nexxo 2026-07-26 14:46:25 +02:00
parent 8c3a79e258
commit 4f3e11ae5e
2 changed files with 41 additions and 7 deletions

View File

@ -330,10 +330,17 @@ Still to do, in this order:
1. Point the DNS records at ${PUBLIC_IP} and put TLS in front (Zoraxy, 1. Point the DNS records at ${PUBLIC_IP} and put TLS in front (Zoraxy,
Caddy or nginx). ${ADMIN_DOMAIN} must NOT be publicly resolvable. Caddy or nginx). ${ADMIN_DOMAIN} must NOT be publicly resolvable.
2. Enter STRIPE_WEBHOOK_SECRET in $INSTALL_DIR/.env — Stripe dashboard → 2. Enter STRIPE_SECRET and STRIPE_WEBHOOK_SECRET in $INSTALL_DIR/.env —
Developers → Webhooks → https://${APP_DOMAIN}/webhooks/stripe, events Stripe dashboard → Developers → Webhooks →
checkout.session.completed and checkout.session.async_payment_succeeded. https://${APP_DOMAIN}/webhooks/stripe, subscribing all six events:
3. Sign in and switch the website to hidden under Settings until you are checkout.session.completed checkout.session.async_payment_succeeded
invoice.paid invoice.payment_failed
customer.subscription.updated customer.subscription.deleted
3. Mirror the plan catalogue into Stripe — nothing can be sold until it knows
what it is billing for. Look first; a Stripe Price cannot be deleted:
docker compose exec app php artisan stripe:sync-catalogue --dry-run
docker compose exec app php artisan stripe:sync-catalogue
4. Sign in and switch the website to hidden under Settings until you are
ready to be found (Settings → Website visibility). ready to be found (Settings → Website visibility).
Updating later — as ${APP_USER}, not as root: Updating later — as ${APP_USER}, not as root:

View File

@ -65,9 +65,36 @@ kept failing until the worker was restarted.
the hostnames in `ADMIN_HOSTS` and 404s everywhere else, but keeping it out the hostnames in `ADMIN_HOSTS` and 404s everywhere else, but keeping it out
of public DNS is the layer above that. of public DNS is the layer above that.
- **`STRIPE_WEBHOOK_SECRET`.** Stripe dashboard → Developers → Webhooks → - **`STRIPE_WEBHOOK_SECRET`.** Stripe dashboard → Developers → Webhooks →
`https://<app-domain>/webhooks/stripe`, events `checkout.session.completed` `https://<app-domain>/webhooks/stripe`. The secret starts with `whsec_` and
and `checkout.session.async_payment_succeeded`. The secret starts with differs between test and live mode. Subscribe all six events the application
`whsec_` and differs between test and live mode. handles — the first two open a contract, the rest are the billing cycle,
which is Stripe's:
```
checkout.session.completed
checkout.session.async_payment_succeeded
invoice.paid
invoice.payment_failed
customer.subscription.updated
customer.subscription.deleted
```
- **The Stripe catalogue.** Nothing can be sold until Stripe knows what it is
billing for:
```
docker compose exec app php artisan stripe:sync-catalogue --dry-run # look first
docker compose exec app php artisan stripe:sync-catalogue
```
Run it again after publishing any new plan version. It is idempotent, and it
has to be: a Stripe Price cannot be edited or deleted, so a duplicate is
permanent. `--dry-run` lists exactly what would be created.
- **A look at the catalogue itself.** `php artisan plans:check` reports
overlapping availability windows, plans on sale with no live version, and
missing prices. Worth running after any plan change — all of it is computed
when read, so a mistake announces itself at a customer's checkout otherwise.
- **Backups.** At minimum the MariaDB volume and `/etc/wireguard` in the - **Backups.** At minimum the MariaDB volume and `/etc/wireguard` in the
`wireguard` volume — losing the hub key means re-peering every host. `wireguard` volume — losing the hub key means re-peering every host.