Navigation

How to Add Stripe Subscriptions to Your .NET SaaS App

How to Add Stripe Subscriptions to Your .NET SaaS App

Subscription billing is the backbone of modern SaaS—revenue, retention, and customer trust all depend on getting this right. Stripe, with its powerful APIs and deep .NET support, is the industry standard. This guide gives you a step-by-step blueprint for building robust subscription billing into your .NET SaaS, minimizing launch risk and maximizing conversion.

Why Stripe Is the SaaS Gold Standard

Stripe delivers:

  • PCI compliance out-of-the-box (you never handle card numbers)
  • Prebuilt checkout, subscription, invoices, receipts, and full API
  • Global payments, flexible pricing, deep fraud checks
  • Support for upgrades, coupons, trials, metered billing, and more
  • Rich webhooks and docs; great test environment for every use case

Don’t want Stripe? Paddle, Braintree, and Adyen are SaaS alternatives, but for breadth of features and ecosystem, Stripe remains first choice for most .NET SaaS teams.


Step 1: Set Up Your Stripe Account and Pricing

  1. Register at Stripe Dashboard. Work in "Test" mode before going live.
  2. Define your core pricing structure:
    • Create products for each SaaS plan (monthly/yearly, tiers, seat-based, free trials, etc.)
    • Set up prices (USD, EUR, etc.), attach features to plans.
  3. For B2B SaaS: model plans for both flat-rate and seat-based subscriptions. Stripe supports both.

Step 2: Install and Configure Stripe.NET in Your Project

  • Install the official package:
Install-Package Stripe.net
  • Add your API keys via environment (never hardcode!):
{
  "Stripe": {
    "ApiKey": "sk_test_...",
    "WebhookSecret": "whsec_..."
  }
}
  • Register and inject Stripe services in your .NET DI container. Inject config with IOptions<StripeConfig>. All sensitive values from env or user secrets.

Step 3: Implementing the Stripe Checkout Flow

  • Use Stripe Checkout to handle the entire payment UI (security, PCI, SCA, fraud checks, etc.):
  • Create a Checkout Session when a user chooses a plan:
var session = await new SessionService().CreateAsync(new SessionCreateOptions {
  PaymentMethodTypes = new List<string> { "card" },
  LineItems = new List<SessionLineItemOptions> {
    new() {
      Price = "price_123...", // from Stripe Dashboard
      Quantity = 1,
    },
  },
  Mode = "subscription",
  SuccessUrl = domain + "/account?success=true",
  CancelUrl = domain + "/pricing?canceled=true"
});
  • Redirect users to session URL, handle callback on completion/cancel.
  • Use the session completion hook (see webhooks below) to grant or rescind app access.

Step 4: Managing Subscription Lifecycle with Webhooks

  • Webhooks: The only way to guarantee your app stays in sync with Stripe!
  • Listen for events:
    • invoice.paid, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, payment_failed
  • Example controller endpoint:
[HttpPost("/stripe/webhook")]
public async Task<IActionResult> StripeWebhook() {
    var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
    var stripeEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], webhookSecret);
    if (stripeEvent.Type == Events.CustomerSubscriptionCreated) {
        // Update user access, notify, etc.
    }
    // ...more event handling
    return Ok();
}
  • Keep idempotency: Check your DB for whether you processed this event already. Stripe may resend events multiple times.
  • Always handle upgrades, downgrades, cancellations, failed renewals—notify users the moment there is trouble!

Step 5: UX, Testing, and Final Checklist Before Launch

  • Show clear pricing, renewal period, and "what’s included" on all user flows.
  • Email confirmations immediately after new subscriptions or plan changes.
  • Let users easily:
    • Update card or payment source
    • Cancel or resume subscriptions
    • View receipts
    • Apply discounts/coupons
  • Test ALL payment flows:
    • Signups, renewals, failures/declines, upgrades/downgrades, cancellations
    • Use test cards
  • Ensure “subscription status” in your app always mirrors Stripe’s status, in code and UX.
  • Simulate webhook/failure events using Stripe’s dashboard tools (and in automated integration tests if possible).

Reliability and Dunning for SaaS

  • Grace periods: Allow users a grace window after payment failures to update their card, before cutting access
  • Dunning: Schedule email/alert reminders for failed payments, with increasing urgency
  • Ensure refunds/cancellations are reflected immediately in access control

Metrics, Compliance, and Scaling

  • Track MRR, churn, paid trials, plan breakdown by user/region
  • Link customer records to Stripe Customer IDs for audit/troubleshooting
  • GDPR: Remove all Stripe-related data on user account deletion
  • Monitor Stripe Dashboard for disputes, fraud, payment integrity
  • Localize receipts and billing info for global users

The CodeBlock DevKit Shortcut

CodeBlock DevKit provides production-ready modules for subscription management, webhooks, billing, upgrades, and dunning. You get:

  • Pre-built “subscribe” flows, plan selection UI
  • Secure webhooks with idempotent processing
  • Automated grace period and dunning reminders
  • Self-service billing portal
  • Deep integration with user and access logic, all auto-upgradable from NuGet

No need for custom glue code—just configure your plans and focus on your SaaS value.