DEV Community

Cover image for Pricing your first digital product: a tiny Python calculator for fees, break-even and platform choice
Revenue Operator
Revenue Operator

Posted on

Pricing your first digital product: a tiny Python calculator for fees, break-even and platform choice

"What should I charge?" is the question that stalls a lot of first digital products: templates, ebooks, Notion setups, starter kits. Part of the answer is about positioning and the buyer, which no script can do for you. The other part is plain arithmetic that most people skip:

  • How much of each sale do I keep after platform and payment fees?
  • How many sales does it take to cover my monthly costs?
  • At what volume does a monthly-subscription platform beat a percentage-fee one?

That arithmetic fits in about 100 lines of Python with no dependencies. Here's the script, how the fee models work, and what the output tells you.

The fee models (and why they differ)

Selling platforms charge in one of three ways:

  1. A percentage plus a fixed fee per sale. The fixed part ($0.30–$0.80) matters a lot at low prices: on a $5 product it can be 6–16% on its own.
  2. A flat percentage per sale. Simple, but often high when the platform also brings you the buyer (marketplace sales).
  3. A monthly subscription with 0% platform fee. You still pay card processing. It's cheaper once you sell enough, and you pay it even in months you sell nothing.

These are the list prices we used for a standard domestic card sale, checked in October 2026:

Platform Per-sale fees Monthly
Gumroad, direct sale 10% + $0.50, plus 2.9% + $0.30 processing $0
Gumroad, Discover (marketplace) sale flat 30% $0
Lemon Squeezy 5% + $0.50 (more for international cards and PayPal) $0
Polar, organizations created from May 27, 2026 5% + $0.50 $0
Payhip Free / Plus / Pro 5% / 2% / 0%, plus Stripe or PayPal fees $0 / $29 / $99
Ko-fi Free / Gold 5% / 0%, plus processor fees $0 / $12
Etsy 6.5% transaction + 3% + $0.25 processing + $0.20 listing $0
Stan Store Creator 0%, plus Stripe fees $29

Two caveats. These numbers change, so the script keeps them in one list you can edit. And they aren't like-for-like: Gumroad, Lemon Squeezy and Polar act as merchant of record, which means they handle sales tax and VAT for you, and Etsy collects US sales tax as a marketplace facilitator. With platforms that only process payments, tax compliance is your job. A slightly higher fee can still be the cheaper option once your own time is counted.

The script

#!/usr/bin/env python3
"""price_calc.py: what you keep per sale, break-even, and the cheapest platform.

Usage:
  python price_calc.py 27                     # compare platforms at $27
  python price_calc.py 27 --costs 40          # + break-even with $40/month in other costs
  python price_calc.py 27 --sales 50          # monthly totals at 50 sales/month
  python price_calc.py --sweep 9 19 27 39 49  # net per sale across price points

Fee models are public list prices (USD, standard domestic card sale) checked
Oct 2026. They change, so re-check before you rely on them.
Python 3.10+, standard library only.
"""
import argparse
import math
from dataclasses import dataclass

STRIPE_PCT, STRIPE_FIXED = 0.029, 0.30  # standard US card processing


@dataclass
class Platform:
    name: str
    pct: float           # percentage fee per sale (platform + processing)
    fixed: float         # fixed fee per sale
    monthly: float = 0.0 # subscription cost per month

    def net(self, price: float) -> float:
        return price - price * self.pct - self.fixed


PLATFORMS = [
    Platform("Gumroad (direct sale)",   0.10 + 0.029, 0.50 + 0.30),
    Platform("Gumroad (Discover sale)", 0.30,         0.0),
    Platform("Lemon Squeezy",           0.05,         0.50),
    Platform("Polar (new orgs)",        0.05,         0.50),
    Platform("Payhip Free",             0.05 + STRIPE_PCT, STRIPE_FIXED),
    Platform("Payhip Plus",             0.02 + STRIPE_PCT, STRIPE_FIXED, 29),
    Platform("Payhip Pro",              STRIPE_PCT,        STRIPE_FIXED, 99),
    Platform("Ko-fi Free",              0.05 + STRIPE_PCT, STRIPE_FIXED),
    Platform("Ko-fi Gold",              STRIPE_PCT,        STRIPE_FIXED, 12),
    Platform("Etsy (incl. listing fee)",0.065 + 0.03,      0.25 + 0.20),
    Platform("Stan Creator",            STRIPE_PCT,        STRIPE_FIXED, 29),
]


def break_even(p: Platform, price: float, other_costs: float) -> float:
    """Sales per month needed to cover the subscription + your other costs."""
    per_sale = p.net(price)
    if per_sale <= 0:
        return math.inf
    return math.ceil((p.monthly + other_costs) / per_sale)


def crossover(a: Platform, b: Platform, price: float) -> float | None:
    """Monthly sales above which a (higher subscription) beats b."""
    gain = a.net(price) - b.net(price)
    extra = a.monthly - b.monthly
    if gain <= 0:
        return None
    return math.floor(extra / gain) + 1


def compare(price: float, costs: float, sales: int | None) -> None:
    print(f"\nPrice ${price:.2f}" + (f", other costs ${costs:.0f}/mo" if costs else ""))
    head = f"{'Platform':<26}{'Keep/sale':>10}{'Keep %':>8}{'Sub/mo':>8}{'Break-even':>12}"
    if sales:
        head += f"{f'Net @ {sales}/mo':>14}"
    print(head)
    print("-" * len(head))
    if sales:  # rank by what you keep in a month at that volume
        rows = sorted(PLATFORMS, key=lambda p: -(p.net(price) * sales - p.monthly))
    else:      # rank by what you keep per sale
        rows = sorted(PLATFORMS, key=lambda p: (-round(p.net(price), 2), p.monthly))
    for p in rows:
        n = p.net(price)
        be = break_even(p, price, costs)
        line = f"{p.name:<26}{n:>10.2f}{n / price:>8.1%}{p.monthly:>8.0f}{be:>12}"
        if sales:
            line += f"{n * sales - p.monthly:>14.2f}"
        print(line)


def sweep(prices: list[float]) -> None:
    keys = ["Gumroad (direct sale)", "Lemon Squeezy", "Payhip Free", "Etsy (incl. listing fee)"]
    ps = [p for p in PLATFORMS if p.name in keys]
    print(f"\n{'Price':>7}" + "".join(f"{p.name.split(' (')[0]:>15}" for p in ps))
    for price in prices:
        print(f"{price:>7.2f}" + "".join(f"{p.net(price):>15.2f}" for p in ps))


if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("price", type=float, nargs="?", default=27)
    ap.add_argument("--costs", type=float, default=0, help="other monthly costs ($)")
    ap.add_argument("--sales", type=int, help="expected sales per month")
    ap.add_argument("--sweep", type=float, nargs="+", help="list of prices to compare")
    a = ap.parse_args()
    if a.sweep:
        sweep(a.sweep)
    else:
        compare(a.price, a.costs, a.sales)
        by = {p.name: p for p in PLATFORMS}
        x = crossover(by["Stan Creator"], by["Lemon Squeezy"], a.price)
        y = crossover(by["Payhip Plus"], by["Payhip Free"], a.price)
        print(f"\nStan Creator beats Lemon Squeezy above {x} sales/mo at this price.")
        print(f"Payhip Plus beats Payhip Free above {y} sales/mo at this price.")
Enter fullscreen mode Exit fullscreen mode

The core is one line: net = price - price * pct - fixed. Everything else is a loop over platforms:

  • Break-even: ceil((subscription + other_costs) / net_per_sale), the number of sales per month that covers the platform subscription plus whatever else you pay for (domain, email tool, ads budget).
  • Crossover: subscription plans charge more per month but less per sale. Plan A beats plan B once sales × (netA − netB) > subA − subB. The script prints the first whole number of sales where that's true.

What it prints

At $27 with $40/month of other costs (python price_calc.py 27 --costs 40):


Price $27.00, other costs $40/mo
Platform                   Keep/sale  Keep %  Sub/mo  Break-even
----------------------------------------------------------------
Ko-fi Gold                     25.92   96.0%      12           3
Stan Creator                   25.92   96.0%      29           3
Payhip Pro                     25.92   96.0%      99           6
Payhip Plus                    25.38   94.0%      29           3
Lemon Squeezy                  25.15   93.1%       0           2
Polar (new orgs)               25.15   93.1%       0           2
Payhip Free                    24.57   91.0%       0           2
Ko-fi Free                     24.57   91.0%       0           2
Etsy (incl. listing fee)       23.98   88.8%       0           2
Gumroad (direct sale)          22.72   84.1%       0           2
Gumroad (Discover sale)        18.90   70.0%       0           3

Stan Creator beats Lemon Squeezy above 38 sales/mo at this price.
Payhip Plus beats Payhip Free above 36 sales/mo at this price.
Enter fullscreen mode Exit fullscreen mode

A few things to notice:

  • The gap between platforms is real but not dramatic at this price. It's $22.72 against $25.15 per sale for Gumroad direct versus Lemon Squeezy, about $2.43. That matters at volume, but it shouldn't be the reason you delay launching. Pick one, ship, and switch later if the numbers justify it.
  • Marketplace sales cost more, and that can be fine. A Gumroad Discover sale keeps 70%, but it's a buyer you didn't have to find. Treat that 30% as a customer-acquisition cost, not as a fee to minimize.
  • Subscriptions are a bet on volume. At $27, Stan's $29/month beats Lemon Squeezy only above 38 sales a month, and Payhip Plus beats Payhip Free above 36. Below that, a $0/month plan keeps more. Start on a free plan and move once your actual numbers (not hoped-for ones) cross the line.
  • Break-even is small at this price. At $27 and $40/month in costs, 2–3 sales cover the month on most platforms. That makes your break-even a traffic and conversion question, not a pricing one.

Low prices get hit hardest by fixed fees

python price_calc.py --sweep 9 19 27 39 49 shows what you keep per sale across price points:


  Price        Gumroad  Lemon Squeezy    Payhip Free           Etsy
   9.00           7.04           8.05           7.99           7.69
  19.00          15.75          17.55          17.20          16.75
  27.00          22.72          25.15          24.57          23.98
  39.00          33.17          36.55          35.62          34.84
  49.00          41.88          46.05          44.83          43.89
Enter fullscreen mode Exit fullscreen mode

On Gumroad direct you keep about 78% at $9 and about 85% at $49, because the $0.80 fixed portion is a bigger share of a small price. Combined with the fact that a $9 product needs three times the buyers of a $27 one to earn the same, this is the strongest arithmetic argument against pricing your first product at "impulse" levels by default. Whether a higher price sells is a separate question, and only a launch answers it.

Bonus: work backwards from what you want to keep

If you know you want $25 per sale after fees, invert the formula: price = (target + fixed) / (1 − pct).

import math
from price_calc import PLATFORMS

def price_for_net(p, target):
    return math.ceil((target + p.fixed) / (1 - p.pct) * 100) / 100

for p in PLATFORMS:
    print(f"{p.name:<26} ${price_for_net(p, 25):.2f}")
Enter fullscreen mode Exit fullscreen mode

To keep $25 you'd charge $26.85 on Lemon Squeezy, $28.13 on Etsy, $29.63 on Gumroad direct and $35.72 for a Gumroad Discover sale. Round to whatever price looks right to buyers. The script just tells you which side of the line you're on.

Extending it

  • Add your own platform by appending a Platform(...) line. For international buyers on Lemon Squeezy, add 0.015 to pct (and another 0.015 for PayPal).
  • Add a refund-rate argument and multiply net by (1 − refund_rate).
  • Put the PLATFORMS list in a JSON file so a non-developer co-founder can update fees.

Wrapping up

The calculator won't tell you what your product is worth to a buyer. That comes from validation and the first few sales. What it does is turn "which platform?" and "is $9 too cheap?" into numbers you can check in a few seconds and stop worrying about.

If fees on any of these platforms have changed since we checked, please mention it in the comments and we'll update the table.

Sources (checked October 2026): Gumroad fees · Lemon Squeezy fees · Polar fees · Payhip pricing · Ko-fi pricing · Etsy fees · Stan Store pricing


Disclosure: this article is from Revenue Operator. We make the 30-Day Revenue Operator Pack, a $27 playbook for picking, pricing and launching a first digital product, with templates and trackers. Everything above works without it, and there's a free 6-page guide here: getrevenueoperator.com/free. We also keep a longer platform fee comparison on our blog: Gumroad alternatives in 2026.

Top comments (0)