CluPilotCloud/app/Livewire
nexxo 32a8bd9a88 Refuse the sale instead of reaching Stripe without a key
Task 5: Billing::purchase() now checks SecretVault for a stripe.secret before
touching anything else — no customer, no plan lookup, no Order row — and the
customer reads a plain sentence instead of a 500 page. HttpStripeClient's own
secret() throws the same StripeNotConfigured exception rather than sending a
request with an empty bearer token and letting Stripe's 401 stand in for the
real cause.

isConfigured() was fixed alongside it: it used to call secret() too, which
would have turned every "is Stripe set up?" check (the checkout controller,
the catalogue sync commands) into an uncaught exception the moment a key went
missing — the opposite of what this task is for. It now reads the vault
directly.

The new guard is unconditional, including for the cart-only purchase types
(storage, addon, plan changes) that never call Stripe themselves — a cart
order nobody can ever pay for is pointless to create. That broke every
existing Billing/Cart/Downgrade test that calls purchase() without a stored
key; each affected fixture now deposits one via the new withStripeSecret()
Pest helper. A few of those tests (CustomDomainAccessTest, DowngradeTest) were
passing already but for the wrong reason — the new guard, not the check they
were named for — since both only assert an order was NOT created; they get
the same fixture fix so they still prove what they claim.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 11:58:01 +02:00
..
Admin Fix nine defects in the provisioning pipelines 2026-07-30 01:34:55 +02:00
Auth Give people a way back in, and put the URL in English 2026-07-29 16:50:29 +02:00
Concerns Close the domain page to packages that may not have one 2026-07-29 16:20:21 +02:00
Backups.php Show times on the operator's clock, keep storing them in UTC 2026-07-27 17:32:21 +02:00
Billing.php Refuse the sale instead of reaching Stripe without a key 2026-07-30 11:58:01 +02:00
Cloud.php Deliver the storage a customer actually buys 2026-07-29 19:13:10 +02:00
ConfirmBookStorage.php Deliver the storage a customer actually buys 2026-07-29 19:13:10 +02:00
ConfirmCancelAddon.php Ask whether they are a consumer, and let one change their mind 2026-07-29 21:06:06 +02:00
ConfirmCancelPackage.php Stop charging for a service that has ended 2026-07-30 00:52:19 +02:00
ConfirmCloseAccount.php fix(portal): no silent no-ops without a customer; maintenance visible per instance; maintenance form redesign 2026-07-25 19:10:44 +02:00
ConfirmDisableTwoFactor.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
ConfirmEndOtherSessions.php Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
ConfirmRemoveOrder.php Book a downgrade for a date that cannot move, and sell a module once 2026-07-29 17:51:37 +02:00
ConfirmRestartCloud.php Restart a machine, enforce the quota that was sold, end a route that ended 2026-07-29 18:28:28 +02:00
ConfirmRevokeSeat.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
ConfirmWithdraw.php Charge the price the website shows, and hand a withdrawal back in full 2026-07-29 22:42:02 +02:00
CustomDomain.php Serve the custom domain, not just announce it 2026-07-29 16:44:52 +02:00
CustomerProvisioning.php Take the order, park it, and say when it will be delivered 2026-07-29 18:50:46 +02:00
Dashboard.php Prove a custom domain before serving it, and keep proving it 2026-07-29 14:47:51 +02:00
EditMailbox.php Merge credentials and infrastructure into one Integrations page 2026-07-29 01:49:39 +02:00
EditSeat.php Editing in modals, an update button that is not gated on a stale reading, and a support page that is real 2026-07-27 17:55:49 +02:00
Invoices.php Say the same thing to the customer, the register and the bank 2026-07-30 01:30:24 +02:00
NewSupportRequest.php Editing in modals, an update button that is not gated on a stale reading, and a support page that is real 2026-07-27 17:55:49 +02:00
Order.php Stop charging VAT to the customers who owe us none 2026-07-30 02:15:41 +02:00
Sessions.php Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
Settings.php Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Support.php Editing in modals, an update button that is not gated on a stale reading, and a support page that is real 2026-07-27 17:55:49 +02:00
Users.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00