Short answer
A new subscription stays incomplete until its first invoice is paid, and the customer has 23 hours. If the PaymentIntent says requires_action, the card needs authentication: listen for invoice.payment_action_required, send the customer through it with stripe.handleNextAction, and give access only after invoice.paid or an active subscription. After 23 hours it becomes incomplete_expired and you need a new subscription.
What the status means, and the fix
01
The first payment needs 3D Secure
“Some payment methods require customer authentication with 3D Secure (3DS). Whether authentication is required depends on your Radar rules and the issuing bank for the card.” Stripe, How subscriptions work
Whether a card asks for authentication depends on your Radar rules and the customer’s bank, so it can work for you and fail for some customers. Check the PaymentIntent status: requires_action means the customer still has to authenticate.
02
Your app never shows the authentication step
“Retrieve the PaymentIntent’s client secret and pass it to stripe.handleNextAction.” Stripe, How subscriptions work
Tell the customer they need to authenticate, then pass the PaymentIntent’s client secret to stripe.handleNextAction. Stripe says it guides the customer through any required steps and returns the result to your application.
const { error } = await stripe.handleNextAction({ clientSecret }); if (error) showMessage(error.message);03
No webhook for invoice.payment_action_required
“Monitor for the invoice.payment_action_required event notification with webhook endpoints. This indicates that authentication is required.” Stripe, How subscriptions work
Stripe sends invoice.payment_action_required when authentication is required. Add this event to your webhook endpoint and use it to bring the customer back to authenticate.
04
Access is granted before the payment succeeds
“Before provisioning your product, confirm that the subscription is active or that the customer has active entitlements.” Stripe, How subscriptions work
An incomplete subscription hasn’t been paid. Give access on invoice.paid, or after checking that the subscription is active or the customer has active entitlements, not when the subscription is created.
05
It already turned incomplete_expired
“if the customer doesn’t pay within 23 hours, the subscription updates to incomplete_expired and the invoice becomes void. To reactivate their access, create a new subscription.” Stripe, How subscriptions work
After 23 hours without a successful payment, the invoice is voided, and Stripe’s fix is a new subscription. Create one for the customer and make sure the authentication step works this time.
Checked against the vendor’s docs on : Stripe docs: How subscriptions work; Stripe docs: Subscription webhooks.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- $950Stripe Billing Fix and SetupSubscriptions, webhooks, customer portal and failed payments set up or fixed, tested in Stripe test mode.See scope and start
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way.See scope and start
Related: Stripe paid, account not upgraded · Stripe webhook 200 but database not updated · Stripe subscription canceled, access wrong · Stripe customer portal not working