Skip to content

Commit 2d9e34c

Browse files
committed
payg bundle: address #7032 review nits (comments + i18n fallbacks)
- Comments claiming the metered subscription is auto-provisioned off the saved card (ActivationChoiceModal, FreePlanView) now describe it as a known, not-yet-wired follow-up rather than asserting it works. - Corrects the price-authority narrative: the client-sent p_price_minor is a pre-mint display estimate only; create-payg-bundle-quote overwrites price_minor with the server-derived total once the Stripe quote is minted, and the Stripe line/amount is always server-derived (stripe.ts, BundleCheckoutModal). - Aligns 'prepaid PDFs' code fallbacks with the 'prepaid credits' TOML (usageMeters, PrepaidCapacityCard).
1 parent 605c1a4 commit 2d9e34c

6 files changed

Lines changed: 25 additions & 13 deletions

File tree

frontend/editor/src/cloud/components/shared/config/configSections/usageMeters.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ export function PrepaidCapacityMeterPanel({ snap }: { snap: PrepaidSnapshot }) {
196196
figure={snap.remaining.toLocaleString()}
197197
capSuffix={t(
198198
"payg.prepaid.meter.capSuffix",
199-
"of {{total}} prepaid PDFs",
199+
"of {{total}} prepaid credits",
200200
{
201201
total: snap.total.toLocaleString(),
202202
},

frontend/editor/src/portal/billing/stripe.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,12 @@ export interface BundleQuoteInput {
117117
provisionedMonthlyVolume: number;
118118
/** Size-folded run-credits = the Stripe line quantity when this quote is paid. */
119119
poolCredits: number;
120-
/** Discounted total in minor units; null when the per-run rate is unknown. */
120+
/**
121+
* Client-estimated discounted total in minor units, persisted for the pre-mint display only; null
122+
* when the per-run rate is unknown. NOT authoritative: once the Stripe quote is minted,
123+
* create-payg-bundle-quote overwrites the row's price_minor with the server-derived total
124+
* (Price x qty - amount_off), and the Stripe quote/invoice amount is server-derived regardless.
125+
*/
121126
priceMinor: number | null;
122127
currency: string;
123128
/** Affirmative consent to the prepaid→metered auto-transition (ARL/EULA §7.2). */

frontend/editor/src/portal/components/billing/ActivationChoiceModal.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,14 @@ function DoorCard({
5050
* before any card is entered. Two door-cards, matching the demo —
5151
*
5252
* - Pay as you go → the metered subscription checkout (spend limit + card).
53-
* - Prepay a year → the discounted bundle (calculator + one-time payment); the
54-
* backend silently stands up the metered subscription off the saved card so
55-
* metering resumes when the pool empties, so no spend-limit step is needed.
53+
* - Prepay a year → the discounted bundle (calculator + one-time payment); no
54+
* spend-limit step, since the buyer commits to a fixed pool up front.
5655
*
5756
* Same per-PDF rate on both paths — prepay just front-loads two free months.
57+
*
58+
* Note: auto-standing-up the metered subscription off the saved card so metering
59+
* resumes once a prepaid pool empties is a known follow-up, NOT yet wired — a
60+
* prepay-only team isn't metered past its pool today.
5861
*/
5962
export function ActivationChoiceModal({
6063
open,

frontend/editor/src/portal/components/billing/BundleCheckoutModal.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,12 @@ export function BundleCheckoutModal({
218218
const [stripeQuoteSig, setStripeQuoteSig] = useState<string | null>(null);
219219
// The invoice generated when the quote is accepted (awaiting payment); null when simulated.
220220
const [invoice, setInvoice] = useState<BundleInvoice | null>(null);
221-
// On resume, the total the quote was persisted at (server value), frozen so the receipt shows what
222-
// the buyer actually quoted rather than a figure recomputed from a since-changed rate. Paired with
223-
// the pool size it was persisted at — once the buyer edits the sizing (pool changes) we drop back to
224-
// the live estimate, since editing re-mints and re-persists anyway.
221+
// On resume, the total the quote was persisted at, frozen so the receipt shows what the buyer
222+
// actually quoted rather than a figure recomputed from a since-changed rate. Once the Stripe quote
223+
// has been minted this is the server-derived total (create-payg-bundle-quote overwrites price_minor
224+
// with Price x qty - amount_off); before that it's the client estimate persisted at upsert. Paired
225+
// with the pool size it was persisted at — once the buyer edits the sizing (pool changes) we drop
226+
// back to the live estimate, since editing re-mints and re-persists anyway.
225227
const [persistedPriceMinor, setPersistedPriceMinor] = useState<number | null>(
226228
null,
227229
);

frontend/editor/src/portal/components/billing/FreePlanView.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,11 @@ export function FreePlanView({ wallet, unsynced, onSubscribed }: Props) {
184184
)}
185185

186186
{/* Prepay reuses the bundle modal (free team → first-purchase copy, no cap
187-
step). On completion the webhook credits the pool AND silently creates
188-
the metered subscription off the saved card, so we poll like the payg
189-
path to flip the wallet to subscribed. */}
187+
step). On completion the webhook credits the pool; we still poll onSubscribed
188+
like the payg path, but flipping the wallet to subscribed depends on the
189+
metered-subscription auto-provisioning off the saved card, a known follow-up
190+
that's NOT yet wired — so for a prepay-only team this poll can just time out
191+
until then. */}
190192
{wallet.teamId != null && (
191193
<BundleCheckoutModal
192194
open={step === "prepay"}

frontend/editor/src/portal/components/billing/PrepaidCapacityCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function PrepaidCapacityCard({
7575
figure={remaining.toLocaleString()}
7676
capSuffix={t(
7777
"portal.billing.prepaid.capSuffix",
78-
"of {{total}} prepaid PDFs",
78+
"of {{total}} prepaid credits",
7979
{
8080
total: total.toLocaleString(),
8181
},

0 commit comments

Comments
 (0)