Back to 0fee
0fee

The Pricing Evolution: From Tiers to 0.99%

How 0fee.dev's pricing evolved from 3 tiers to a flat 0.99% fee with no monthly charges and infinite credit. By Juste A. Gnimavo.

Thales & Claude | March 25, 2026 8 min 0fee
pricingbusiness-modelsimplificationfeesstrategy

The pricing model for a payment platform is one of the most consequential product decisions you make. It determines who can afford to use your platform, how developers perceive your value, and ultimately whether your business survives. 0fee.dev's pricing went through three distinct phases in rapid succession -- from a standard 3-tier SaaS model to a radical simplification that removed all barriers to entry.

The entire evolution happened in three sessions across two days. This is the story of how we decided that everyone should get the same deal.

Session 013: The 3-Tier Model

The initial pricing model followed the standard SaaS playbook. Three tiers, progressively more expensive, with more features at each level:

PlanMonthly FeePer-Transaction FeeVolume LimitFeatures
Starter$02.0%$10,000/monthBasic API access, test mode, 1 app
Growth$491.5%$100,000/monthFull API, 5 apps, priority support, analytics
Scale$1990.99%UnlimitedUnlimited apps, dedicated support, SLA, custom branding

This looked reasonable. It is the model that Stripe, Paddle, and dozens of other payment platforms use (with variations). The logic is straightforward: small businesses pay less per month but more per transaction; large businesses pay more per month but less per transaction.

We implemented the full tier system:

python# models/subscription.py (Session 013 -- later deleted)
class SubscriptionTier(str, Enum):
    STARTER = "starter"
    GROWTH = "growth"
    SCALE = "scale"

TIER_CONFIG = {
    "starter": {
        "monthly_fee": 0,
        "transaction_fee_percent": 2.0,
        "volume_limit": 10_000_00,  # $10,000 in cents
        "max_apps": 1,
        "features": ["basic_api", "test_mode"],
    },
    "growth": {
        "monthly_fee": 49_00,  # $49
        "transaction_fee_percent": 1.5,
        "volume_limit": 100_000_00,
        "max_apps": 5,
        "features": ["basic_api", "test_mode", "analytics", "priority_support"],
    },
    "scale": {
        "monthly_fee": 199_00,  # $199
        "transaction_fee_percent": 0.99,
        "volume_limit": None,  # Unlimited
        "max_apps": None,  # Unlimited
        "features": ["basic_api", "test_mode", "analytics", "priority_support",
                      "sla", "custom_branding", "dedicated_support"],
    },
}

The tier determined which API features were available:

python# middleware/tier_check.py (Session 013 -- later deleted)
async def check_tier_feature(user: User, feature: str):
    tier = await get_user_tier(user.id)
    config = TIER_CONFIG[tier]

    if feature not in config["features"]:
        raise HTTPException(
            status_code=403,
            detail=f"Feature '{feature}' requires {get_required_tier(feature)} plan or higher"
        )

The Problem With Tiers

The tier model was live for three sessions (approximately 2 hours of development time) before the problems became obvious:

Problem 1: Feature gating creates artificial friction. A developer on the Starter plan who wants analytics must upgrade to Growth. They are not paying for analytics -- they are paying for a bundle that includes analytics. This feels arbitrary and punitive.

Problem 2: Volume limits punish success. A Starter user who exceeds $10,000/month must upgrade -- not because they need more features, but because they are successful. Punishing successful users with forced upgrades is adversarial.

Problem 3: The pricing page requires a comparison table. Developers visiting the pricing page must compare three plans, decide which features they need, estimate their volume, and calculate total cost. This is a decision tree. Decision trees cause abandonment.

Problem 4: The Starter tier's 2% fee is uncompetitive. At 2% per transaction, the Starter plan is more expensive than Stripe (2.9% + $0.30, but effectively less than 2% on larger transactions) for many use cases. The "free" plan is not actually attractive.

Problem 5: Africa-first means price-sensitive users. The primary market for 0fee.dev is African developers and merchants. A $49/month fee is a significant expense in countries where average developer salaries are $500-$2,000/month. The tier model effectively locks out the Africa-first market.

Session 015: The Simplification

Two sessions after implementing tiers, Thales made the call: rip it out. The new model was radical in its simplicity:

One fee: 0.99% per transaction. No monthly fees. No tiers. No volume limits. Every feature for everyone.

python# config/pricing.py (Session 015 -- still current)
PLATFORM_FEE_PERCENT = 0.99

# That is the entire pricing configuration.

The deletion was comprehensive:

python# Files deleted in Session 015:
# models/subscription.py       -- Tier definitions
# middleware/tier_check.py      -- Feature gating middleware
# routes/subscriptions.py       -- Upgrade/downgrade endpoints
# services/subscription.py      -- Tier management logic
# frontend/PricingTable.tsx     -- 3-column comparison table

The pricing page went from a 3-column comparison table to a single statement:

0.99% per transaction.
No monthly fees.
No hidden charges.
No volume limits.

Session 044: Removing Credit Limits

The simplification continued in Session 044 when credit limits were removed entirely. The original billing system had a credit limit -- users were suspended when their negative balance exceeded a threshold. This created another friction point:

python# BEFORE (Sessions 016-043): Credit limit suspension
SUSPENSION_THRESHOLD = -50_00  # Suspended at -$50

async def check_billing_status(user_id: str):
    balance = await get_user_balance(user_id)
    if balance < SUSPENSION_THRESHOLD:
        raise HTTPException(
            status_code=402,
            detail="Account suspended due to unpaid fees. Please add funds."
        )
python# AFTER (Session 044): Infinite negative balance
# No suspension check. No credit limit. No payment required to use the API.
# Users accumulate fees, and we bill monthly.

This was a bold decision. Most payment platforms require prepaid credit or immediate fee deduction. 0fee.dev allows infinite negative balance -- fees accumulate and are billed at the end of each monthly cycle.

The reasoning:

  1. Trust developers first. Requiring prepayment assumes bad faith. Most developers will pay their bills.
  2. Reduce onboarding friction. A new developer can start processing payments immediately without adding funds.
  3. Align incentives. If the developer succeeds (processes more payments), 0fee.dev succeeds (earns more fees). Suspending them for unpaid fees hurts both parties.
  4. Keep the credit risk manageable. At 0.99%, even a developer processing $100,000/month only owes $990. The credit risk is proportional to the developer's success.

The Monthly Billing Cycle

With no prepayment and no suspension, billing happens monthly:

python# services/billing.py
async def process_monthly_billing():
    """Run at the start of each month for all users."""
    users = await get_all_active_users()

    for user in users:
        cycle = await get_current_billing_cycle(user.id)

        if cycle.total_fees <= 0:
            continue  # No fees this month

        # Generate invoice
        invoice = await create_invoice(
            user_id=user.id,
            amount=cycle.total_fees,
            currency="USD",
            period_start=cycle.start_date,
            period_end=cycle.end_date,
            items=await get_fee_line_items(cycle),
        )

        # Send invoice email
        await send_invoice_email(user, invoice)

        # Start new billing cycle
        await create_new_billing_cycle(user.id)

The billing cycle tracks:

pythonclass BillingCycle(Base):
    __tablename__ = "billing_cycles"

    id = Column(String, primary_key=True)
    user_id = Column(String, ForeignKey("users.id"), nullable=False)
    start_date = Column(DateTime, nullable=False)
    end_date = Column(DateTime, nullable=False)
    total_volume = Column(Float, default=0.0)     # Total transaction volume
    total_fees = Column(Float, default=0.0)        # 0.99% of volume
    transaction_count = Column(Integer, default=0)
    status = Column(String, default="active")      # active, invoiced, paid

Every completed transaction adds to the running totals:

pythonasync def record_fee(transaction: Transaction):
    cycle = await get_current_billing_cycle(transaction.user_id)
    fee_amount = transaction.source_amount * (PLATFORM_FEE_PERCENT / 100)

    cycle.total_volume += transaction.source_amount
    cycle.total_fees += fee_amount
    cycle.transaction_count += 1

    await db.commit()

The Philosophy: Same Rules for Everyone

The pricing evolution reflects a deeper philosophy: same rules for everyone, no barriers to entry.

Traditional Platform0fee.dev
Free tier with limitationsFull access from day one
Higher tiers unlock featuresEvery feature for everyone
Volume limits force upgradesNo volume limits
Monthly fees create obligationNo monthly fees
Credit limits restrict usageInfinite credit
Suspension for unpaid feesMonthly invoicing

This philosophy is rooted in the Africa-first vision. A developer in Lagos, a merchant in Dakar, a startup in Nairobi -- they all face the same payment integration challenges. They should all get the same tools at the same price.

The Economics

Does 0.99% with no monthly fee work economically?

Example: Developer processes $50,000/month

Monthly fee:        $0
Transaction fees:   $50,000 x 0.99% = $495/month
Annual revenue:     $5,940

Under the old Growth tier:
Monthly fee:        $49
Transaction fees:   $50,000 x 1.5% = $750/month
Annual revenue:     $9,588

The flat 0.99% generates less revenue per high-volume user but removes all barriers for low-volume users. The bet is that the total addressable market expands significantly when there are zero barriers to entry -- enough to compensate for the lower per-user revenue.

For a developer processing $1,000/month (common for early-stage African startups), the difference is stark:

0fee.dev:   $1,000 x 0.99% = $9.90/month
Old Starter: $1,000 x 2.0% = $20.00/month

The developer who processes $1,000/month is exactly the developer who will process $100,000/month in two years -- if they are not priced out in the first year.

What We Learned

Simplicity is a competitive advantage. The easiest pricing page to understand is the one with one number on it. "0.99% per transaction" requires no calculator, no comparison, no decision.

Kill your tiers before they kill adoption. Tiers feel safe because they are standard. But for a new platform competing against established players, the simpler offering wins attention.

Trust your users and bill them later. Prepayment requirements and credit limits protect against a small percentage of bad actors while punishing the majority of honest users. The credit risk at 0.99% is manageable.

Price for your market. A $49/month plan designed for San Francisco developers is irrelevant to Abidjan developers. Price for the market you want to serve.

The entire pricing evolution -- from 3 tiers to flat fee to infinite credit -- took three sessions across two months. But the impact on adoption was immediate and lasting.


This article is part of the "How We Built 0fee.dev" series. 0fee.dev is a payment orchestrator covering 53+ providers across 200+ countries, built by Juste A. GNIMAVO and Claude from Abidjan with zero human engineers. Follow the series for the complete build story.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles