All work

Case study 02 · TrueProfit · Shopify SaaS

Four setup paths became three. Support tickets fell 83%.

Redesigning shipping cost settings for a net profit analytics app, so merchants can set it up right the first time and trust the number on their dashboard.

Role
Senior Product Designer
Company
Firegroup
Timeline
Apr 2023 to Oct 2024
Scope
Research, IA, flows, UI, design system on Shopify Polaris
TrueProfit, net profit analytics for Shopify. 13,500+ installs and a 4.9 out of 5 rating, shown next to the analytics dashboard.

Problem

Shipping cost setup had four overlapping paths. Merchants got lost, made mistakes, and their profit reports went wrong.

What I did

Mapped every case, then rebuilt the model location-first. One default zone now covers most stores with zero product work.

Outcome

−83% support tickets, setup time from 8 to 4.3 minutes, and +5% free-to-paid conversion.

−0%

support tickets

0→0

minutes to finish setup

+0%

free-to-paid conversion

$0K

MRR, across 4.8K monthly active merchants

01Context

Profit is only as true as the costs behind it.

TrueProfit is a Shopify app that shows merchants their real net profit. Revenue minus ad spend, cost of goods, transaction fees, and shipping. It has over 13,500 installs and a 4.9 out of 5 rating.

Every number on the dashboard depends on the costs merchants enter in settings. If shipping cost is wrong, net profit is wrong. If net profit is wrong, the product has no reason to exist. So settings were not a back-office page. They were the foundation of trust.

I owned the redesign of the cost of goods (COGS) and shipping cost settings. This case focuses on shipping, the more complex of the two.

02The problem

The settings asked merchants to think like a database.

Real shipping is messy. A store might ship most products worldwide at one price, charge more for heavy items, and use different rates for a few countries. The old settings could handle all of that. The problem was how they asked for it.

Merchants had to start by creating a shipping profile, which is a set of products. Only then could they choose where those products ship and at what price. To set one special rate for one country, a merchant had to build a profile, pick products, add a zone, pick countries, and only then set a cost.

Merchants think “where do I ship, and what does it cost?” The old settings asked “which products?” first.

The cost showed up in three places. Setup took around 8 minutes. Support tickets about shipping kept coming. And free-trial merchants who couldn’t get accurate numbers had little reason to upgrade to a paid plan.

03Mapping the mess

Before simplifying anything, I drew every possible path.

I mapped every configuration a merchant could create in the old model. Four distinct cases came out, each a different combination of profile type and zone type.

Old modelCase 1

All products, worldwide, one price

Default profile → all products → worldwide → rule and cost.

Old modelCase 2

Some products, worldwide, one price

Custom profile → select products → worldwide → rule and cost.

Old modelCase 3

All products, several zones

Default profile → all products → custom zone → select countries → rule and cost.

Old modelCase 4

Some products, several zones, several prices

Custom profile → select products → custom zone → select countries → rule and cost.

Seeing them side by side made the issue obvious. Location appeared in every case, but it came last. Products came first, even though most stores charge the same for every product. The model was built around the exception, not the rule.

04The reframe

Flip the order: location first, products only when needed.

I rebuilt the model around shipping zones. Every store gets a default zone that covers “all countries not in other zones”. Inside a zone, products sit in groups. By default there is one group with every product in the store.

That means the most common setup, one price for everything everywhere, needs no product selection at all. Merchants add product groups only when prices differ. They add custom zones only when a country needs its own rate.

4setup paths18steps across all paths

BeforeProduct-first

  • Start by creating a profile, which is a list of products.
  • Location is chosen inside each profile, so zones repeat across profiles.
  • A single country exception means building a whole new profile.
  • Four paths with up to five steps each.

AfterLocation-first

  • Start from a default zone that already covers the world.
  • Products live in groups inside a zone, with one group by default.
  • A country exception is one custom zone with its own groups.
  • Three paths, and the most common one has three steps.

05Designing the details

A simple model still needs guardrails.

A clean model on a diagram is only half the work. The other half is making every screen prevent mistakes instead of reporting them later. These are the key moments of the flow.

Shipping Costs page. A Default zone card shows Rest of world, all products in store as one group, and shipping costs of 12 to 36 dollars. Below is an empty Custom zones section with a Create zone link.
The landing state. The default zone summarizes where, what and how much in one row. An empty state explains custom zones in one sentence, with one action.
Edit default zone modal with Rest of world on the left and a Product group panel on the right showing the Default group, quantity-based, at 0 dollars.
Edit a zone. Where on the left, what and how much on the right.
Edit default zone modal with a new product group named Group 1 containing three selected products.
Add a product group. Only when some products cost more to ship.
Edit products picker with filters for products selected in this group, selected in other groups, and available products.
No double-counting. The picker shows which products already sit in another group, so one product never gets two shipping costs.
Product group form with an inline error: click Add products and select at least one product.
Inline validation. A group can’t be saved empty. The error says exactly what to do next.

Rules that keep data clean

A zone must have at least one country and at least one product group. Merchants edit one group at a time, and it is validated before they can open another. Search and filters have their own empty states.

Create custom shipping zone modal. Zone details and selected countries on the left. Several product groups on the right, one being edited with three products.
Custom zones reuse the same pattern. Learn the default zone once and you already know how custom zones work.
Edit countries panel grouped by continent with selection counts, and a version showing the error: select at least one country or region.
Country picker grouped by continent, with counts and a clear error state.
Shipping Costs page with a default zone and three custom zones, each summarizing countries, product groups and cost ranges, with edit and delete actions.
The finished setup reads as a table of where, what and how much.
Shipping cost settings page with two calculation options, use the highest shipping fee of any variant or sum shipping fees of all variants, plus a multiply-per-unit checkbox and a live example order table.
Edge cases, explained with an example. Orders with several variants can use the highest fee or the sum. A live example order shows the result before merchants save.

Two more details mattered for trust. Changes to shipping cost can be applied to past orders with one action, so historical profit stays consistent. And leaving the page with unsaved edits triggers a confirmation, so no one loses work by accident.

06Design system

Built on Shopify Polaris, so it feels native.

I built and maintained TrueProfit’s design system on top of Shopify Polaris. Merchants spend their day in Shopify admin. When an app uses the same patterns for modals, pickers and errors, there is nothing new to learn.

It also made engineering faster. The new settings used existing components with documented states, so we spent our time on logic and validation, not on pixels.

07Results

Fewer tickets, faster setup, more upgrades.

Setup time before8.0 min
Setup time after4.3 min
  • Support tickets dropped by 83%. Fewer merchants needed help to finish setup.
  • Setup time fell from 8 to 4.3 minutes. That is 46% faster.
  • Free-to-paid conversion rose by 5%. Merchants who trust their numbers are more willing to pay for them.

For an app at $119.8K monthly recurring revenue, this one redesign helped both sides of the business. It lowered support cost and raised revenue.

08What I learned

Simple isn’t fewer features. It’s the right order.

We didn’t remove a single capability. Every case from the old model still works. What changed was the order of questions and the default answer. When the default fits most people, the complex cases stop getting in everyone else’s way.

I now start every settings problem the same way. Map every case, find the question users ask first, and make the most common answer the default.