Per-project to per-user pricing migration
I owned the design, front-end code, and QA of the new billing page. Shipped with Claude Code as my build partner.
Overview
Balsamiq Cloud moved from per-project pricing (in place since 2017) to per-user pricing this year. Our Interim CEO drove the initial spec. Our owner and product designer wireframed the design. Our architect owned the Stripe-integrated backend. I owned the billing page: design refinement, front-end implementation in production code with Claude Code, and end-to-end QA.
My role
- Redesigned the billing page, adapting our founder-designer's wireframes and Claude's first-pass code into what shipped.
- Built the front-end in production code with Claude Code as my build partner.
- Made the product calls on where Stripe checkout hosted the flow versus where our UI did.
- Ran end-to-end QA: plan, running bug list, an AI-generated probe template to test billing flows across fixture states, and unit tests.
- Surfaced legacy plan migration and cancel-and-resubscribe gaps during build, so we designed them before they became QA surfaces.
The challenge
Per-project pricing had become increasingly hard for customers to reason about and misaligned with how teams collaborate today. The company needed to move to per-user pricing without breaking legacy customers, and without losing clarity for users about gated features (SAML, data residency, billing admin) that Stripe checkout couldn't cleanly host.
Objectives
- Move to per-user pricing cleanly, shaped in one cycle and built in the next.
- Preserve access for legacy per-project customers with a real migration path.
- Communicate feature gating clearly for the transitions Stripe couldn't handle in-flow.
- Ship the billing UI at Balsamiq's craft bar, not just at working-parity.
Strategy and execution
Where I owned the flow versus Stripe
Default was to hand off to Stripe checkout. But three features (SAML, data residency, billing admin) needed explanation, not just gating. I kept those transitions in our UI. The tradeoff: more code we own, more surface to maintain. The benefit: our own explanation of why some options weren't available.
Building alongside engineering
Our architect owned the Stripe-integrated backend. I owned the billing page front-end. The boundary was clean at the start, blurred as trust built. By the fixing phase, I was opening PRs for bugs I found during my own QA. Every change went through normal review. I never deployed to production myself.
AI-assisted through every phase
- Prototype. Standalone prototype using our owner's wireframes as reference. The recap I wrote afterward became the implementation brief.
- Plan. Wrote the implementation task list with Claude before touching production code.
- Build. Adapted Claude's first-pass billing UI into what shipped. For each task: wrote the spec, Claude Code proposed, I reviewed and committed.
- Test. AI-assisted QA plan, running bug list, AI-generated probe template to test billing flows across fixture states, unit tests for the changes.
Point of view: shipping code as a PM
Being in the codebase with Claude Code changed the loop between deciding and shipping. When I asked our architect whether the division of labor was working, his answer reframed how I thought about it: coding is easiest for whoever's closest to the domain, and engineering becomes the safety net that keeps AI in line with our conventions.
I'm not claiming this is how every PM should work, or that I'm an engineer. I'm claiming that a PM close enough to a specific product surface, with Claude Code as build partner and engineering as safety net, can close the loop faster than a traditional handoff for that surface.
Results
- Smooth release. Post-release follow-up was smaller than typical for a change of this scope.
- Caught a re-subscribe path during QA that could have allowed free seats at lower capacity. Fixed it in code, opened the PR, approved the next morning.
- Surfaced gaps in the pitch during build (legacy migration path, cancel-and-resubscribe edge case) so they were designed, not discovered post-launch.
- Set a precedent inside Balsamiq that PMs can own UI work end-to-end, which has changed how we scope smaller projects since.
The honest tradeoff
Owning design, implementation, and QA in one person meant work that would normally pass between roles. Some weeks I worked longer days than I would have otherwise. It only worked because engineering let me in, the culture didn't read PM-in-code as a threat, and my manager watched my hours. None of this generalizes: "every PM should ship code now" is the wrong takeaway.
Why it matters
The muscle isn't "I built a billing page." It's deciding where a small company keeps ownership of the customer relationship versus where it hands off to a platform like Stripe. And it's finding out that when a PM is close enough to the product behavior, being in the code with an AI build partner can be the fastest, safest path, not the loudest one. The question I'm sitting with: where else could the loop be shorter?