Skip to main content

Overview

Pricing is one of the most important decisions for your SaaS business. This guide covers common pricing strategies and how to implement them using Eufaturo Billing.

Common Pricing Models

Good-Better-Best (3-Tier Pricing)

The most common SaaS pricing structure with three tiers:
use Eufaturo\Billing\Billing;
use Eufaturo\Billing\ProductPlans\Enums\Interval;
use Eufaturo\Billing\ProductPlans\Enums\ProductPlanType;

$usd = Billing::currencies()->find('USD');

// BASIC - Entry point
$basic = Billing::products()->create(
    name: 'Basic',
    description: 'For individuals just getting started',
    isVisible: true,
);

Billing::plans()->create(
    product: $basic,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Basic Monthly',
    slug: 'basic-monthly',
    isActive: true,
    price: 900, // $9/month
    interval: Interval::Monthly,
    intervalCount: 1,
);

// PRO - Most popular (anchor pricing)
$pro = Billing::products()->create(
    name: 'Professional',
    description: 'For growing teams and businesses',
    isVisible: true,
    isPopular: true, // Highlight this tier
    isDefault: true, // Pre-select in UI
);

Billing::plans()->create(
    product: $pro,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Pro Monthly',
    slug: 'pro-monthly',
    isActive: true,
    price: 2900, // $29/month (3.2x Basic)
    interval: Interval::Monthly,
    intervalCount: 1,
);

// ENTERPRISE - High-value customers
$enterprise = Billing::products()->create(
    name: 'Enterprise',
    description: 'For large organizations with custom needs',
    isVisible: true,
);

Billing::plans()->create(
    product: $enterprise,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Enterprise Monthly',
    slug: 'enterprise-monthly',
    isActive: true,
    price: 9900, // $99/month (3.4x Pro)
    interval: Interval::Monthly,
    intervalCount: 1,
);
Why It Works:
  • ✅ Covers wide range of customers
  • ✅ Middle tier captures most conversions
  • ✅ Enterprise tier increases perceived value
  • ✅ Simple for customers to understand
Pricing Ratios:
  • Basic to Pro: ~3-4x
  • Pro to Enterprise: ~3-4x

Monthly vs Yearly Discount

Incentivize annual commitments with discounts:
$pro = Billing::products()->find('pro');
$usd = Billing::currencies()->find('USD');

// Monthly plan - full price
$monthly = Billing::plans()->create(
    product: $pro,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Pro Monthly',
    slug: 'pro-monthly',
    isActive: true,
    price: 2900, // $29/month
    interval: Interval::Monthly,
    intervalCount: 1,
);

// Yearly plan - 17% discount
$yearly = Billing::plans()->create(
    product: $pro,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Pro Yearly',
    slug: 'pro-yearly',
    isActive: true,
    price: 29000, // $290/year ($24.17/month)
    interval: Interval::Yearly,
    intervalCount: 1,
    description: 'Save 17% with annual billing',
    trialInterval: Interval::Daily,
    trialIntervalCount: 14,
);
Common Annual Discounts:
  • 10% off: Good starting point
  • 15-20% off: Industry standard
  • 25%+ off: Aggressive (use for B2B or high-value products)
Calculate Discount:
$monthlyPrice = 2900; // $29
$annualPrice = $monthlyPrice * 12 * 0.83; // 17% off
// $annualPrice = 29000 ($290/year)

// Verify discount percentage
$discount = (1 - ($annualPrice / ($monthlyPrice * 12))) * 100;
// $discount = 17%

Usage-Based Pricing

Charge based on consumption:
$api = Billing::products()->create(
    name: 'API Access',
    description: 'Pay only for what you use',
);

// Base fee + per-unit pricing
$usagePlan = Billing::plans()->create(
    product: $api,
    currency: $usd,
    type: ProductPlanType::UsageBased,
    name: 'Pay-as-you-go',
    slug: 'api-usage',
    isActive: true,
    price: 1000, // $10/month base
    pricePerUnit: 10, // $0.10 per API call
    interval: Interval::Monthly,
    intervalCount: 1,
);

// Total bill = base + (usage * pricePerUnit)
// Example: $10 + (1,000 calls * $0.10) = $110
Best For:
  • API services
  • Cloud storage
  • SMS/email sending
  • Video transcoding
  • Any metered usage
Pricing Formula:
Total = BasePrice + (UnitsConsumed × PricePerUnit)

Freemium

Free tier with paid upgrades:
// Free tier (create as $0 plan)
$free = Billing::products()->create(
    name: 'Free',
    description: 'Basic features, forever free',
    isVisible: true,
);

$freePlan = Billing::plans()->create(
    product: $free,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Free Forever',
    slug: 'free',
    isActive: true,
    price: 0, // $0/month
    interval: Interval::Monthly,
    intervalCount: 1,
);

// Paid tiers for upgrades
$pro = Billing::products()->create(
    name: 'Pro',
    description: 'Unlock all features',
    isVisible: true,
);

$proPlan = Billing::plans()->create(
    product: $pro,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Pro',
    slug: 'pro',
    isActive: true,
    price: 1900, // $19/month
    interval: Interval::Monthly,
    intervalCount: 1,
);
Freemium Strategy:
  • Free tier: Limited features/usage
  • Paid tier: Remove limits + premium features
  • Conversion rate: Typically 2-5% of free users

Per-Seat Pricing

Charge per user/team member:
// You handle the quantity in your subscription logic
$perSeat = Billing::products()->create(
    name: 'Team',
    description: 'Per user pricing',
);

$teamPlan = Billing::plans()->create(
    product: $perSeat,
    currency: $usd,
    type: ProductPlanType::FlatRate,
    name: 'Team Plan',
    slug: 'team-per-seat',
    isActive: true,
    price: 1500, // $15 per seat/month
    interval: Interval::Monthly,
    intervalCount: 1,
);

// When creating subscription, store quantity
// Total = price × quantity
// Example: 5 seats × $15 = $75/month
Implementation:
// Store seat count in subscription metadata
$subscription->metadata = [
    'seats' => 5,
    'price_per_seat' => 1500,
];

// Calculate total
$total = $teamPlan->price * $subscription->metadata['seats'];
// $total = 7500 ($75.00)

Psychological Pricing Tactics

Charm Pricing (9vs9 vs 10)

Prices ending in 9 convert better:
// ✅ Better conversion
price: 2900, // $29
price: 9900, // $99

// ❌ Lower conversion
price: 3000, // $30
price: 10000, // $100

Anchor Pricing

Make one tier look like the best value:
<div class="pricing-grid">
    {{-- Basic: $19/mo --}}
    <div class="tier">
        <h3>Basic</h3>
        <p class="price">$19<span>/mo</span></p>
    </div>

    {{-- Pro: $49/mo - HIGHLIGHTED --}}
    <div class="tier popular">
        <span class="badge">Most Popular</span>
        <h3>Pro</h3>
        <p class="price">$49<span>/mo</span></p>
        <p class="savings">Save 20% vs monthly</p>
    </div>

    {{-- Enterprise: $199/mo --}}
    <div class="tier">
        <h3>Enterprise</h3>
        <p class="price">$199<span>/mo</span></p>
    </div>
</div>
The “Most Popular” badge and design emphasis drives conversions to the middle tier.

Trial Strategies

Trial Length

Longer trials = higher conversion for complex products:
// Simple product (7-day trial)
Billing::plans()->create(
    // ...
    trialInterval: Interval::Daily,
    trialIntervalCount: 7,
);

// Complex product (14-day trial)
Billing::plans()->create(
    // ...
    trialInterval: Interval::Daily,
    trialIntervalCount: 14,
);

// Enterprise/B2B (30-day trial)
Billing::plans()->create(
    // ...
    trialInterval: Interval::Daily,
    trialIntervalCount: 30,
);
Guidelines:
  • 7 days: Simple tools, quick value
  • 14 days: Standard SaaS
  • 30 days: Complex/B2B products

Credit Card Upfront vs No Credit Card

// Require credit card upfront (higher conversion)
// - Better quality leads
// - Lower trial abuse
// - Higher conversion rate

// No credit card required (higher trial signups)
// - More trial signups
// - Lower conversion rate
// - More trial abuse
Recommendation: Require credit card for B2B, optional for B2C.

International Pricing

Currency-Based Pricing

Adjust prices for local markets:
$pro = Billing::products()->find('pro');

// US pricing
$usd = Billing::currencies()->find('USD');
Billing::plans()->create(
    product: $pro,
    currency: $usd,
    // ...
    price: 2900, // $29
);

// European pricing (slightly lower)
$eur = Billing::currencies()->find('EUR');
Billing::plans()->create(
    product: $pro,
    currency: $eur,
    // ...
    price: 2700, // €27
);

// Emerging markets (lower prices)
$inr = Billing::currencies()->find('INR');
Billing::plans()->create(
    product: $pro,
    currency: $inr,
    // ...
    price: 149900, // ₹1,499 (~$18 equivalent)
);
Pricing Parity (PPP):
  • Adjust prices based on local purchasing power
  • US: 100% (baseline)
  • EU: 90-95%
  • Emerging markets: 50-70%

Real-World Examples

GitHub Pricing

// Free tier
$free = Billing::products()->create(name: 'Free');
$freePlan = Billing::plans()->create(
    product: $free,
    // ...
    price: 0,
);

// Team tier
$team = Billing::products()->create(name: 'Team');
$teamPlan = Billing::plans()->create(
    product: $team,
    // ...
    price: 400, // $4 per user/month
);

// Enterprise tier
$enterprise = Billing::products()->create(name: 'Enterprise');
$enterprisePlan = Billing::plans()->create(
    product: $enterprise,
    // ...
    price: 2100, // $21 per user/month
);

Stripe Pricing

// Usage-based with volume discounts
$stripe = Billing::products()->create(name: 'Stripe Payments');
$stripePlan = Billing::plans()->create(
    product: $stripe,
    // ...
    type: ProductPlanType::UsageBased,
    price: 0, // No monthly fee
    pricePerUnit: 29, // 2.9% + $0.30 per transaction
);

Netflix Pricing

// Good-Better-Best
$basic = Billing::products()->create(name: 'Basic');
$basicPlan = Billing::plans()->create(product: $basic, price: 999); // $9.99

$standard = Billing::products()->create(name: 'Standard');
$standardPlan = Billing::plans()->create(product: $standard, price: 1549); // $15.49

$premium = Billing::products()->create(name: 'Premium');
$premiumPlan = Billing::plans()->create(product: $premium, price: 1999); // $19.99

Testing Your Pricing

A/B Testing Prices

Create multiple plans to test:
// Control group
$control = Billing::plans()->create(
    name: 'Pro (Control)',
    slug: 'pro-control',
    price: 2900, // $29
    // ...
);

// Test group (10% higher)
$test = Billing::plans()->create(
    name: 'Pro (Test)',
    slug: 'pro-test',
    price: 3200, // $32
    // ...
);

// Randomly assign in your controller
$plan = rand(0, 1) === 0 ? $control : $test;

Metrics to Track

// Conversion rate
$conversionRate = $paidSubscriptions / $trialSignups * 100;

// Revenue per user
$arpu = $totalRevenue / $totalUsers;

// Customer lifetime value
$ltv = $averageMonthlyRevenue * $averageLifetimeMonths;

Best Practices

✅ Do

  • Start simple - 2-3 tiers maximum initially
  • Test pricing - A/B test before finalizing
  • Show annual savings - Highlight discount percentage
  • Grandfather existing customers - Keep them on old pricing
  • Be transparent - No hidden fees
  • Offer trials - Especially for annual plans

❌ Don’t

  • Change prices frequently - Creates distrust
  • Surprise customers - Communicate price changes early
  • Undervalue your product - Don’t race to bottom
  • Overcomplicate - Too many tiers confuse customers
  • Forget about churn - Monitor cancellation rates
  • Ignore feedback - Listen to “too expensive” complaints

Next Steps


Further Reading