[PR #6957] [MERGED] [PM-37691] feat: Surface pending cancellation status on Premium plan view #93583

Closed
opened 2026-05-27 12:48:05 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/bitwarden/android/pull/6957
Author: @SaintPatrck
Created: 5/20/2026
Status: Merged
Merged: 5/21/2026
Merged by: @SaintPatrck

Base: mainHead: premium-upgrade/pm-37691-pending-cancellation-status


📝 Commits (1)

  • 1c35c7c [PM-37691] feat: Surface pending cancellation status on Premium plan view

📊 Changes

22 files changed (+375 additions, -29 deletions)

View changed files

📝 app/src/main/kotlin/com/x8bit/bitwarden/MainActivity.kt (+16 -7)
📝 app/src/main/kotlin/com/x8bit/bitwarden/MainViewModel.kt (+13 -0)
📝 app/src/main/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManagerImpl.kt (+3 -1)
📝 app/src/main/kotlin/com/x8bit/bitwarden/data/billing/repository/model/PremiumSubscriptionStatus.kt (+5 -0)
📝 app/src/main/kotlin/com/x8bit/bitwarden/data/billing/repository/model/SubscriptionInfo.kt (+3 -0)
📝 app/src/main/kotlin/com/x8bit/bitwarden/data/billing/repository/util/BitwardenSubscriptionResponseJsonExtensions.kt (+20 -13)
📝 app/src/main/kotlin/com/x8bit/bitwarden/data/platform/manager/model/SpecialCircumstance.kt (+8 -1)
📝 app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/PlanScreen.kt (+22 -1)
📝 app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/PlanViewModel.kt (+38 -3)
📝 app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/util/PremiumSubscriptionStatusExtensions.kt (+5 -0)
📝 app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/RootNavViewModel.kt (+2 -0)
📝 app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/model/AuthTabLaunchers.kt (+1 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/MainViewModelTest.kt (+15 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManagerTest.kt (+1 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/data/billing/repository/BillingRepositoryTest.kt (+1 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/data/billing/repository/util/BitwardenSubscriptionResponseJsonExtensionsTest.kt (+37 -1)
📝 app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/enterprisesignon/EnterpriseSignOnScreenTest.kt (+1 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/twofactorlogin/TwoFactorLoginScreenTest.kt (+1 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/cookieacquisition/CookieAcquisitionScreenTest.kt (+1 -0)
📝 app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/PlanScreenTest.kt (+45 -2)

...and 2 more files

📄 Description

🎟️ Tracking

📔 Objective

After canceling a subscription via the Stripe customer portal, the badge on the Premium plan screen stayed on "Active" until the user manually refreshed. The /account/billing/vnext/subscription payload at that point reports status: active with cancelAt: <future-instant>, and the app never sees a push notification for the transition. Two gaps caused this:

  • The portal launch went through intentManager.launchUri(...) (plain Chrome Custom Tab) with no return signal.
  • The status mapping only looked at the raw status field, so active + cancelAt collapsed to PremiumSubscriptionStatus.ACTIVE.

This PR routes the portal launch through startAuthTab with a dedicated stripePortalLauncher, so closing the tab fires MainAction.StripePortalResultSpecialCircumstance.StripePortal → a fresh /subscription fetch. A new PremiumSubscriptionStatus.PENDING_CANCELLATION is derived when status ∈ {active, trialing} and cancelAt is non-null, rendering a warning badge plus "Your subscription is scheduled to cancel on {date}. You can reinstate it anytime before then."

📸 Screenshots

Figma Actual

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/bitwarden/android/pull/6957 **Author:** [@SaintPatrck](https://github.com/SaintPatrck) **Created:** 5/20/2026 **Status:** ✅ Merged **Merged:** 5/21/2026 **Merged by:** [@SaintPatrck](https://github.com/SaintPatrck) **Base:** `main` ← **Head:** `premium-upgrade/pm-37691-pending-cancellation-status` --- ### 📝 Commits (1) - [`1c35c7c`](https://github.com/bitwarden/android/commit/1c35c7c7ac3211e0bb68a692edfafb1a0d0cf881) [PM-37691] feat: Surface pending cancellation status on Premium plan view ### 📊 Changes **22 files changed** (+375 additions, -29 deletions) <details> <summary>View changed files</summary> 📝 `app/src/main/kotlin/com/x8bit/bitwarden/MainActivity.kt` (+16 -7) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/MainViewModel.kt` (+13 -0) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManagerImpl.kt` (+3 -1) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/data/billing/repository/model/PremiumSubscriptionStatus.kt` (+5 -0) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/data/billing/repository/model/SubscriptionInfo.kt` (+3 -0) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/data/billing/repository/util/BitwardenSubscriptionResponseJsonExtensions.kt` (+20 -13) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/data/platform/manager/model/SpecialCircumstance.kt` (+8 -1) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/PlanScreen.kt` (+22 -1) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/PlanViewModel.kt` (+38 -3) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/util/PremiumSubscriptionStatusExtensions.kt` (+5 -0) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/RootNavViewModel.kt` (+2 -0) 📝 `app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/model/AuthTabLaunchers.kt` (+1 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/MainViewModelTest.kt` (+15 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManagerTest.kt` (+1 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/data/billing/repository/BillingRepositoryTest.kt` (+1 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/data/billing/repository/util/BitwardenSubscriptionResponseJsonExtensionsTest.kt` (+37 -1) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/enterprisesignon/EnterpriseSignOnScreenTest.kt` (+1 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/twofactorlogin/TwoFactorLoginScreenTest.kt` (+1 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/cookieacquisition/CookieAcquisitionScreenTest.kt` (+1 -0) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/premium/plan/PlanScreenTest.kt` (+45 -2) _...and 2 more files_ </details> ### 📄 Description ## 🎟️ Tracking - https://bitwarden.atlassian.net/browse/PM-37691 ## 📔 Objective After canceling a subscription via the Stripe customer portal, the badge on the Premium plan screen stayed on "Active" until the user manually refreshed. The `/account/billing/vnext/subscription` payload at that point reports `status: active` with `cancelAt: <future-instant>`, and the app never sees a push notification for the transition. Two gaps caused this: - The portal launch went through `intentManager.launchUri(...)` (plain Chrome Custom Tab) with no return signal. - The status mapping only looked at the raw `status` field, so `active + cancelAt` collapsed to `PremiumSubscriptionStatus.ACTIVE`. This PR routes the portal launch through `startAuthTab` with a dedicated `stripePortalLauncher`, so closing the tab fires `MainAction.StripePortalResult` → `SpecialCircumstance.StripePortal` → a fresh `/subscription` fetch. A new `PremiumSubscriptionStatus.PENDING_CANCELLATION` is derived when `status ∈ {active, trialing}` and `cancelAt` is non-null, rendering a warning badge plus "Your subscription is scheduled to cancel on **{date}**. You can reinstate it anytime before then." ## 📸 Screenshots | Figma | Actual | |--------|--------| | <img width="365" src="https://github.com/user-attachments/assets/96a55347-0241-4f77-b893-73c08d867a95" /> | <img width="365" src="https://github.com/user-attachments/assets/a99110dc-e5ed-43e3-96ef-7e55345b14a0" /> | --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-27 12:48:05 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/android#93583