Steer by Profit, Not Sales
Imagine knowing what every product earns you the day it sells.
Selling many products in several markets, where returns differ from one product to the next?
A few similar products in one or two markets? Then one margin is close enough, and I'll tell you so.

Every sale's profit is clear on day one.
- Expected returns−39538% for this product in this market
- Cost of goods, on the units expected to stay sold−236landed, including duty and freight in
- Outbound fulfilment−42
- Return handling, expected−33freight back, and units that can't be sold again
- Payment fee−21
- Advertising, allocated−94this order's share of the campaign that brought it in
Every cost in its place
I bring Shopify, your accounts and ad costs together so each sale carries the costs that belong to it.
Start with what you have
You don't have to tidy your systems before we start.
No spreadsheet to keep up
Return rates for each product and country, and freight for each parcel, stay current without anyone keeping a spreadsheet.
You can use the month's earnings before the last return is settled.
A dress launched yesterday has a return rate.
You don't have to wait for a season of returns. I use the dress's type, brand, colour and size to work out what to expect in each market. Products with enough history use their own returns.
| Country | Today | Best | More a month | |
|---|---|---|---|---|
| Sweden | 499 DKK | 699 DKK | 24.000 DKK | |
| Denmark | 499 DKK | 599 DKK | 18.000 DKK | |
| Norway | 799 DKK | 899 DKK | 9.000 DKK | |
| Finland | 499 DKK | 499 DKK | 0 DKK |
Free shipping pays only if the extra orders earn enough to cover it.
Set free shipping where it pays for itself.
Your free shipping limit may work in Denmark and cost you money in Sweden. I test changes in each country and check again as you grow, since what works now may not keep working.
Free returns get the same check. A free size swap can give the customer a reason to keep the order.
It stands on every source in one place, from Numbers You Can Bet the Business On.

Put more behind products and countries that earn.
| Style | Sold | Back | Expected contribution profit | |
|---|---|---|---|---|
| Wool coat, camel | 412 | 18% | 96.000 DKK | |
| Linen shirt | 1.240 | 9% | 71.000 DKK | |
| Knit vest | 610 | 22% | 38.000 DKK | |
| Slip dress, black | 980 | 46% | 12.000 DKK | |
| Wide trousers | 530 | 51% | −8.000 DKK |
Use what each style earned to decide what your merchandiser orders next.
Each product, each country
You see what the same product earns in each market, with its own costs and expected returns.
Hear when earnings change
Slack tells you when a product or country earns more or less than you planned.
See whether growth pays
As your range and markets grow, you can tell whether extra sales are leaving you with more money.
| Country | Sold | Back | Expected contribution profit | |
|---|---|---|---|---|
| Denmark | 410 | 38% | 14.000 DKK | |
| Sweden | 290 | 48% | 4.000 DKK | |
| Norway | 160 | 52% | −3.000 DKK | |
| Germany | 120 | 58% | −3.000 DKK |
Germany's higher return rate leaves less to cover the cost of each sale.
See why Germany earns less than you expected.
A country can look healthy until you see what each product costs to sell there. The slip dress earns in Denmark, but loses money in Germany once its returns are counted.
I put the costs against each product in each market. You can see which stock deserves more ad money before you commit to growing there.
| Code or sale | Orders | Expected contribution profit | |
|---|---|---|---|
| WELCOME10 | 2.140 | 184.000 DKK | |
| Spring sale, 20% | 3.900 | 96.000 DKK | |
| Influencer codes | 1.200 | 12.000 DKK | |
| Black Friday, 40% | 5.600 | −64.000 DKK |
The discount cuts what you earn on every order the customer keeps.
Give customers a deal you can afford.
Your customers may have come to expect a sale. You still need to know how much you can take off. I measure what each code and sale earns after its costs and returns.
At Miinto, a few percentage points decided whether a campaign made money. You can compare a straight discount with a bundle that leaves you more.
| Channel | Sales | Expected contribution profit | |
|---|---|---|---|
| Your webshop | 9.170.000 DKK | 2.110.000 DKK | |
| Wholesale | 1.900.000 DKK | 305.000 DKK | |
| Boozt | 1.300.000 DKK | 260.000 DKK | |
| Zalando | 2.050.000 DKK | 205.000 DKK |
Marketplace fees come out before you compare what each channel earns.
Know where it pays to sell your stock.
Selling through a marketplace adds fees your own shop doesn't have. Wholesale has its own prices and returns. I bring those sales beside your webshop so you can compare what each leaves you.
You can use this season's earnings to price next season's wholesale line sheet, and see which marketplaces deserve more stock.
Shopify's factory price makes your profit look too high.
| Cost | The day it lands | When the bills are in |
|---|---|---|
| Goods | −312.000 DKK | −312.000 DKK |
| Freight | −18.000 DKK | −21.400 DKK |
| Duty | −39.600 DKK | −40.000 DKK |
| Currency | −4.200 DKK | −5.100 DKK |
| Each unit | −156 DKK | −158 DKK |
Orders use Shopify's costs at launch. Full unit costs follow in months two to four.
Shopify stays up to date
Each delivery updates your costs, including freight and duty.
The seasonal spreadsheet goes
I build the cost updates so you don't have to work through each delivery by hand.
Costs your accountant agrees with
Each unit's cost is worked out the way your accountant needs it and checked against your books.
The old Shopify cost made every coat sold look 131 DKK better than it was.
Price your stock before the last bill arrives.
The coat is already on sale when the freight bill arrives. If Shopify still holds the factory price, you can give too much away in a discount or spend too much on ads.
I include expected delivery costs from the day the goods land. When the bills arrive, the costs are corrected, including for units you've already sold.

Let Meta and Google bid on what you earn.
| Product | Price | Sent back | Sent to Meta | |
|---|---|---|---|---|
| Slip dress | 799 DKK | 46% | 75 DKK | |
| Wool coat | 1.999 DKK | 18% | 690 DKK | |
| Knit vest | 699 DKK | 22% | 240 DKK | |
| Linen shirt | 499 DKK | 9% | 190 DKK |
Meta gets what the order earns after costs and expected returns, before ad spend.
The country counts too
The slip dress earns less in Germany, and the value sent to Meta and Google reflects that.
Your team runs the ads
Your marketing team keeps control of the campaigns, with profit as the value to aim for.
The budget moves for you
Meta and Google shift money between ads within each campaign as orders show what earns.
- Week 1Google switches first, on the campaigns that matter least.
- Weeks 2 and 3Google learns, and sales dip as planned. Meta runs as before.
- Week 4Meta switches, once Google is back above where it was.
- Week 8Both aim at profit, and the dip is behind you.
Plan the dip before you change your ads.
Changing what Meta and Google hear means the campaigns need time to learn. We choose a quiet month and move one platform at a time, so you can plan for the dip as they enter the learning phase.
I agree the switch with your marketing team. We reset the targets in Ads Manager too, so your agency measures the campaigns on the profit they're now aiming for.
Know what you can pay for a new customer.
| Country | First order | After a year | |
|---|---|---|---|
| Denmark | 210 DKK | 640 DKK | |
| Sweden | 180 DKK | 520 DKK | |
| Norway | 170 DKK | 380 DKK | |
| Germany | 150 DKK | 310 DKK |
Repeat orders give you more room to pay for a new customer. How much room depends on where they shop.
Count what they earn later
You see what customers earn you over a year, including the orders after their first.
Set budgets country by country
Compare what customers earn by country and where they came from before you decide what to spend.
Ready for an investor's questions
If you sell the business, you can show what your customers earn you over time.
Get each market's ad budget worked out in Ads That Chase Profit.

Watch your day-one numbers get closer to the books.
- 6,1%May
- 4,3%Jun
- 2,8%Jul
- 1,4%Aug
- 0,9%Sep
Each month's check shows where the estimates need work before you use them again.
| Line | September | Owner |
|---|---|---|
| Sales | 9.170.000 DKK | E-commerce |
| Expected returns | −2.750.000 DKK | Operations |
| Cost of goods | −2.570.000 DKK | Merchandising |
| Freight and duty | −480.000 DKK | Operations |
| Payment fees | −105.000 DKK | Finance |
| Marketing | −1.155.000 DKK | Marketing |
| Expected contribution profit | 2.110.000 DKK | Founder |
Late bills get followed up
I help get bills in and booked sooner, so fewer costs have to stay as estimates.
Talk it through with me
You get a weekly call when you need one, with Slack in between.
Bookkeeping needn't hold you back
You can plan spending while the accounts catch up, with costs counted even before they're booked.
Miinto puts its ad money where the profit is
At Miinto, we knew this would pay off if we got it right. We also knew it would be hard.
Miinto sells products from many countries, to many countries. Some products earn a lot. Some earn very little. On some, it pays to spend a lot on ads. On others, almost nothing.
Many products are new, or sell only a few. So we had to learn to guess how often each one will come back. We look at what it is, like its type, brand and colour. That way a new product has its own return rate from the day it goes online. As its real returns come in, the guess gets sharper.
We used it all along, but it took about a year and a half to get it fully right. By then, our numbers matched the books, very close.
Now our ad money and the best spots on the site go where the profit is. We are better at picking which stock to push. It has added millions in gross profit.
Before, it was a rough guess, and nobody trusted it much. Now it works for every order line, and every team uses it.
Miinto is a hard case. A webshop with its own products and a few carriers is simpler. It still pays off in a big way, because you still put your ad money and your stock where the profit is. And you start from what we learned at Miinto.
None of it worked until the numbers were in order. That work is Numbers You Can Bet the Business On.
Today we build more tools on this number than on any other. How we build them is in Tools as a Service.
- +4%
more gross profit
- 35.000
DKK a month, from the day it's live
- Week 6
when it's live, by a definition we agree before we start
About 4% more gross profit, from the products, countries and costs that lose money once returns are counted. And around 15% of a typical ad budget moves from sales that lose money to what earns.
On a typical e-commerce brand already running a BI setup. A brand starting from nothing gets more.
Your data is stored in Europe, in a setup only your company uses.
Hosted in Europe
Your data, your metrics book and your tools all run on servers inside the EU.
Yours alone
No other client's data sits next to yours, and the whole setup runs in your company's name.
You decide who sees what
Each person, and each person's AI, reaches only what their job needs.
Built for a GDPR or security audit
We sign a data processing agreement before we start, and the setup is built the way auditors expect, in the EU, apart from other clients, with access set person by person.
Two exceptions, both services your team already uses. When you ask Claude or ChatGPT, the question and its answer may be handled outside the EU. And Meta and Google receive what each order earns, so they can bid on it.
Live by week 6
- Every order shows its expected contribution profit, on the cost prices in Shopify to start. Your real unit costs, freight and duty included, follow in months two to four.
- Everyone who needs it gets it through their own Claude or ChatGPT.
- After week 6, Meta and Google start getting each order's expected contribution profit, one platform at a time in a quiet month. The tool that sends it, such as Profit Metrics, runs on your own subscription.
Pay When It's Live. You pay for each part from the day it works.
Tell me which product you suspect.
Write a few lines about the business and what you can't answer today. I'll reply myself, and if it's a fit we book a call.