Designing the Service Infrastructure Behind Pricing and Billing
How I turned fragmented service and supplier data into a governed system connecting operational costs, customer pricing, orders, and invoicing, across three business models.
Context
The request that wasn't the real problem
I was designing a feature that would let clients document their service instructions inside the platform: standard operating procedures for how a device should be configured, shipped, or handled. It sounded like a straightforward content problem.
Then I hit something odd. The feature was asking customers to describe services that, technically, didn't exist yet. Not as structured, connected records anyone in the company could point to. GroWrk had grown from one subscription model into three (All In, Flex, and A La Carte), each with its own service inclusions and pricing logic. But nothing tied a supplier's raw service to what GroWrk actually sold, or to what a customer should be charged for it.
That gap became the real project.
The Problem
What was actually broken
GroWrk needed a reliable link between three things: what suppliers charged, what GroWrk sold, and what customers paid. That link didn't exist.
Instead:
Supplier costs lived across spreadsheets, contracts, and individual conversations.
Operations interpreted supplier agreements by hand, every time.
Finance built invoices by piecing information together from multiple sources.
Prices for the same kind of service could vary by country and by business model, with no single place that showed why.
Some services being delivered weren't being charged at all, because they weren't represented in the platform or in the order. Extra pickup boxes are a concrete example: clients received them, but there was no structured way to represent that service within the order, so it went unbilled.
None of this was any one team's fault. It was the natural result of adding new business models faster than the underlying service structure could keep up.
This mattered because it wasn't just a design inconvenience. It touched margin visibility, billing accuracy, pricing consistency, and how fast GroWrk could scale a lower-touch model like Flex. Every one of those has a dollar sign attached.
Constraints & Complexity
Why this wasn't a table redesign
The obvious version of this project is "build a bigger table with the services in it." That version would have failed within a quarter.
The system had to represent 313 distinct service definitions across two layers: what a supplier actually does, and what GroWrk sells to a client. Some map one to one. Others bundle several supplier line items into a single customer-facing service. Multiply that by multiple suppliers per country, multiple countries with their own currencies, and three business models that each price the same service differently (included in a subscription, billed as a fixed amount, quoted case by case, or not offered at all), and "a table with the services in it" stops being a real answer.
A few constraints shaped everything downstream:
V3 depended on V2 being stable first. I couldn't design the customer-facing layer until the supplier-facing foundation held.
Costs changed more often than prices should. Supplier pricing moved frequently; customer pricing needed to stay predictable.
Ownership was split. Finance, Operations, and Product each owned a different slice of the system, and the interface had to make sense to all three without becoming three different tools.
The pricing formula itself was still being finalized by Finance while I was designing the structure that would eventually hold it.
That last one turned into one of the more interesting decisions in the project. More on that below.
My Role
What I owned
I wasn't handed a finished spec. I identified the underlying problem while working on an unrelated feature, helped make the case for expanding the scope beyond it, and led the translation of operational and financial knowledge into a product architecture that could actually hold it.
I led the discovery and framing, the cross-functional research with Product, Operations, Procurement, Finance, and Engineering, the information architecture connecting Supplier Services to GroWrk Services, the Costs, Prices, and History structure, the navigation patterns for a genuinely dense dataset, prototyping, and a round of usability testing with eight cross-functional participants. I also worked directly with Finance and Engineering on how the pricing logic itself should be modeled, without personally owning the financial formula.
Research
Three teams, three different definitions of a "service"
Early research made one thing clear fast: Operations, Finance, and Product weren't just missing a system. They were working from three different mental models of what a "service" even was. Operations thought in terms of what a supplier physically did. Finance thought in terms of what got billed. Product needed something that could hold both without breaking.
V2 research involved cross-functional alignment across more than 90 initial services that needed standardizing, clarifying ownership across Logistics, Finance, and Product, and mapping how a supplier-side service should translate into something a client-facing team could sell. V3 research went further: interviews with Sales, Operations, and Finance surfaced the need to distinguish services included in a subscription from services charged separately, country-level pricing differences, company-specific contract overrides, Finance SKUs, and a recurring theme: services being performed without a clean connection to billing.
Defining the Model
Separating what suppliers do from what customers buy
The foundational decision was splitting the system into three layers instead of one:
Supplier Service: the raw operational service a vendor performs.
GroWrk Service: the standardized service a customer actually understands and requests.
Price + SKU: the financial output, shaped by geography and business model.
A single customer-facing "Deployment" service, for example, might bundle several separate supplier activities behind the scenes: device preparation, packaging, and shipping. The customer never needs to see that breakdown. Finance and Operations do, and the model had to hold both views at once without forcing either team into the other's mental model.
Key Decisions
Separating cost from price
Organizing by country, then supplier
Cost is what GroWrk pays a supplier. Price is what a customer pays, after business rules are applied. Those sound similar. They are not the same number, and conflating them was part of what made the original spreadsheets so hard to trust.
I designed Supplier Costs and GroWrk Prices as two distinct, connected structures rather than one merged view: costs organized by supplier and country, prices organized by country and business model, with a Country Base Cost acting as the bridge between them. Separating the two made margin logic visible for the first time, and it kept the mental model clean for teams who only needed one side of it.
The earliest structure treated every supplier-region combination as its own column, which meant a Service and Supplier Matrix that grew wider every time GroWrk added a new supplier or entered a new country. It worked, technically. It didn't match how anyone actually used the data.
Operations evaluated coverage and cost country by country, not supplier by supplier. So I restructured the hierarchy: country as the primary group, suppliers nested and expandable underneath, with Country Base Cost shown in local currency and normalized to USD. It's a small architectural change with a real effect: faster market-level scanning without losing supplier-level detail when someone actually needed it. That pattern held up well enough that it's since been adopted into GroWrk's design system as a reusable way to handle dense, hierarchical data elsewhere in the platform.
Governance over unrestricted flexibility
V2 let staff create new services and bundles directly from the table. It felt flexible. It was also a quiet risk: a service created without a defined connection to orders, pricing, and SKUs could break every downstream feature that depended on the catalog being trustworthy.
For V3, I removed unrestricted service creation from general staff access and replaced it with a request-and-review process through Product. It's a smaller feature on paper. It's also the decision that keeps the catalog from becoming exactly the kind of fragmented, untrustworthy system it was built to replace. A slightly less flexible tool that stays accurate beats a flexible one nobody fully trusts.
Designing around a pricing formula that wasn't finished yet
Finance hadn't finalized how Country Base Cost should actually be calculated (weighted supplier cost, fulfillment history, risk uplift, FX buffer, and business-model margin were all still being debated) while I needed to keep the product architecture moving.
So I designed around the formula instead of waiting for it. Country Base Cost became a derived, read-only value: something the interface could display and depend on structurally, without the table itself owning the calculation logic. That let Product, Design, and Engineering keep building while Finance and backend owners finished defining the actual policy underneath it. I didn't build the final formula. I built a structure that could hold whatever the formula turned out to be.
Validation
What eight usability sessions told me
I ran usability sessions with eight cross-functional participants (two from Product, four from Operations, one from Finance, one C-level).
The core model held up. Participants understood the catalog's purpose quickly, and the Costs versus Prices distinction matched how Operations and Product already thought about the problem. Country Base Cost read clearly as a country-level aggregation, and once people noticed USD normalization, they considered it genuinely useful.
Testing also surfaced two specific things worth fixing before development: most participants didn't independently notice when a service was marked Not Available, and most didn't notice Country Base Cost recalculating after an edit. Both are solvable with clearer state design, not a rethink of the model itself, which is exactly the kind of finding you want before development, not after.
Outcome
What shipped, and what's proven
V2 shipped. It established the standardized Supplier Service structure GroWrk now runs on: supplier costs organized centrally, services connected to categories, countries, and suppliers, with edit history, import and export, and change tracking built in. It's the foundation everything else sits on.
V3 is partially shipped. Parts of it are already live in production; the rest is designed, validated through usability testing, and still in development. It extends the architecture to the customer-facing layer: GroWrk Services connected to Supplier Services, Costs separated from Prices, All In, Flex, and A La Carte logic represented explicitly, Finance SKUs attached, and full auditability through catalog history.
Until exact metrics are available, the honest version of the impact is this: the catalog created a shared service infrastructure across Product, Operations, and Finance, closing a gap where delivered services could exist without a clean connection to an order or an invoice.
Reflection
What I'd do differently, and what's next
Building a source of truth turned out to be less of a UI problem than I expected going in. The interface mattered, but trust in the system depended just as much on who owned which numbers, how often data actually got updated, and whether people could see why a price was what it was.
If I kept going, I'd want to measure a few things directly: how often staff complete or abandon a catalog edit, whether viewing a price correlates with a service actually getting requested, how often someone needs a manual override, and how much manual reconciliation work actually goes away once V3 is live. Right now those are open questions rather than results, and I'd rather say that plainly than round up.