Enable a single CustomersDot User to have multiple BillingAccount memberships
# Problem CustomersDot's single billing account membership restriction creates **two separate but related problems** affecting thousands of customers. Both problems stem from the same architectural constraint and require the same solution. ## Problem 1: Billing account access The single billing account membership restriction causes customers to **lose access to subscriptions, invoices, and payment history** they have legitimately purchased. Analysis shows **2,840 unique email addresses (3.33% of all subscribers)** are associated with multiple billing accounts as SoldTo contacts, but can only access one account at a time through CustomersDot. Multiple billing accounts per user occur due to GitLab's subscription architecture creating separate accounts when customers change billing entities, or go through separate purchasing workflows. Customers are locked out of viewing or managing other billing accounts where they have previously made purchases. **Business Impact**: [These 2,840 customers](https://docs.google.com/spreadsheets/d/1MqDJ_JpE-OcKXmlETNge8EyurcTW_RoG/edit?gid=1242014799#gid=1242014799) cannot access all billing accounts where they are legitimate SoldTo contacts, forcing them to contact Support to switch between accounts to view subscriptions, invoices, and payment history they own. This creates ongoing Support ticket volume, and user frustration from requiring Support intervention for basic account access. **Support Impact:** In the support system, a customer can only be tied to one org (i.e. SFDC Account). Customer will only get support for the org they are tied to. So if they only buy consumption minutes on one but ultimate on the other, it'd come down to which account they got associated to in regards to what support they'd be entitled to. (this was raised by `@jcolyer`). ## Problem 2: Billing Account Managers workflow disruption (.com-specific) The same architectural limitation prevents users from accepting BAM (Billing Account Manager) invitations across multiple billing accounts. **5,851 .com groups (9.31% of all groups with subscription history)** have multiple billing accounts, often created when different Group Owners make purchases or when organizations have multiple purchasing workflows. Group Owners cannot utilize the recently launched self-service BAM invitation feature without Support intervention to manually remove their existing membership first. **Business Impact**: [These 5,851 groups](https://docs.google.com/spreadsheets/d/1Mohb8HAMYORO0ONNk5m6l2NDAz05e55jeACvtT3GFkA/edit?gid=0#gid=0) cannot utilize the BAM invitation feature as designed, where Group Owners want to collaborate on billing management across their organization's accounts but are forced to contact Support for manual membership changes before accepting invitations. This creates feature adoption limitations for new self-service BAM capabilities and user frustration from requiring Support intervention for collaboration workflows. # Solution **Enable multiple billing account memberships per User** - allow CustomersDot Users to be members of multiple billing accounts simultaneously, removing the architectural constraint that causes both service access and workflow collaboration problems. The solution requires updating CustomersDot's data architecture to support the `User` to `BillingAccount` many-to-many relationship that was designed in previous iterations but restricted to one-to-one. This includes: * Removing safeguards that prevent multiple `BillingAccountMembership` records per User * Updating UI/UX to handle multiple account contexts ## Iterations <table> <tr> <th> :hash: </th> <th>Description</th> <th>Scope of work</th> <th>Status</th> </tr> <tr> <td> :one: </td> <td> [**Iteration 1: Core multi-billing account backend architecture**](https://gitlab.com/groups/gitlab-org/-/epics/19865) </td> <td> Build the backend infrastructure to support multiple billing account memberships per user based on [this blueprint](https://gitlab.com/gitlab-org/customers-gitlab-com/-/blob/main/doc/architecture/design_documents/multiple_billing_account_managers/phase_2.md): * Implement `Current` model with `ActiveSupport::CurrentAttributes` * Create `BillingAccountContext` service for session-based account management * Add `BillingAccountManager` controller concern * Migrate services to use `Current.billing_account` * Keep the unique constraint on `billing_account_memberships` in place * **No customer-facing changes** </td> <td> Planned for ~&quot;FY26::Q4&quot; </td> </tr> <tr> <td> :two: </td> <td> [**Iteration 2: Customer experience**](https://gitlab.com/groups/gitlab-org/-/epics/19866) </td> <td> Launch the multi-billing account customer experience: * Create the multi-billing account landing page * Build the billing account selector component * Design and implement solution for customers to see which billing account they're currently viewing and switch between accounts throughout the portal * Implement [robust logic](https://gitlab.com/groups/gitlab-org/-/epics/8986#note_2649895051) to automatically select the right billing account and avoid prompting customers to select when possible * Modify profile dropdown to show "My billing accounts" * Implement `set_current` and `available` endpoints for account switching * Update all portal flows to maintain billing account context throughout the session * Remove the unique constraint on `billing_account_memberships` to enable many-to-many relationships Previous design discussions: * https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/4973#note_1289078968 * [Solution validation results](https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/4973#note_1317643028) </td> <td> ~UX is planned for either ~&quot;FY27::Q1&quot; or ~&quot;FY27::Q2&quot; </td> </tr> <tr> <td> :three: </td> <td> **Iteration 3: Data migration** </td> <td> Backfill existing data to create multi-billing account access: * Query Zuora to identify multiple billing accounts associated with the same email address * Create corresponding billing account memberships in CustomersDot for each Zuora billing account found * Enable users to access all their Zuora billing accounts from a single CustomersDot login </td> <td>Blocked by iteration 2.</td> </tr> </table> <!--## Impact and rationale When considering [all SoldTo Contact emails](https://docs.google.com/spreadsheets/d/1MqDJ_JpE-OcKXmlETNge8EyurcTW_RoG/edit?gid=1242014799#gid=1242014799) (as of 2025-07-21), this use case makes up about 3.33%: | TOTAL | 85,321 | 100% | |-------|--------|------| | Num. of Accounts per email address **= 1** | 82,481 | 96.67% | | Num. of Accounts per email address **\> 1** | 2,840 | **3.33%** :point_left: | ### Use cases for having multiple Zuora accounts per email Paraphrased from <a href="https://gitlab.com/gitlab-com/business-technology/enterprise-apps/financeops/finance-systems/-/issues/938#note_1140330611">_Brian's comment_</a>: 1. Same SoldTo or BillTo contact used on multiple account created to represent a different selling entities (US, DE, UK, etc). 2. Same BillTo contact used on multiple accounts created to represent different subsidiaries. 3. Multiple accounts created for one-time charges * For example, `example@email.com` is listed as the BillTo and SoldTo contact for five accounts and all of the subscriptions have a one-time charge for GitLab.com CI Minutes.--> --- **Support Priority Score:** 24
epic