feat(cli): add RevenueCat payments provider for native frontends#1076
feat(cli): add RevenueCat payments provider for native frontends#1076danestves wants to merge 7 commits into
Conversation
Adds 'revenuecat' as a payments option, offered only when a native (Expo) frontend is selected. When the backend is Convex it wires the convex-revenuecat component (app.use, webhook route, subscription queries); other backends get the native react-native-purchases SDK integration only. Native scaffolding (provider, init lib, subscription-status-card and paywall-example) is generated for all three native variants (bare, uniwind, unistyles) and is auth-agnostic. Also surfaces RevenueCat in the web stack-builder with a native-frontend requirement constraint.
|
@danestves is attempting to deploy a commit to the Better T Stack Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2996c62c14
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import { components } from "./_generated/api"; | ||
|
|
||
| export const revenuecat = new RevenueCat(components.revenuecat, { | ||
| REVENUECAT_WEBHOOK_AUTH: process.env.REVENUECAT_WEBHOOK_AUTH ?? "", |
There was a problem hiding this comment.
Pass through an unset RevenueCat webhook secret
When generating Convex + RevenueCat, .env.local leaves REVENUECAT_WEBHOOK_AUTH unset until the user runs convex env set, but this fallback converts that missing value into "". The convex-revenuecat setup treats secrets shorter than 32 chars as deploy errors, whereas an unset value only rejects webhooks until configured, so fresh projects can fail on the first Convex deploy/dev before the user configures the webhook secret; pass process.env.REVENUECAT_WEBHOOK_AUTH through instead of defaulting to an empty string.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 85c2d9f — REVENUECAT_WEBHOOK_AUTH is now passed through as process.env.REVENUECAT_WEBHOOK_AUTH (no ?? ""), matching the reference. When unset it stays undefined, so the component rejects webhooks until it's configured rather than treating "" as an invalid (sub-32-char) secret and failing the Convex deploy.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAdds RevenueCat as a new payments provider option restricted to native (Expo) frontends. Changes include PaymentsSchema enum and dependency versions, CLI prompts and compatibility validation, web UI option constants, test matrix cases and oracle rules, template processor routing and env var generation, Convex backend templates, native layout provider wrapping, RevenueCat SDK utility and context/provider layers, native UI components, UI template integration, post-install instructions, and regenerated template bundle with new RevenueCat templates. ChangesRevenueCat Payments Integration
Possibly Related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2c80508a-7553-4c93-b637-93bdd1a566aa
📒 Files selected for processing (27)
apps/cli/src/prompts/payments.tsapps/cli/src/utils/compatibility-rules.tsapps/cli/test/matrix/cases.tsapps/cli/test/matrix/oracle.tsapps/web/src/app/(home)/new/_components/utils.tsapps/web/src/lib/constant.tspackages/template-generator/src/processors/env-vars.tspackages/template-generator/src/processors/payments-deps.tspackages/template-generator/src/template-handlers/payments.tspackages/template-generator/src/templates.generated.tspackages/template-generator/src/utils/add-deps.tspackages/template-generator/templates/auth/better-auth/convex/backend/convex/http.ts.hbspackages/template-generator/templates/backend/convex/packages/backend/convex/convex.config.ts.hbspackages/template-generator/templates/frontend/native/bare/app/_layout.tsx.hbspackages/template-generator/templates/frontend/native/unistyles/app/_layout.tsx.hbspackages/template-generator/templates/frontend/native/uniwind/app/_layout.tsx.hbspackages/template-generator/templates/payments/revenuecat/convex/backend/convex/revenuecat.ts.hbspackages/template-generator/templates/payments/revenuecat/convex/no-better-auth/convex/http.ts.hbspackages/template-generator/templates/payments/revenuecat/native/bare/components/paywall-example.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/bare/components/subscription-status-card.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/base/lib/revenue-cat/index.ts.hbspackages/template-generator/templates/payments/revenuecat/native/base/providers/RevenueCatProvider.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/unistyles/components/paywall-example.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/unistyles/components/subscription-status-card.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/uniwind/components/paywall-example.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/uniwind/components/subscription-status-card.tsx.hbspackages/types/src/schemas.ts
| { | ||
| id: "revenuecat", | ||
| name: "RevenueCat", | ||
| description: "In-app subscriptions and cross-platform monetization for mobile.", | ||
| icon: `${ICON_BASE_URL}/revenuecat.svg`, | ||
| color: "from-red-400 to-red-600", | ||
| default: false, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
URL="https://r2.better-t-stack.dev/icons/revenuecat.svg"
echo "Checking: $URL"
curl -sS -o /dev/null -w "HTTP %{http_code}\n" -I "$URL"Repository: AmanVarshney01/create-better-t-stack
Length of output: 150
Upload RevenueCat icon asset to R2 before shipping.
The icon asset at https://r2.better-t-stack.dev/icons/revenuecat.svg is missing (HTTP 404). This will render a broken icon in the payments picker UI. Upload the asset to complete this feature.
There was a problem hiding this comment.
Acknowledged — revenuecat.svg needs uploading to the R2 icon bucket, which is a maintainer step (I can't push to that bucket). It's called out in the PR description, and the entry follows the existing polar.svg convention, so it resolves once the asset is added.
There was a problem hiding this comment.
@danestves, understood — thanks for the context. Since the R2 upload is a maintainer step and already documented in the PR description, the implementation-side work is complete. The concern stays open only until the asset is actually uploaded.
Would you like me to open a GitHub issue to track the R2 asset upload (revenuecat.svg → r2.better-t-stack.dev/icons/) so it doesn't get missed after this PR merges?
- Pass REVENUECAT_WEBHOOK_AUTH through unset instead of defaulting to an empty string, so an unconfigured secret rejects webhooks rather than failing the Convex deploy / accepting unauthenticated requests. - Normalize EXPO_PUBLIC_REVENUECAT_* platform keys (trim) before the presence check so whitespace-only values aren't forwarded to the SDK. - Add re-entry guards to the example paywalls: purchase and restore are now mutually exclusive (isBusy) across bare/uniwind/unistyles.
- lib/revenue-cat/index.ts -> lib/revenuecat.ts (flat, matching lib/constants.ts and lib/use-color-scheme.ts) - providers/RevenueCatProvider.tsx -> contexts/revenuecat-context.tsx (matching contexts/app-theme-context.tsx); RevenueCatProvider export name kept - rewire all imports to @/lib/revenuecat and @/contexts/revenuecat-context
Mirror getPolarInstructions: print RevenueCat dashboard + env key + (Convex) webhook setup steps after project creation. Gated on payments=revenuecat (auth-agnostic).
Add the hosted RevenueCat MCP server (https://mcp.revenuecat.ai/mcp) to the MCP server list and recommend it when payments=revenuecat, mirroring the Polar MCP entry.
…nd dashboard Full parity with how Polar surfaces its example: - bare components rebuilt with @expo/ui (Host/Column/ExpoUIText/Button) - uniwind components rebuilt with heroui-native (Card/Button/Spinner) - unistyles components unchanged (already convention-correct) - mount SubscriptionStatusCard + PaywallExample on the native dashboard index (app/(drawer)/index.tsx) across all variants and both index sources (frontend/native + auth/better-auth/native), gated on payments=revenuecat only
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9b6d331d-cc49-4b71-95ca-672ca632bf6b
📒 Files selected for processing (14)
apps/cli/src/helpers/addons/mcp-setup.tsapps/cli/src/helpers/core/post-installation.tspackages/template-generator/src/templates.generated.tspackages/template-generator/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbspackages/template-generator/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbspackages/template-generator/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbspackages/template-generator/templates/frontend/native/bare/app/(drawer)/index.tsx.hbspackages/template-generator/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbspackages/template-generator/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/bare/components/paywall-example.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/bare/components/subscription-status-card.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/uniwind/components/paywall-example.tsx.hbspackages/template-generator/templates/payments/revenuecat/native/uniwind/components/subscription-status-card.tsx.hbspackages/types/src/schemas.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/template-generator/templates/payments/revenuecat/native/uniwind/components/subscription-status-card.tsx.hbs
- packages/template-generator/templates/payments/revenuecat/native/bare/components/paywall-example.tsx.hbs
- packages/template-generator/src/templates.generated.ts
Post-install instructions omitted EXPO_PUBLIC_REVENUECAT_ENTITLEMENT_ID, which env-vars.ts writes to apps/native/.env and the SDK lib reads. Add it so the printed setup matches the generated env contract.
What
Adds RevenueCat as a new
paymentsprovider for in-app purchases on native (Expo / React Native) apps.Unlike Polar (web + Better-Auth), RevenueCat is native-gated and auth-agnostic:
native-bare/native-uniwind/native-unistyles) is selected, with any backend exceptnone.convex-revenuecatcomponent:app.use(revenuecat)inconvex.config.ts, webhook viaregisterRoutes(POST /webhooks/revenuecat), and arevenuecat.tsclient exposinghasEntitlement/isSubscriber/getActiveSubscriptions.react-native-purchasesSDK integration only (RevenueCat hosts subscription state).How it works
revenuecatadded toPaymentsSchema; the prompt offers it when a native frontend is present;validatePaymentsCompatibilityerrors if selected without a native frontend. Matrix oracle + cases updated (payments-revenuecat-requires-native-frontend).http.tswebhook is added to the Better-Authhttp.tswhen present, and a standalonehttp.tsis generated for Convex + Clerk/none (so the Better-Auth routes are never clobbered).RevenueCatProvider+lib/revenue-catSDK layer, plus styledsubscription-status-cardandpaywall-examplecomponents (StyleSheet / NativeWind / unistyles). The provider is mounted via a conditional wrap in eachapp/_layout.tsx..envgetsEXPO_PUBLIC_REVENUECAT_IOS_KEY/_ANDROID_KEY/_ENTITLEMENT_ID; Convex.env.localgetsREVENUECAT_WEBHOOK_AUTHwith setup comments.apps/webwith a native-frontend requirement constraint mirroring how Polar gates on Better-Auth.Based on
0rtbo/convexpo-revenuecat, adapted to this project's conventions (the reference'suser-contextcoupling and identity auto-sync were intentionally dropped to keep the provider auth-agnostic; example components are SDK/provider-based rather than tied to a specific Convexsubscriptionsmodule).Testing
BTS_MATRIX_MODE=smokematrix: 289 pass / 0 fail (covers revenuecat × all native variants × convex with/without Better-Auth, plus invalid combos rejected with the right rule).oxlintclean on changed files.convex + better-auth + native-bareandhono + native-uniwindprojects and verified the generated provider wrap, Convex wiring, env files, and components.Notes for maintainers
r2.better-t-stack.dev/icons/revenuecat.svg— that icon asset still needs to be uploaded to R2 (matching the existingpolar.svgconvention).convex-revenuecatis pinned to^0.3.2(the API the templates are written against).Summary by CodeRabbit
New Features
Validation / Compatibility
Chores / Types