Aeion Billing vs Stripe Billing
Stripe handles payments but not subscription lifecycle. Aeion Billing is the intelligent layer on top of Stripe with module license management, dunning automation, limit enforcement, and unified platform—included free with any module.
Feature-by-Feature Comparison
| Feature | Aeion Billing | Stripe Billing | Winner |
|---|---|---|---|
| **Module License Lifecycle** | Full lifecycle management | Raw subscriptions | Aeion |
| **Dunning Automation** | Auto-retry 1/3/7 days, auto-suspend | Manual retry | Aeion |
| **Trial Management** | Configurable trials, auto-convert | Basic trials | Aeion |
| **Limit Enforcement** | Real-time, auto-throttle | None | Aeion |
| **Feature Flags** | Per-license, tier-based | None | Aeion |
| **Stripe Integration** | Native sync, webhooks | Core product | Tie |
| **Invoice Generation** | Auto, multi-format | Auto via Stripe | Tie |
| **Payment Processing** | Via Stripe | Core product | Stripe |
| **Payment Methods** | All Stripe types | All Stripe types | Tie |
| **Platform Integration** | Native to Aeion OS | API required | Aeion |
| **Usage Tracking** | Built-in | Requires build | Aeion |
| **Cost Model** | $0 (included) | % of collections | Aeion |
| **SaaS-specific Features** | Module licensing, limits | General billing | Aeion |
Why Aeion Billing Wins
| Component | Stripe | Aeion |
|---|---|---|
| Module license | ❌ | ✅ |
| Trial management | ❌ | ✅ Built-in |
| Dunning automation | ❌ | ✅ |
| Limit enforcement | ❌ | ✅ |
| Feature flags | ❌ | ✅ Per-license |
| License state API | ❌ | ✅ One call |
Module License Lifecycle
Stripe: No License Concept
Stripe subscriptions are generic:
typescript
// Stripe treats all subscriptions the same
// No concept of "module" or "license tier"
const sub = await stripe.subscriptions.create({
customer: "cus_xxx",
items: [{ price: "price_xxx" }],
});
You must track manually:
- Which module and tenant the subscription is for
- The license tier ("starter", "professional", etc.)
- A feature map (what's turned on for this license)
- A limits map (usage caps for this license)
- Trial length, if applicable
- The linked Stripe subscription
- Status ("active", "expired", "suspended", "cancelled")
Plus:
- License validation
- Feature checking
- Limit checking
- Upgrade/downgrade handling
- Trial expiration
Aeion Billing: Full Lifecycle
bash
GET /api/licenses/crm/state
json
{
"data": {
"hasLicense": true,
"type": "subscription",
"tier": "pro",
"status": "active",
"features": {
"apiAccess": true,
"webhooks": true,
"maxUsers": 100,
"maxContacts": 100000,
"aiInsights": true
},
"limits": {
"maxUsers": 100,
"maxApiCalls": 1000000
},
"nextBillingDate": "2026-06-01T00:00:00Z"
}
}
License State Machine:
trial → active → expired → cancelled
↓
suspended (payment failed)
↓
active (payment recovered)
Dunning Automation
Stripe: Manual Retry
```javascript // Stripe: No automatic retry // You must build your own retry logic: async function retryPayment(invoiceId) { const invoice = await stripe.invoices.retrieve(invoiceId);
// Check retry count from metadata const retryCount = invoice.metadata.retryCount || 0;
if (retryCount >= 3) { // Give up - but you have to manually update subscription status await stripe.subscriptions.update(invoice.subscription, { status: "past_due", }); return; }
// Retry - but you have to schedule it yourself await scheduleRetry(invoiceId, retryCount + 1); } ```
What you need to build:
- Retry scheduling (cron, delayed jobs)
- Retry delay calculation (1/3/7 days)
- Email notifications (each retry, final notice, suspended)
- Subscription status update (past_due, suspended)
- License suspension (module license status update)
- Reactivation on successful payment
Time to build: 4-6 weeks
Aeion Billing: Auto-Dunning
When a payment fails, Aeion marks the invoice failed and increments its retry count automatically. While the retry count is under the maximum of 3 attempts, the next retry is scheduled on the standard 1-day / 3-day / 7-day cadence, and an event fires so other systems — the billing queue, notification emails, your own automations — can react. Once all three retries are exhausted, the invoice moves to past-due and the suspension flow kicks in — no manual scheduling, no manual status updates.
Dunning Timeline:
``` Day 0: Payment fails → Email: "Payment Failed" → Status: payment_failed, retryCount: 1
Day 1: Retry #1 → Email: "Retry Scheduled" → Status: payment_failed, retryCount: 2
Day 4: Retry #2 → Email: "Final Notice" → Status: payment_failed, retryCount: 3
Day 11: Retry #3 (final) → If fails: Status: past_due → Subscription: suspended → License: suspended → Email: "Service Suspended" ```
Auto-Suspend Logic: Once the maximum retry count is reached, any linked subscription and module license are automatically moved to a suspended state, and an event fires to notify other modules (so a module's UI can show the right banner, a CSM can be alerted, and so on).
Trial Management
Stripe: Basic Trials
```javascript // Stripe: Trial on subscription const subscription = await stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], trial_period_days: 14, // Max 730 days });
// No concept of: // - Auto-conversion // - Trial reminders // - Feature restrictions during trial // - Trial-specific limits ```
Aeion Billing: Full Trial Management
bash
POST /api/licenses/trial
{
"moduleId": "crm",
"tier": "pro",
"trialDays": 14
}
json
{
"data": {
"hasLicense": true,
"type": "trial",
"tier": "pro",
"status": "trial",
"trial": {
"daysRemaining": 12,
"trialStartedAt": "2026-05-01T00:00:00Z",
"trialExpiresAt": "2026-05-15T00:00:00Z",
"willConvertAutomatically": true
}
}
}
Automatic conversion:
- Trial expires
- Stripe subscription activated
- License type flips to "subscription"
- Conversion timestamp recorded
- Email: "Trial Converted"
Or cancellation:
- User cancels trial
- Cancellation timestamp recorded
- Stripe subscription cancelled
Trial Configuration:
- Trials enabled, defaulting to 14 days
- Auto-converts to a paid subscription at expiry
- Payment method can be required up front, or deferred until conversion
- Reminder emails sent at 7, 3, and 1 days before expiry
- Optional trial-only restrictions — e.g. a lower user or contact cap, or AI features disabled until conversion
Limit Enforcement
| Tier | maxUsers | maxContacts | maxApiCalls |
|---|---|---|---|
| Free | 5 | 1,000 | 10,000 |
| Starter | 25 | 10,000 | 100,000 |
| Professional | 100 | 100,000 | 1,000,000 |
| Enterprise | Unlimited | Unlimited | Unlimited |
Feature Flags
| Feature | Free | Starter / Professional | Enterprise |
|---|---|---|---|
| API access | – | ✅ | ✅ |
| Webhooks | – | ✅ | ✅ |
| AI insights / analytics | – | ✅ (Professional+) | ✅ |
| SSO | – | – | ✅ |
| Custom integrations | – | – | ✅ |
Pricing Analysis
| Volume | Stripe Fee | Cost |
|---|---|---|
| $10,000/month | 2.9% + $0.30 | $320/month |
| $50,000/month | 2.9% + $0.30 | $1,480/month |
| $100,000/month | 2.9% + $0.30 | $2,930/month |
| $500,000/month | 2.9% + $0.30 | $14,530/month |
Platform Integration
Stripe: API Required
```javascript // Stripe: Manual integration const stripe = require("stripe")("sk_live_xxx");
// Sync subscription to your system async function syncSubscription(subscription) { // 1. Update your own licenses table await db.update("licenses", { stripeSubscriptionId: subscription.id, status: mapStripeStatus(subscription.status), });
// 2. Update tenant features await updateTenantFeatures(subscription.customer);
// 3. Emit events for other systems await emit("billing.subscription.updated", { subscriptionId: subscription.id, }); } ```
What you must build:
- Webhook handler (verify signature, parse event)
- Status mapping (stripe → your system)
- Feature updates (on subscription change)
- Limit enforcement (on upgrade/downgrade)
- Trial conversion (on trial end)
- Dunning sync (on payment failure)
- Reactivation (on successful retry)
Aeion Billing: Native Integration
bash
POST /api/licenses/paid
{
"moduleId": "crm",
"tier": "pro",
"stripePriceId": "price_xxx"
}
Automatically:
- Creates Stripe subscription
- Tracks the license
- Sets up feature flags
- Configures limits
- Enables dunning
- Emits events for all modules
Event Flow:
``` License created → billing.license.created → CRM: enable module → Notifications: welcome email → AI: initialize insights
Payment failed → billing.dunning.scheduled → BillingQueue: retry job scheduled → Notifications: payment failed email
Max retries → billing.license.suspended → CRM: disable module features → Notifications: suspended email → Dashboard: past_due banner ```
Migration from Raw Stripe
| Data | Status |
|---|---|
| Subscriptions | ✅ Stripe ID, status, customer |
| Customers | ✅ Stripe customer ID |
| Invoices | ✅ Invoice history, payment history |
| Licenses | ✅ Module, tier, features, limits |
| Trials | ✅ Trial dates, conversion status |
| Stripe | Aeion Billing |
| ------------------- | --------------------------------------- |
| `subscriptions` | `module_licenses` |
| `customers` | `tenants` (via Stripe ID) |
| `invoices` | `invoices` |
| `prices` | `license.tier` + `license.billingCycle` |
| `trial_period_days` | `license.trialDays` |
| `status` | `license.status` |
FAQ
Aeion's license engine adds: moduleId, tier, features, limits, trial management, and validation. Stripe has only subscriptions with no concept of module licensing.
Built-in retry schedule (1 / 3 / 7 days), auto-suspend, email notifications. Raw Stripe requires custom retry logic.
1st retry in 1 day, 2nd retry in 3 days, 3rd retry in 7 days. Total 11-day grace period before suspension.
Configurable trial days (default: 14). Trial period tracked in license record. Auto-converts to subscription or cancels at expiry. Reminder emails at 7, 3, 1 days.
The limit enforcer checks current usage against license limits on the relevant create operation. Once usage reaches 100% of the limit, the operation is blocked and an upgrade prompt is shown. Enforcement is binary today — there's no separate warning tier below 100%.
Per-license features map. Free tier has basic features, enterprise has all. Feature access is a simple lookup per license.
Stripe charges 2.9% + $0.30 per transaction — a percentage of everything you collect. Aeion Billing is $0 — included free with any module — with no percentage cut. On $100K/month volume Stripe's billing overhead alone is ~$2,930/month; Aeion removes that percentage entirely.
Yes. Export Stripe subscriptions, transform to Aeion license format, import. Stripe IDs preserved for webhook handling.
When max dunning retries (3) reached: subscription status → "past_due", license status → "suspended". User sees past_due banner. Reactivates on successful payment.
The billing job queue handles 10,000 billing events / hour with built-in retry scheduling and subscription reconciliation.
The license status endpoint returns: hasLicense, type, tier, status, features, limits, trial info, and next billing date/amount.
Stripe webhooks map to license events. `customer.subscription.created/updated/deleted`, `invoice.paid/payment_failed`, etc.
When upgrading: new license with higher tier. Proration calculated for price difference. Charged immediately or at next billing cycle.
The billing job queue handles 10,000 billing events/hour. Exponential backoff on failures. Keeps 5,000 failed jobs for debugging.