Pin every third-party action in .github/workflows/ to a full commit SHA
with a trailing version comment, and bump to the latest stable release.
Defends against tag-rewrite supply-chain attacks while keeping versions
legible.
Two issues surfaced during user testing of the live-payment flow on
create-organization and change-plan.
1. confirmPayment() in src/lib/stores/stripe.ts always called
resolve('/(console)/organization-[organization]/billing', {organization: orgId})
eagerly at the top of the try block. The create-organization callsite
passes only `route` (no orgId, since the team doesn't yet exist), so
resolve() threw on the missing required `organization` param, the
outer catch fired, and the user saw the generic
"There was an error processing your payment..." message instead of
the actual Stripe error. The URL is now built lazily — resolve() is
only invoked when no `route` is supplied. The outer catch now
surfaces the underlying error message (Stripe / SDK error) and falls
back to the generic copy only when no message is available.
2. When the frontend Stripe confirmation failed, the backend was never
notified, leaving draft teams (status='draft') and partial upgrades
stranded. handleTeamCreateUpgradeFailure already deletes drafts and
rolls back upgrades — but only when the backend recognises failure.
The create-organization and change-plan error branches now make a
best-effort call to organizations.validatePayment after a failed
confirmation. validatePayment inspects the actual Stripe intent and
routes to handleTeamCreateUpgradeFailure when it isn't
succeeded/processing. validatePayment is expected to throw
BILLING_PAYMENT_FAILED in this path; the throw is swallowed because
the user has already seen the underlying Stripe error and the
backend cleanup is the desired side-effect.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch the BAA addon enable flow (both the re-enable button on the
settings card and the BAAEnableModal submit) to confirm the addon
PaymentIntent on-session via stripe.confirmPayment with redirect:
'if_required'. After a succeeded or processing outcome, finalize the
addon by calling organizations.confirmAddonPayment directly and
invalidate ADDONS + ORGANIZATION dependencies inline — no more URL
round-trip via ?type=confirm-addon&addonId=.
A processing outcome surfaces an info notification ("BAA addon payment
is processing — we'll activate it shortly.") since the addon stays
pending while Stripe settles, and the existing "Payment pending" badge
on the BAA card already covers the visual state.
The onMount redirect-handler in BAA.svelte that consumes the
?type=confirm-addon query string is preserved as a fallback for the
rare case where Stripe still elects to redirect (e.g. some 3DS
challenges that can't be inlined) — the route is still passed to
confirmPayment so Stripe has a return URL when needed.
Switch the create-organization and change-plan submit flows to confirm
PaymentIntents on-session via stripe.confirmPayment with redirect:
'if_required'. The frontend now treats PaymentAuthentication responses
as the expected default path for paid plans (not just the 3DS edge
case) and surfaces succeeded / processing / requires_action outcomes
to callers via a new ConfirmPaymentOutcome return type. Other call
sites (account/payments, billing, BAA, retry-invoice) remain on the
previous redirect-based flow.
Add a "Payment is processing" header alert that renders when the
team status is 'upgrading' (Stripe still settling). The alert sits
below readonly / budget / mark-for-deletion alerts (importance 5),
so it only shows when nothing more critical is happening, and lets
the user keep using the org while the charge clears.
Update the Indian RBI card-holder warning copy to reflect that the
first charge is now authenticated on-session and the $150 mandate
applies to future renewals — this avoids the 24h "processing"
limbo seen with off-session first charges under the RBI mandate.