Checkout conversion: recovery emails, guest checkout lockdown, working promo codes - #2141
Checkout conversion: recovery emails, guest checkout lockdown, working promo codes#2141richiemcilroy wants to merge 8 commits into
Conversation
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
| foundUserId = User.UserId.make(customer.metadata.userId); | ||
| } | ||
| if ("email" in customer && customer.email) { |
There was a problem hiding this comment.
Mutable customer ownership breaks recovery
If two Cap accounts with the same email reuse a Stripe customer, its metadata.userId points to the most recently associated account, so this handler checks that account instead of the owner recorded in the expired session's dubCustomerId. This can suppress recovery for a free checkout owner or send an upgrade reminder based on the wrong account's entitlement.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/api/webhooks/stripe/route.ts
Line: 691-693
Comment:
**Mutable customer ownership breaks recovery**
If two Cap accounts with the same email reuse a Stripe customer, its `metadata.userId` points to the most recently associated account, so this handler checks that account instead of the owner recorded in the expired session's `dubCustomerId`. This can suppress recovery for a free checkout owner or send an upgrade reminder based on the wrong account's entitlement.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| // Attaches a recovery URL to `checkout.session.expired` so abandoned | ||
| // upgrades can be emailed back (handled in the Stripe webhook). | ||
| after_expiration: { | ||
| recovery: { enabled: true, allow_promotion_codes: true }, | ||
| }, | ||
| // `priceId` is read back on `checkout.session.expired` for the recovery email. | ||
| metadata: { |
There was a problem hiding this comment.
Recovery comments duplicate implementation
These comments merely restate the adjacent after_expiration and priceId fields, and the same narration is repeated in the guest and authenticated web checkout creators. Removing these descriptive comments avoids maintenance noise and prevents them from drifting from the webhook implementation.
Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/api/desktop/[...route]/root.ts
Line: 785-791
Comment:
**Recovery comments duplicate implementation**
These comments merely restate the adjacent `after_expiration` and `priceId` fields, and the same narration is repeated in the guest and authenticated web checkout creators. Removing these descriptive comments avoids maintenance noise and prevents them from drifting from the webhook implementation.
**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…pported platforms
|
hey @greptileai please review |
Greptile Summary
This PR adds abandoned-checkout recovery emails, tightens guest checkout validation and rate limiting, and applies allowlisted URL promotion codes.
Confidence Score: 4/5
The PR is not yet safe to merge because checkout recovery can still evaluate or email the wrong account when a Stripe customer is reused.
The expired-session handler trusts the Stripe customer's mutable
metadata.userIdeven though each checkout session records its initiating user inmetadata.dubCustomerId, leaving the previously reported cross-account recovery failure reachable.Files Needing Attention: apps/web/app/api/webhooks/stripe/route.ts
Important Files Changed
Reviews (2): Last reviewed commit: "fix(web): list Linux, the Chrome extensi..." | Re-trigger Greptile
Context used: