Files
cgalo5758 d1352b3b3e Say that an upgrade to another billing interval starts a new period today
#287. When a member upgrades to a tier billed on another interval, for
example from a monthly tier to a yearly one, Stripe does not prorate
within the current period: it starts a new period on the day of the
switch, charges the full new period less a credit for the unused time,
and moves the billing date to that day. The confirmation said the
charge was "for the rest of this period". It now reads "Your card is
charged $270.32 now, after a credit for the unused part of your current
plan, then $300.00 a year from today."; when the credit covers the new
price, "Nothing is charged now; then $40.00 a month from today."; and
when Stripe's preview gives no figure, the paused switch's sentence,
"Your card is charged {price} now, minus a credit for the unused part
of your current plan, then {recurring} from today."

The offer decides the case: rule 16 marks an enabled upward switch as a
new period when both the held price's interval and the target's are
known and differ (Position.Interval, set in onLadder from the rows
payingOn already reads; no statement is added). A switch at the
subscription's own interval and a downgrade read as before. Accepted:
from a yearly price to a monthly one, the no-figure sentence names a
charge the credit can exceed; it shows only when Stripe's preview fails
or Stripe still carries the console's pause.

docs/stripe.md and docs/models/payments-billing.md say the same.

Tests: TestOffer rows for the interval change (including a yearly
subscription offered a switch to a new period above it, an upgrade from
a yearly price to a monthly one), TestPlanMoveMessageStatesTheTiming
rows for N1, N2 and the no-figure sentence, and
TestSwitchPreviewAcrossIntervals (three members priced across
intervals, the confirmation read from the page). No golden changed.

Full suite on reset databases: 5161 passed, 15 skipped, none failed.
make screens: no page changed; no demo state reaches the confirmation.
Sandbox walk on this commit: monthly to yearly confirmed $270.00 and
Stripe's invoice charged 27000 with the period and billing date moved
to the switch; yearly to monthly read "Nothing is charged now", the
invoice was paid at 0 and the credit stayed as the customer's balance;
an upgrade over a scheduled downgrade left no schedule on the
subscription and a year's period from the switch.

Breaks, all CAUGHT (15 records):
- rule 16 marks no new period
- relation test dropped
- unknown interval test dropped
- enabled test dropped
- interval comparison reduced to the target's interval being set
- onLadder leaves the interval unset
- N1 worded as today's figure sentence
- N2 without from today
- N1 reached without a new period
2026-10-30 01:29:48 -05:00
..