diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md index aaaaaa9b62..8d90d9d6e6 100644 --- a/docs/release-control/v6/internal/subsystems/cloud-paid.md +++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md @@ -3500,7 +3500,9 @@ without requiring a second restart; an unchanged visit stays silent. A stale panel is replaced only after the refreshed running plan is confirmed, never because the billing return URL says a change was made. When the return check finishes before the initial plan load, the panel may show that confirmed paid -plan silently but must keep its second check for a later webhook. Regression +plan silently but must keep its second check for a later webhook. A cancelled +or unknown checkout return value must not assert whether a charge occurred. +Regression coverage: `TestLoadConfig_ProviderHostedMSPPrefersRenewedLicense` in `internal/cloudcp/config_test.go`, diff --git a/internal/cloudcp/portal/dist/build_manifest.json b/internal/cloudcp/portal/dist/build_manifest.json index 58e6172e48..7780992355 100644 --- a/internal/cloudcp/portal/dist/build_manifest.json +++ b/internal/cloudcp/portal/dist/build_manifest.json @@ -1,5 +1,5 @@ { - "source_hash": "a630a1a29019df3a176613efe21ad63fd006ea2a531bdb1d4cadc2bbb50b2158", + "source_hash": "d5c69f37d9cf32a2e8ef727af6779bd44148235ed352fcb427967ef8a6a24859", "build_inputs": [ "package.json", "tsconfig.json", diff --git a/internal/cloudcp/portal/dist/portal_app.js b/internal/cloudcp/portal/dist/portal_app.js index 897d926212..bc85e87910 100644 --- a/internal/cloudcp/portal/dist/portal_app.js +++ b/internal/cloudcp/portal/dist/portal_app.js @@ -3043,8 +3043,8 @@ pollAfterCheckout(0); } else if (returned === "billing") { checkAfterBillingReturn(0); - } else { - view.notice = "Checkout was cancelled. Nothing was charged."; + } else if (returned === "cancelled") { + view.notice = "Checkout was not completed here. Check your current plan below."; } } return { diff --git a/internal/cloudcp/portal/frontend/src/provider_plan.test.ts b/internal/cloudcp/portal/frontend/src/provider_plan.test.ts index aa5b3148a8..bea0801219 100644 --- a/internal/cloudcp/portal/frontend/src/provider_plan.test.ts +++ b/internal/cloudcp/portal/frontend/src/provider_plan.test.ts @@ -485,9 +485,15 @@ describe('installProviderPlan', () => { expect(controller.view().notice).toBe(''); }); - it('says nothing was charged when checkout is cancelled', () => { + it('does not infer a charge outcome from a cancelled checkout return', () => { const { controller } = install(providerBootstrap(), '?provider_msp_checkout=cancelled'); - expect(controller.view().notice).toBe('Checkout was cancelled. Nothing was charged.'); + expect(controller.view().notice).toBe('Checkout was not completed here. Check your current plan below.'); + expect(api.refreshLicense).not.toHaveBeenCalled(); + }); + + it('ignores an unrecognised checkout return value', () => { + const { controller } = install(providerBootstrap(), '?provider_msp_checkout=unknown'); + expect(controller.view().notice).toBe(''); expect(api.refreshLicense).not.toHaveBeenCalled(); }); diff --git a/internal/cloudcp/portal/frontend/src/provider_plan.ts b/internal/cloudcp/portal/frontend/src/provider_plan.ts index 5664292c35..144af167e1 100644 --- a/internal/cloudcp/portal/frontend/src/provider_plan.ts +++ b/internal/cloudcp/portal/frontend/src/provider_plan.ts @@ -488,8 +488,8 @@ export function installProviderPlan(deps: ProviderPlanDeps): ProviderPlanControl pollAfterCheckout(0); } else if (returned === 'billing') { checkAfterBillingReturn(0); - } else { - view.notice = 'Checkout was cancelled. Nothing was charged.'; + } else if (returned === 'cancelled') { + view.notice = 'Checkout was not completed here. Check your current plan below.'; } }