feat(checkout): Migrate CBA MPGS to Resolver Configuration#3075
feat(checkout): Migrate CBA MPGS to Resolver Configuration#3075henrikh-kovalenko wants to merge 2 commits into
Conversation
4550f1f
8e1862c to
4550f1f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4550f1f. Configure here.
7059546 to
846c74d
Compare
846c74d to
396016e
Compare
| @@ -35,6 +38,13 @@ const HostedCreditCardPaymentMethod: FunctionComponent< | |||
| initializePayment, | |||
| ...rest | |||
| }) => { | |||
| const { selectedState: config } = useCheckout(({ data }) => data.getConfig()); | |||
| const isCBAMPGSResolverEnabled = isExperimentEnabled( | |||
| ): ComponentType<PaymentMethodProps> | undefined { | ||
| const { ComponentRegistry, ...allExports } = lazyPaymentMethods; | ||
| const filteredMethods = Object.fromEntries( |
There was a problem hiding this comment.
Why are we adding this?
There was a problem hiding this comment.
Hi @animesh1987 we want to experiments for our PaymentMethods
However we can't somehow change this

that's why one place where we can check this experiments in this file, and we filter our payment methods if experiment is false then this method should not be in result arr
There was a problem hiding this comment.
for behavior of this PR we set experiment name in config then in file resolvePaymentMethod we check is this experiment true or false if it is true pr if we don't have experiment then this method will be in result arr if not than we will not have this mthod in arr
There was a problem hiding this comment.
Attaching an experiment name to a payment method config requires some explanations on the purpose of this experiment.
Could we use the experiment to control payment method identifiers instead of making it part of the payment method resolution logic?
There was a problem hiding this comment.
This experiment is specifically needed to safely migrate the CBA MPGS and other payment providers that are using hosted fields from the legacy core flow to the new resolver-based package architecture.
Why it needs to be on the resolver level, not on the identifier level:
The resolver is the exact point where the routing decision is made — it determines whether a payment method renders via the new package component or falls back to the legacy V1 core component. Controlling the identifier itself wouldn't give us that routing control, since the same cba_mpgs ID needs to exist in both paths during the transition.
Why we're being cautious:
We previously had an incident with the hosted fields migration process, so we want to roll this out gradually and have a clean rollback path. The experiment flag gives us that safety net.
What happens after the migration is complete:
Once we've validated the rollout, we'll remove both the experiment flag and all the conditional logic around it — it's intentionally duplicated in the code to make that cleanup straightforward (each side clearly shows what gets removed).
Future migrations:
We'll need similar experiments for migrating other payment providers through the same pattern. The experiment field on PaymentMethodResolveId is designed to be generic for exactly that purpose — any future provider migration can use the same mechanism without changes to the resolver infrastructure itself.
There was a problem hiding this comment.
My question is narrower: it's about where the gate lives, not whether it exists.
Agreed on the rollout safety, the experiment, gradual rollout, and clean revert path. All make sense given the prior incident, no objection there.
The point that the routing decision must happen at runtime in the resolver is right (the registry is generated at build time). But that doesn't require an experiment to be a field on PaymentMethodResolveId.
If we do want a generic per-package migration-gate mechanism long term, I think that's worth its own small design rather than an experiment field.
There was a problem hiding this comment.
this is not long term, we need this for migration maybe 3 providers.
Maybe you have some suggestions how we can resolve it ?
There was a problem hiding this comment.
Thanks for the context. That changes the perspective.
this is not long term, we need this for migration maybe 3 providers.
If possible, could you please add this context as comments? My concern is we will soon forget about it.
There was a problem hiding this comment.
I created task for remove this functional after migration will be completed PI-5464
| const isCBAMPGSResolverEnabled = isExperimentEnabled( | ||
| config?.checkoutSettings, | ||
| 'PI-4748.cba_resolver_configuration', | ||
| false, |
There was a problem hiding this comment.
The purpose of this fallback value is for the time when PI-4748.cba_resolver_configuration is undefined in the checkout settings.
If we have surfaced it, we don't need to explicitly set the value here.
There was a problem hiding this comment.
Could you please explain when the experiment will not appear in the features[]?
There was a problem hiding this comment.
Before the experiment is surfaced/registered in LaunchDarkly (or whatever feature flag service is used), the key won't exist in features[] at all — features['PI-4748.cba_resolver_configuration'] will be undefined.
In that case ?? fallbackValue kicks in. Since the default fallback in isExperimentEnabled is true, without explicitly passing false here, cba_mpgs would resolve through the new flow on day one — before we've intentionally enabled it for anyone. That's exactly what we want to avoid.
There was a problem hiding this comment.
You are right, this is intended use case when we introduced this fallback value.
The experiment appears to be added on Jun 23, 2026 at https://app.launchdarkly.com/projects/default/flags/PI-4748.cba_resolver_configuration/targeting?env=production&selected-env=production.
Is anything blocking us from showing it to Checkout FE now?
There was a problem hiding this comment.
I turned on this flag if you about that. Or I miss understood
| ): ComponentType<PaymentMethodProps> | undefined { | ||
| const { ComponentRegistry, ...allExports } = lazyPaymentMethods; | ||
| const filteredMethods = Object.fromEntries( |
There was a problem hiding this comment.
Attaching an experiment name to a payment method config requires some explanations on the purpose of this experiment.
Could we use the experiment to control payment method identifiers instead of making it part of the payment method resolution logic?


What/Why?
Migrate CBA MPGS payment method to the new resolver-based architecture by registering it in the HostedCreditCardPaymentMethod component resolver (packages/hosted-credit-card-integration).
The migration is gated behind the PI-4748.cba_resolver_configuration experiment:
Experiment ON — CBA MPGS routes through the new resolver flow (HostedCreditCardComponent), where createCBAMPGSPaymentStrategy is included conditionally.
Experiment OFF — CBA MPGS falls back to the legacy V1 flow (HostedCreditCardPaymentMethod in core), where createCBAMPGSPaymentStrategy is added to the integration list conditionally.
The experiment flag is checked via isExperimentEnabled in core and directly via checkoutSettings.features in the hosted-credit-card-integration package (where the utility is not available). Both conditional blocks are intentionally duplicated to make cleanup straightforward once the experiment is fully rolled out.
Added global functional for experiment
Rollout/Rollback
roll back this commit
Testing
without 3ds isHostedFormEnabled false
without.3ds.isHostedFormEnabled.false.mov
with 3ds isHostedFormEnabled false
with.3ds.isHostedFormEnabled.false.mov
without 3ds isHostedFormEnabled true
without.3ds.isHostedFormEnabled.true.mov
with 3ds isHostedFormEnabled true
with.3ds.isHostedFormEnabled.true.mov
Note
Medium Risk
Changes which checkout UI and payment initialization path CBA MPGS uses, gated by a feature flag; incorrect flag handling could break MPGS checkout for some stores.
Overview
CBA MPGS can route through the hosted-credit-card resolver when
PI-4748.cba_resolver_configurationis on, instead of always using the legacy core hosted card path.Resolver entries can now declare an optional
experimentonPaymentMethodResolveId.resolvePaymentMethodfilters the generated registry so experiment-gated mappings (e.g.cba_mpgs) only apply when the flag is enabled;PaymentMethodV2passescheckoutSettingsinto that resolver.createCBAMPGSPaymentStrategyis wired on exactly one path: included in the newHostedCreditCardComponentintegrations when the experiment is on, and kept in coreHostedCreditCardPaymentMethodwhen it is off, so rollout can flip without double-registering the strategy.Reviewed by Cursor Bugbot for commit 396016e. Bugbot is set up for automated code reviews on this repo. Configure here.