You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Lite subscription never activates for 3DS/SCA payments causing users to be permanently locked out #28408
When a user subscribes to OpenCode Lite using a card that requires 3D Secure (3DS) or SCA verification, the subscription is never activated. Payment is confirmed by Stripe, but BillingTable.lite is never set and LiteTable is never populated. The user is locked out of Lite indefinitely with no recovery path.
The customer.subscription.created handler activates Lite by writing BillingTable.lite = {} and inserting into LiteTable. It reads the payment method from default_payment_method on the subscription object.
In 3DS/SCA flows Stripe attaches the payment method asynchronously — after the redirect completes — so default_payment_method is null when customer.subscription.created fires. The handler throws before any DB writes:
constpaymentMethodID=body.data.object.default_payment_methodasstringif(!paymentMethodID)thrownewError("Payment method ID not found")
Stripe retries for 72 hours then stops. By that point payment has already succeeded, but activation was never moved to invoice.payment_succeeded. The user's card is charged and service is never granted.
3DS/SCA is mandatory for EU/UK cards and increasingly common globally.
Fix: Move Lite activation from customer.subscription.created to invoice.payment_succeeded (billing_reason === "subscription_create"), which fires only after Stripe confirms payment — covering both immediate and 3DS/SCA flows.
Plugins
No response
OpenCode version
No response
Steps to reproduce
Subscribe to OpenCode Lite using an EU/UK card that requires 3DS (e.g. Stripe test card 4000002500003155).
Complete the 3DS challenge and return to the app.
Observe the workspace remains on the free tier despite payment succeeding.
OpenCode, I was about to subscribe but not trusting the process at this moment :-( I do not want "try and see if it worked" or to fiddle with support emails and what not. Please review and address the ticket. This is what Github's copilot says about the matter (regardless if AI slop or not)
Root Cause
Missing Payment Confirmation for Subscription Activation
The Issue:
When customer.subscription.created fires (line 108), the code immediately activates the subscription (sets lite: {} at line 150) without verifying that the initial invoice payment succeeded.
The subscription can be created by Stripe even when:
The payment is still pending (e.g., requires 3DS)
The invoice hasn't been paid yet
The subscription status is incomplete or incomplete_expired
What Happens:
customer.subscription.created fires → Subscription activated immediately ✓
Payment requires 3DS verification → User is shown 3DS prompt
Payment eventually succeeds at Stripe → invoice.payment_succeeded fires with billing_reason: "subscription_create"
But the webhook only records the payment (inserts to PaymentTable, line 245-258), it does NOT activate the subscription because it's already activated
The Gap:
The invoice.payment_succeeded handler (lines 210-258) for subscription creation does NOT include:
// This is MISSING - no update to actually activate/enable the subscriptionawaittx.update(BillingTable).set({lite: {},// Should set this when invoice payment succeeds// ... other fields}).where(eq(BillingTable.workspaceID,workspaceID))
So if the subscription was already set to active but there's a failure state or the system crashes between events, OR if there's a condition where the subscription needs to transition from incomplete to active, there's no handler to actually mark it as successfully activated.
Even Worse - Incomplete Subscriptions:
Line 187-196 handle customer.subscription.updated only when status is incomplete_expired, which deactivates the subscription. But there's no handler for when the subscription transitions from incomplete → active after successful payment.
Scenario That Breaks:
User subscribes → customer.subscription.created fires → lite: {} is set (activates)
3DS verification required
User completes 3DS
invoice.payment_succeeded fires → payment recorded but no subscription state update
If there's any system state mismatch, the subscription appears inactive even though payment succeeded
Fix Needed:
Add a handler for when subscription completes payment:
if(body.type==="customer.subscription.updated"&&body.data.object.status==="active"&&body.data.previous_attributes?.status!=="active"){// Subscription just became active after payment confirmation// Ensure lite subscription is properly activated}
Or better: ensure invoice.payment_succeeded with billing_reason: "subscription_create" also updates subscription activation status in your database.
Activity
LucaWolf commentedon Jul 17, 2026
OpenCode, I was about to subscribe but not trusting the process at this moment :-( I do not want "try and see if it worked" or to fiddle with support emails and what not. Please review and address the ticket. This is what Github's copilot says about the matter (regardless if AI slop or not)
Root Cause
Missing Payment Confirmation for Subscription Activation
The Issue:
When customer.subscription.created fires (line 108), the code immediately activates the subscription (sets lite: {} at line 150) without verifying that the initial invoice payment succeeded.
The subscription can be created by Stripe even when:
What Happens:
The Gap:
The invoice.payment_succeeded handler (lines 210-258) for subscription creation does NOT include:
So if the subscription was already set to active but there's a failure state or the system crashes between events, OR if there's a condition where the subscription needs to transition from incomplete to active, there's no handler to actually mark it as successfully activated.
Even Worse - Incomplete Subscriptions:
Line 187-196 handle customer.subscription.updated only when status is incomplete_expired, which deactivates the subscription. But there's no handler for when the subscription transitions from incomplete → active after successful payment.
Scenario That Breaks:
Fix Needed:
Add a handler for when subscription completes payment:
Or better: ensure invoice.payment_succeeded with billing_reason: "subscription_create" also updates subscription activation status in your database.
github-actions commentedon Sep 17, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.