Subscription Service Development: Billing, Retention, Dunning

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1All 2062 services
Subscription Service Development: Billing, Retention, Dunning
Complex
from 2 weeks to 3 months
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1358
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    956
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    947

Subscription Service Development: Billing, Retention, Dunning

Many SaaS projects lose up to 30% of revenue due to unprocessed failed payments. A typical scenario: after registration, a user enters a card, goes through a trial, but a month later the payment fails — the card has expired or insufficient funds. Without dunning, the client leaves, even though they could have stayed. In this article, we will break down how to build reliable billing on Stripe Billing: from trial setup to retention mechanics that bring clients back. We will cover specific scenarios: handling past_due, configuring Smart Retries, integrating the Customer Portal, and centralized access checks. Each of these elements can reduce churn by 20–30%. Mistakes at these stages — incorrect webhook configuration, missing idempotency keys — lead to duplicate payments or missed events. We have accumulated experience from over 50 projects and are ready to share proven solutions. Our team of certified Stripe developers guarantees reliable billing architecture.

How Is the Subscription Lifecycle Structured?

Every subscription goes through states: trialingactivepast_duecancelled or activecancelled (by user action). The payment provider's webhooks notify the application of each transition. It is crucial to handle three key events:

  • invoice.payment_succeeded — activate the subscription, reset trial_end.
  • invoice.payment_failed — set status to past_due, start dunning (retry attempts).
  • customer.subscription.deleted — immediately deactivate access to paid features.

Missing even one webhook means the client retains access without payment.

What Is Dunning and How Does It Reduce Churn?

Dunning is an automated process of retrying failed payments. According to Stripe documentation, Smart Retries uses machine learning to choose the optimal time for each retry: up to 4 times within 14 days. Configuration in the Stripe dashboard:

  1. Set the maximum number of attempts (recommended 3–4).
  2. Specify the interval between attempts (daily or every other day).
  3. Enable the invoice.payment_failed webhook to send email notifications.

Parallel to this, the Stripe Customer Portal allows the client to update their payment method without your involvement. Smart Retries recovers up to 90% of failed payments — three times more effective than manual retries.

Parameter Stripe Smart Retries Manual Retries
Attempts up to 4 any number, no ML
Timing ML chooses fixed interval
Email notifications via Portal custom implementation
Payment recovery up to 90% ~30%

Free Trial Period: With or Without Card?

Parameter Trial without card Trial with card
Registration friction Low High
Conversion to paying Lower (~50%) Higher (~80%)
Fraud risk Higher Lower
Recommendation B2C, viral products B2B SaaS

Thus, trial with card is 1.6 times more effective for conversion (80% vs 50%).

For B2B SaaS, trial with card is recommended. For B2C and viral products, trial without card.

Upgrade/Downgrade: Instant Plan Change

Plan changes should be instant and account for the already paid period. Stripe handles this via proration:

await stripe.subscriptions.update(subscriptionId, {
  items: [{ id: itemId, price: 'price_premium_monthly' }],
  proration_behavior: 'create_prorations',
});

On upgrade, the difference for the remaining days of the period is charged. On downgrade, the difference is credited.

Which Retention Mechanics Actually Work?

  • Cancellation flow: instead of a "Cancel" button — a dialog with clarifying questions ("Why are you leaving?"), offering a pause (1–3 months) or a discount.
  • Email campaigns: a series of emails on past_due, at trial end without conversion, after 30/60/90 days post-cancellation.
  • Win-back offers: special offers for canceled users.

These mechanics recover up to 20% of canceled subscriptions. For example, at a churn of 5% and ARPU of $200, proper dunning configuration can recover up to $9,000 per month.

Typical Mistakes in Subscription Integration
  1. Unhandled past_due — webhooks for failed payments not configured, client is lost.
  2. Missing proration — no proportional credit on plan change, billing out of sync.
  3. Scattered access checks — instead of a centralized Gate, checks are spread across controllers.
  4. Ignoring webhook idempotency — duplicate notifications from Stripe can cause double activation.

What Is Included in the Work on a Subscription Service?

The final project includes:

  • Documentation on billing architecture and API.
  • Access to the Stripe account and test cards.
  • Training your team on billing operations.
  • Support for 30 days after launch.

Work Process

  • Requirements analysis and tariff grid design
  • Stripe Billing integration (webhooks, portal, proration)
  • Implementation of registration, trial, upgrade/downgrade, dunning
  • Retention mechanics (cancellation flow, email campaigns)
  • API and architecture documentation
  • Testing of payment flow and cancellation scenarios
  • Support and refinements after launch
  • Training your team on billing operations

Timelines and Cost

A web service with subscription via Stripe (registration, trial, upgrade/downgrade, portal, basic webhooks): from 2 to 3 months. With extended tariffs, teams, dunning, and analytics: from 3 to 5 months. Cost is calculated individually based on complexity and required stack.

Order development of reliable subscription billing — from tariff design to retention mechanics. Get a consultation for your project.

What Does SaaS Platform Development Involve? Multi-Tenancy, Billing, and Beyond

We know this pain by heart. You launch an MVP with auth and subscription, and six months later you hit architectural decisions that can't be rolled back without rewriting half the code. Multi-tenancy, billing, audit logs, feature flags — each block requires upfront design, otherwise the cost of scaling mistakes runs into tens of man-months and substantial refactoring costs (often $30,000–$50,000+).

Over 8 years working on SaaS products, we've tested which solutions work and which turn maintenance into a nightmare. Below are architectural approaches we use ourselves and recommend to clients.

How we build multi-tenancy: isolation without overhead

The first decision is the data separation scheme. Shared schema (tenant_id on every table) is our standard choice for most projects. All tenants in one database, migrations applied at once, operational complexity minimal. In Laravel we implement it via Global Scope:

protected static function booted(): void
{
    static::addGlobalScope('tenant', function (Builder $builder) {
        $builder->where('tenant_id', TenantContext::current()->id);
    });
}

The global scope is only the first line of defense. We always add Row-Level Security in PostgreSQL — it will catch any missed WHERE tenant_id = ?:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders
    USING (tenant_id = current_setting('app.tenant_id')::uuid);

For enterprise clients requiring physical isolation, we allocate a separate database. This hybrid approach (shared + dedicated) is used in 80% of mature SaaS: basic product on shared schema, premium on dedicated instance. We implement it from the first sprint to avoid rewriting logic later. Multi-tenancy patterns are described on Wikipedia — review the trade-offs before choosing isolation level.

Why Is Billing the Most Underestimated Block?

Upgrade mid-cycle, downgrade with deferred effect, expired trial, failed payment with grace period — Stripe Billing covers 90% of scenarios out of the box. We always process webhooks (customer.subscription.updated, invoice.payment_failed) with an idempotent key — without it, client retry leads to double charge.

For CIS markets — YooKassa or Tinkoff recurring. Their APIs are less convenient but cover 54-FZ requirements.

Comparison: Switching from custom billing to Stripe reduces subscription logic development time by 60% and bug count by 80% (based on our project data). That translates to $15,000–$25,000 savings on a typical SaaS MVP.

Onboarding: how not to lose the user before aha-moment

Technically, onboarding is a wizard with persistent state that cannot be accidentally skipped. Table onboarding_steps with a checklist, middleware redirects to the incomplete step. After completion — a flag in user settings, middleware disabled.

Critical nuance: show real product progress, not abstract steps. "Create your first report" instead of "Complete step 3 of 5." We use drip campaigns via Customer.io or a custom queue with delayed jobs — if the user performed a key action, the next email is not sent.

How to Implement Feature Flags and Access Control?

SaaS with plans requires granular control. Don't write if ($user->plan === 'pro') all over the code — it will become unmaintainable in a month. Instead:

  • Backend: Gate + Policy with checks via features table linked to plans.
  • Frontend: context with flags loaded at app initialization.
  • Open-source tools: Unleash or Growthbook — UI for A/B testing and rollout.

Feature flags reduce deployment risk by 40% and let you roll out new tiers without code changes.

How to Protect API from Aggressive Clients?

Rate limiting is a must for public API. One client can bring down all others. In Laravel we use Redis with sliding window counter:

Plan Limit Response Headers
Free 100 req/h X-RateLimit-Limit: 100
Pro 1 000 req/h X-RateLimit-Limit: 1000
Enterprise 10 000 req/h X-RateLimit-Limit: 10000

Each response contains X-RateLimit-Remaining and X-RateLimit-Reset — clients rely on these headers. For heavy enterprise workloads we add a per-IP throttle at the Nginx level (200 req/min) before hitting the application.

Audit Logs and Monitoring: What, Who, and When?

Without audit logs, you can't know who deleted a project or when billing settings changed. Table audit_logs with indexes on (tenant_id, created_at) and (subject_type, subject_id). In Laravel — Observers on key models.

Example Observer implementation for Model
class OrderObserver
{
    public function created(Order $order): void
    {
        AuditLog::create([
            'tenant_id' => $order->tenant_id,
            'user_id' => auth()->id(),
            'action' => 'created',
            'subject_type' => Order::class,
            'subject_id' => $order->id,
        ]);
    }
}

Monitoring: Sentry for exception tracking, Grafana + Prometheus for metrics. Alerts on error rate > 5% and response time p95 > 2s. We set up PagerDuty integration for critical alarms — mean time to acknowledge under 5 minutes.

Our Team's Experience and Guarantees

Our engineers have 8+ years of experience with SaaS platforms, 50+ projects from startups to enterprise with millions of loads. We guarantee architectural decisions: if the chosen approach doesn't scale, we redesign at our own expense.

Deliverables and Guarantees

  • Architecture documentation: diagrams, ERD, sequence diagrams.
  • CI/CD setup (GitHub Actions / GitLab CI).
  • Access to repository, staging, and production.
  • Team training: 2–3 sessions on code review and runbook.
  • Post-launch support for 1 month.
  • Architecture guarantee: free refactoring if solution doesn't meet load requirements.

Work Process

  1. Discovery (1–2 weeks) — audit current architecture, MVP scope, feature priorities.
  2. Design (1 week) — stack selection, multi-tenancy scheme, billing plan.
  3. Development (4–12 weeks) — 2-week sprints, demo after each.
  4. Testing (1 week) — load tests under target load, security audit.
  5. Deployment and training (1 week) — rollout, monitoring setup, documentation handover.

Timeline Estimates

Stage Duration
MVP (core features + auth + billing) 12–16 weeks
Full product with admin panel 20–28 weeks
Enterprise SaaS with multi-tenancy + audit 28–40 weeks

Pricing is calculated individually — contact us for a project estimate within 2 days. Order turnkey development: from design to deployment with architecture guarantee. Get a consultation on your product architecture — first hour free.