Subscription & Plan Enforcement
Lightning Enable enforces active subscriptions and plan-specific feature access on every API request. This page explains how plan tiers work, what happens when a subscription lapses, and how feature gating controls access to plan-specific functionality.
Plan Tiers
Lightning Enable offers two plan tiers. Pricing is based on capabilities, never transaction volume. Platform integrations (Kentico Commerce, Shopify Commerce) are included with any plan.
| Plan | Tier ID | Price |
|---|---|---|
| Agentic Commerce — Individual | individual | $99/month |
| Agentic Commerce — Business | l402 | $299/month (default) |
All plans include annual pricing at approximately two months free and a 30-day free trial.
Note: The codebase also contains a legacy
standardtier (Kentico Commerce, $249/mo) that is no longer actively marketed. This tier exists for backward compatibility with existing integrations. It hasTrialEligible = falseandL402Enabled = false. New customers should use one of the Agentic Commerce plans above.
Feature Comparison
Every plan includes core API access. Higher tiers unlock additional capabilities.
| Feature | Agentic Commerce — Individual | Agentic Commerce — Business |
|---|---|---|
| Full REST API | Yes | Yes |
| Lightning Network payments | Yes | Yes |
| Refund support | Yes | Yes |
| Multi-currency (USD, EUR, GBP, BTC) | Yes | Yes |
| Analytics | Yes | Yes |
| Priority support | Yes | Yes |
| Max environments | 2 | 2 |
| Max webhook endpoints | 5 | 5 |
| Platform integrations (Kentico, Shopify) | Yes | Yes |
| L402 protocol (server-side) | Yes | Yes |
| Pay-per-request monetization | Yes | Yes |
| MCP AI agent integration | Yes | Yes |
| White-glove onboarding | No | Yes |
| Custom branding | No | No |
Checking Your Plan
Use the merchant settings endpoint to see your current plan and features:
curl https://api.lightningenable.com/api/merchant/me \
-H "X-API-Key: le_merchant_abc123"
The response includes your planTier, subscriptionStatus, and a features object with all feature flags.
Free Trial
Lightning Enable offers a 30-day free trial on Agentic Commerce plans, giving you full API access before your first payment.
How It Works
- Eligible plans: Agentic Commerce -- Individual ($99/mo) and Agentic Commerce -- Business ($299/mo)
- Duration: 30 days from the date of subscription
- Card required: A valid payment method must be provided at signup. You will not be charged during the trial period.
- Full access: Trial merchants have complete API access, identical to a paid subscription. The
subscriptionStatuswill showtrialing. - Auto-converts: At the end of the 30-day trial, the subscription automatically converts to a paid plan. Your card on file will be charged at the plan's regular rate.
- Cancel anytime: You can cancel before the trial ends to avoid being charged. Use the Stripe customer portal to manage your subscription.
Abuse Prevention
To maintain fair access, Lightning Enable enforces one free trial per email address. If a customer has previously used a trial (on any plan), subsequent subscriptions will skip the trial period and begin billing immediately.
Trial Eligibility by Plan
| Plan | Trial Eligible |
|---|---|
| Agentic Commerce -- Individual ($99/mo) | Yes |
| Agentic Commerce -- Business ($299/mo) | Yes |
Subscription Lifecycle
Valid Subscription States
The subscription enforcement middleware checks every authenticated API request. Only two statuses grant access:
| Status | Meaning | API Access |
|---|---|---|
active | Subscription is current and paid | Allowed |
trialing | In free trial period | Allowed |
past_due | Payment failed, awaiting retry | Blocked |
canceled | Subscription was canceled | Blocked |
unpaid | Payment not received | Blocked |
incomplete | Initial payment not completed | Blocked |
incomplete_expired | Initial payment window expired | Blocked |
Subscription Validation Flow
The middleware performs these checks in order for every authenticated request:
- Path exemption -- Certain paths skip subscription checks entirely (Stripe endpoints, webhooks, health checks, Swagger).
- Account active check -- If the merchant account is deactivated (
isActive = false), the request is immediately blocked with a403. - Pilot tier bypass -- Pilot accounts are allowed through without subscription validation (see Pilot Tier below).
- Stripe subscription required -- Non-pilot accounts must have a valid
StripeSubscriptionId. Accounts without one receive a403withaction_required: "subscribe". - Subscription status check -- The status must be
activeortrialing. Any other status returns a403with a status-specific message. - Billing period validation -- If
CurrentPeriodEndis set and has passed, the request is blocked even if the status field still showsactive. This catches expired subscriptions before the Stripe webhook updates the status. - Feature gating -- Plan-specific features are checked against the requested endpoint (see Feature Gating below).
Request
│
├─ Exempt path? ──── Yes ──→ Allow
│
├─ No MerchantId? ── Yes ──→ Allow (unauthenticated)
│
├─ Account inactive? ────── → 403 "Account inactive"
│
├─ Pilot tier? ───── Yes ──→ Allow (with monitoring)
│
├─ No Stripe sub? ─────────→ 403 "Subscription required"
│
├─ Status not active/trialing? → 403 "Subscription not active"
│
├─ CurrentPeriodEnd passed? ──→ 403 "Subscription period expired"
│
├─ Feature not available? ────→ 403 "Feature not available"
│
└─ All checks pass ─────────→ Allow (features set in context)
Subscription Expiration
What Happens When a Subscription Expires
When a subscription expires or is canceled, API requests return 403 Forbidden with a JSON body describing the issue and what action to take.
Canceled subscription:
{
"error": "Subscription not active",
"message": "Your subscription has been canceled. Please subscribe again to continue using the service.",
"subscription_status": "canceled",
"action_required": "renew_subscription"
}
Past due payment:
{
"error": "Subscription not active",
"message": "Your subscription payment is past due. Please update your payment method to continue using the service.",
"subscription_status": "past_due",
"action_required": "update_payment_method"
}
Billing period expired (webhook delay protection):
{
"error": "Subscription period expired",
"message": "Your subscription billing period has expired. Please renew your subscription to continue using the service.",
"subscription_status": "active",
"current_period_end": "2026-01-15T00:00:00.0000000Z",
"action_required": "renew_subscription"
}
Even if the subscription status still reads active, the middleware checks whether CurrentPeriodEnd has passed. This provides a safety net for cases where Stripe webhook delivery is delayed, ensuring expired subscriptions are caught in near-real-time.
Grace Period Behavior
Lightning Enable relies on Stripe's built-in retry and grace period logic:
- Stripe retries failed payments automatically according to your Stripe account's Smart Retries settings (typically 3-4 attempts over several days).
- During retries, the subscription status transitions to
past_due. API access is blocked during this period. - If all retries fail, Stripe marks the subscription as
canceledorunpaiddepending on your Stripe settings. - There is no additional grace period built into Lightning Enable beyond what Stripe provides. The moment the subscription status leaves
activeortrialing, API access is blocked.
To restore access after a lapsed subscription:
- Update your payment method via the Stripe customer portal.
- Or subscribe again at lightningenable.com.
Exempt Paths
These paths are never subject to subscription enforcement, even for expired accounts:
| Path | Reason |
|---|---|
/api/stripe/create-checkout-session | Must be accessible to (re)subscribe |
/api/stripe/customer-portal | Must be accessible to manage billing |
/api/stripe/subscription | Must be accessible to check status |
/api/stripe/pricing | Public pricing information |
/api/webhooks/stripe | Incoming Stripe webhooks |
/api/webhooks/opennode | Incoming OpenNode webhooks |
/api/l402 | L402 demo endpoints (use L402 token auth) |
/health | Health check |
/swagger | API documentation |
This ensures merchants can always manage their subscription and billing even when their API access is blocked.
Pilot Tier
The pilot tier is a special account type used for evaluation and onboarding. Pilot accounts:
- Have full API access without requiring a Stripe subscription.
- Do not require
StripeSubscriptionId,SubscriptionStatus, orCurrentPeriodEnd. - Are monitored -- if a pilot account has been active for more than 90 days, a warning is logged encouraging conversion to a paid plan.
- Are not publicly available -- pilot accounts are created by administrators only.
Pilot accounts are intended for short-term evaluation. They have no expiration enforcement but are expected to convert to a paid plan.
Feature Gating
Beyond subscription status, the middleware enforces plan-specific feature access on certain endpoints.
Gated Features
| Feature | Gated Endpoint | Description |
|---|---|---|
refunds | /api/refunds/* | Refund processing |
multi_currency | /api/payments/*/convert | Multi-currency conversion |
If a merchant attempts to access a gated endpoint without the required feature flag, they receive:
{
"error": "Feature not available",
"message": "Refund processing is not enabled for your account. Please contact support.",
"feature": "refunds",
"current_plan": "pilot",
"required_plan": "standard",
"action_required": "upgrade_plan"
}
Feature Flags in Context
When a request passes all subscription and feature checks, the middleware populates MerchantFeatures in the request context. Controllers can use these flags for fine-grained access control:
| Feature Flag | Type | Description |
|---|---|---|
RefundsEnabled | boolean | Can process refunds |
MultiCurrencyEnabled | boolean | Can use multi-currency conversion |
MaxWebhookEndpoints | int | Maximum webhook endpoints allowed |
AnalyticsEnabled | boolean | Access to analytics |
PrioritySupport | boolean | Priority support access |
CustomBrandingEnabled | boolean | Custom branding on checkout |
L402 Feature Gating
L402 server-side features (creating proxies, configuring endpoint pricing) require the Agentic Commerce — Business plan (l402 tier). This is enforced separately from the middleware via the L402Enabled flag on the merchant entity.
Check your L402 status:
curl https://api.lightningenable.com/api/merchant/l402-status \
-H "X-API-Key: le_merchant_abc123"
| Plan | L402 Server-Side | Price |
|---|---|---|
| Agentic Commerce — Individual | Yes | $99/mo |
| Agentic Commerce — Business | Yes | $299/mo |
The MCP server's L402 client tools (access_l402_resource, pay_l402_challenge) are free for everyone. No subscription is needed to pay L402 invoices -- only to create L402-protected endpoints.
Handling Subscription Errors in Your Integration
Detecting Subscription Issues
All subscription-related errors return HTTP 403 with an action_required field. Use this field to determine the appropriate response:
action_required | Meaning | Recommended Action |
|---|---|---|
contact_support | Account deactivated | Contact support@lightningenable.com |
subscribe | No active subscription | Redirect to subscription page |
update_payment_method | Payment failed | Redirect to Stripe customer portal |
renew_subscription | Subscription expired or canceled | Redirect to subscription page |
upgrade_plan | Feature requires higher plan | Show upgrade options |
Example Error Handler
async function callLightningEnableApi(endpoint) {
const response = await fetch(`https://api.lightningenable.com${endpoint}`, {
headers: { 'X-API-Key': process.env.LIGHTNING_API_KEY }
});
if (response.status === 403) {
const error = await response.json();
switch (error.action_required) {
case 'subscribe':
case 'renew_subscription':
console.error('Subscription issue:', error.message);
// Redirect user to subscription page
break;
case 'update_payment_method':
console.error('Payment issue:', error.message);
// Redirect user to Stripe customer portal
break;
case 'upgrade_plan':
console.error(`Feature "${error.feature}" requires ${error.required_plan} plan`);
// Show upgrade options
break;
case 'contact_support':
console.error('Account issue:', error.message);
break;
}
throw new Error(error.message);
}
return response.json();
}
Next Steps
- Product Overview -- Compare plan features
- Error Code Reference -- All API error codes
- Merchant Settings -- Check subscription status via API
- FAQ -- Common questions about plans and pricing