Problem/Motivation
Since #3629242: Let subscribers choose a plan, not a connector: list plans in the subscribe flow and preselect the plan in redirectToSubscribe() a plan has one price in one currency (PlanPrice), so a site selling the same tier in CAD and USD has two plans per tier. The chooser lists every shown plan, so such a visitor sees both variants of every tier in every group — twice the rows, half of them irrelevant — with nothing but the price label to tell them apart. A site cannot fix this with ordering alone, and hiding one variant per visitor is not something a plan's Show flag can express.
Proposed resolution
- Derived, not configured. The chooser already asks each plan's connector for its price. Collect the distinct currencies of the shown, priced plans; when there are two or more, the chooser gains a currency switcher. One currency, or none (no connector implements
PlanPricingConnectorInterface): nothing appears and nothing changes. No new setting. - One switcher for the page, filtering every group. A single
<select>of the currencies sits above all the groups, the current one selected, and nothing per connector. It has no submit button: choosing an entry reloads the page with that currency (a small library attached by the chooser navigates to?currency=CADonchange). Without JavaScript it degrades to a GET form with a plain Apply button that the library hides, so the page still works. With a currency chosen, every group lists only its plans priced in that currency; plans without a price are always listed, since they cannot be excluded on a currency they do not state. The switcher never reorders groups or changes which one is open: the default-connector steering of #3629242: Let subscribers choose a plan, not a connector: list plans in the subscribe flow and preselect the plan in redirectToSubscribe() is untouched. A group left with no plans is still shown (collapsed, with a "No plans in CUR" line), so a connector does not silently vanish. - Default and memory. The default is the currency of the subscriber's current plan when they have one, else the currency of the first priced plan in the default connector's group. A chosen currency is remembered in user data (
subscription_managermodule, keycurrency) and used on later visits without the query parameter; subscribers are always logged in, so no cookie is needed. An invalid or unknown?currency=falls back to the default. - Direct hand-offs are unaffected.
?connector=&plan=still names a plan outright; the single-plan short-cut counts plans across all currencies, as now (a site with a CAD plan and a USD plan has two plans, and gets the chooser with the switcher). - API. The chooser shape of
api/subscribe-urlgainscurrencies(the distinct list, in the order offered) andcurrency(the one applied);?currency=filters itsplans[]the same way and is remembered the same way. Front ends that want all plans at once pass?currency=all, which is also accepted by the page. - Cache. The chooser adds
url.query_args:currency; the remembered choice is per user, which the existingusercontext covers. - Plan switching. #3629796: Let a charge-based subscriber switch plans on the native management page, upgrading now and downgrading at period end's in-page list should offer only plans in the subscription's currency, which this issue's currency grouping makes a one-line filter; the engine's proration assumes one currency per subscription.
Remaining tasks
- Design pass: where the switcher sits in
subscription-manager-plan-chooser.html.twig(newcurrenciesandcurrencyvariables, so themes already overriding the template keep working); whether the switcher is a render-array form element passed to the template or markup the template builds, given that the chooser is a plain theme hook rather than a form; whether the empty-group line is wanted or the group should hide; whether?currency=allis worth having on the page. - Implementation in
PlanChooser(currency collection, filter, default) with Kernel tests (one currency: no switcher; two: switcher, filter, unpriced plans kept, default from the current plan, memory in user data, invalid values, API fields) and a browser test for the links. - Change record (additive: template variables, API fields, query parameter; no connector impact).
User interface changes
A currency drop-down above the plan chooser's groups, reloading the list on selection, only when the shown plans are priced in more than one currency.
API changes
api/subscribe-url's chooser shape gains currencies and currency and honours ?currency=. Two new template variables and a small JavaScript library. No connector interface changes.
Data model changes
None. The remembered currency lives in user data.
Comments