From a631fc8039fceaadee8fffcf34896bb7e0777ce1 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Thu, 24 Sep 2026 05:08:47 +0100 Subject: [PATCH] fix(portal): avoid charge claims from cancelled return Treat checkout return values as navigation hints rather than evidence of a completed or absent charge. Keep the cancelled message conditional and ignore unrecognised values. Change-source: pulse-maintainer --- .../v6/internal/subsystems/cloud-paid.md | 4 +++- internal/cloudcp/portal/dist/build_manifest.json | 2 +- internal/cloudcp/portal/dist/portal_app.js | 4 ++-- .../cloudcp/portal/frontend/src/provider_plan.test.ts | 10 ++++++++-- internal/cloudcp/portal/frontend/src/provider_plan.ts | 4 ++-- 5 files changed, 16 insertions(+), 8 deletions(-) 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.'; } }