Cursor app paywall never updates after payment
Cursor will generate a paywall component and a checkout button. The part that grants access is less photogenic, so it often stays as a TODO that returns 200.
Why this happens
- The route handler logs the event and does not touch the database.
- The user id in metadata doesn't match the id in your users table.
- You check a 'paid' flag that nothing sets.
What ShipWatch looks for
- ShipWatch is aimed at this exact gap: checkout can pass while paid access fails.
- The failure comes with a prompt you can paste back into Cursor.
Prompt to paste
Paying does not unlock the app. Trace checkout.session.completed and update the paying user's plan in the database. Match the user id field you set on the Checkout Session. Add a test that a completed checkout makes the paid page render.