Skip to content

fix: detect billing plan across all active Stripe subscriptions - #5228

Open
Siumauricio wants to merge 2 commits into
canaryfrom
fix/hubspot-chat-multi-subscription-plan
Open

fix: detect billing plan across all active Stripe subscriptions#5228
Siumauricio wants to merge 2 commits into
canaryfrom
fix/hubspot-chat-multi-subscription-plan

Conversation

@Siumauricio

@Siumauricio Siumauricio commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes the HubSpot chat bubble not showing for cloud users on the Startup plan.

getCurrentPlanForUser (billing.ts) and getProducts (stripe.ts) only looked at subscriptions.data[0], the first active Stripe subscription returned. A customer with more than one active subscription (e.g. Startup plus a separately purchased additional server) could have the plan resolved from the wrong subscription, so currentPlan came back as null/wrong plan instead of "startup", and the chat bubble (gated on currentPlan === "startup") never rendered.

Both functions now scan price IDs across all active subscriptions instead of just the first one. getProducts also sums currentPriceAmount across all active subscriptions instead of only the first one's items.

Verified locally with Playwright against a cloud-mode instance: stripe.getCurrentPlan now returns "startup" and the HubSpot script loads correctly.

Greptile Summary

The PR updates Stripe plan detection to inspect all active subscriptions instead of only the first and aggregates their charges for the billing view.

  • Resolves Startup, Hobby, and Legacy prices across all returned active subscriptions.
  • Selects the matching plan subscription for billing cadence.
  • Sums prices and quantities across active subscriptions.

Confidence Score: 4/5

The mixed-interval price aggregation should be corrected before merging because it can show customers a materially incorrect billing amount and cadence.

getProducts labels a sum spanning every active subscription with the billing interval of only the selected plan subscription, so annual and monthly charges can be combined and presented as though they share one cadence.

Files Needing Attention: apps/dokploy/server/api/routers/stripe.ts

Reviews (1): Last reviewed commit: "fix: detect billing plan across all acti..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used:

getCurrentPlanForUser and getProducts only inspected subscriptions.data[0],
so a customer with more than one active Stripe subscription (e.g. Startup
plus a separately purchased additional server) could have their plan
resolved from the wrong subscription, resulting in currentPlan !== "startup"
and the HubSpot chat bubble not rendering.
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 31, 2026
Comment on lines 118 to 129
const totalCents = subscriptions.data.reduce(
(subTotal, sub) =>
subTotal +
sub.items.data.reduce((sum, item) => {
const price = item.price as Stripe.Price;
const amount = price.unit_amount ?? 0;
const qty = item.quantity ?? 1;
return sum + amount * qty;
}, 0),
0,
);
currentPriceAmount = totalCents / 100;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Mixed billing intervals misprice totals

If a customer has active subscriptions with different billing intervals, currentPriceAmount combines all their charges while isAnnualCurrent describes only the selected plan subscription, causing an annual charge to be included in a total displayed as monthly—or vice versa—and initializing the plan-change form with a cadence that does not describe that total.

Knowledge Base Used: Billing and enterprise features

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 3f6dfba. currentPriceAmount now sums only the items of the identified plan subscription (activeSub) instead of across all active subscriptions, so it stays consistent with isAnnualCurrent even when a customer has subscriptions on different billing intervals.

Summing across all active subscriptions could mix amounts with
different billing intervals (isAnnualCurrent only reflects the
matched plan subscription), producing an inconsistent total.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant