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
parent
8c3a79e258
commit
4f3e11ae5e
|
|
@ -330,10 +330,17 @@ Still to do, in this order:
|
|||
|
||||
1. Point the DNS records at ${PUBLIC_IP} and put TLS in front (Zoraxy,
|
||||
Caddy or nginx). ${ADMIN_DOMAIN} must NOT be publicly resolvable.
|
||||
2. Enter STRIPE_WEBHOOK_SECRET in $INSTALL_DIR/.env — Stripe dashboard →
|
||||
Developers → Webhooks → https://${APP_DOMAIN}/webhooks/stripe, events
|
||||
checkout.session.completed and checkout.session.async_payment_succeeded.
|
||||
3. Sign in and switch the website to hidden under Settings until you are
|
||||
2. Enter STRIPE_SECRET and STRIPE_WEBHOOK_SECRET in $INSTALL_DIR/.env —
|
||||
Stripe dashboard → Developers → Webhooks →
|
||||
https://${APP_DOMAIN}/webhooks/stripe, subscribing all six events:
|
||||
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).
|
||||
|
||||
Updating later — as ${APP_USER}, not as root:
|
||||
|
|
|
|||
|
|
@ -65,9 +65,36 @@ kept failing until the worker was restarted.
|
|||
the hostnames in `ADMIN_HOSTS` and 404s everywhere else, but keeping it out
|
||||
of public DNS is the layer above that.
|
||||
- **`STRIPE_WEBHOOK_SECRET`.** Stripe dashboard → Developers → Webhooks →
|
||||
`https://<app-domain>/webhooks/stripe`, events `checkout.session.completed`
|
||||
and `checkout.session.async_payment_succeeded`. The secret starts with
|
||||
`whsec_` and differs between test and live mode.
|
||||
`https://<app-domain>/webhooks/stripe`. The secret starts with `whsec_` and
|
||||
differs between test and live mode. Subscribe all six events the application
|
||||
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
|
||||
`wireguard` volume — losing the hub key means re-peering every host.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue