1. Overview
| Component | Role |
|---|---|
| RevenueCat Dashboard | Create project, connect stores (Apple, Google, Stripe, etc.), add products, create entitlement(s), create offering(s), optional paywall. |
| RevenueCat Server API | CreditNexus server uses the Secret API key (sk_…) to: (1) check subscriber entitlements (GET /v1/subscribers/{app_user_id}), (2) grant promotional entitlements (POST .../promotional). |
| CreditNexus server | Uses REVENUECAT_ENABLED, REVENUECAT_API_KEY, REVENUECAT_ENTITLEMENT_PRO; identifies users as app_user_id = str(user.id) (CreditNexus user ID). |
app/services/revenuecat_service.py, app/api/subscription_routes.py, app/services/payment_router_service.py
2. RevenueCat Dashboard Setup
2.1 Create or select a project
- Go to RevenueCat.
- Create a new project or select an existing one. Projects are top-level containers for apps, products, entitlements, and paywalls.
2.2 Connect to a store
Depending on your platforms, connect at least one store:- Apple App Store: iOS Product Setup — App Store Connect, in-app purchases.
- Google Play: Google Play Product Setup — Google Play Console, subscriptions/products.
- Stripe: Stripe Product Setup — for web or custom billing.
- Paddle: Paddle Product Setup — for web.
2.3 Create an entitlement
An entitlement represents a level of access (e.g. “Pro”) that you grant when a customer purchases a product.- In the RevenueCat dashboard, go to Product catalog → Entitlements.
- Create an entitlement. The identifier is what the server uses in the REST API (e.g.
entlfa0ee126b6— use the exact value shown in the dashboard). - Set
REVENUECAT_ENTITLEMENT_PROin.envto this exact identifier (e.g.entlfa0ee126b6). - Attach your products (from the linked store) to this entitlement.
GET /v1/subscribers/{app_user_id} and POST .../entitlements/{entitlement_identifier}/promotional using this identifier.
2.4 Products to add: subscribe + buy credits
The server expects these product_id values when the client callsPOST /api/subscriptions/revenuecat/purchase. Create products in your linked store (sandbox and/or production) and map them as below.
Subscribe (entitlement + credits)
| product_id (client sends) | Use case | Server behavior |
|---|---|---|
subscription_upgrade | Monthly Pro subscription | Grant Pro entitlement P1M + SUBSCRIPTION_UPGRADE_CREDITS (default 200 pennies) |
org_admin | Organization admin signup ($2) | Grant Pro (or org-admin) P1Y + mark org paid + ORG_ADMIN_SIGNUP_CREDITS (default 200) |
mobile_app | Mobile one-time purchase (~$3.60) | Grant Pro P1Y + MOBILE_APP_PURCHASE_CREDITS (default 360) |
- In RevenueCat Products: create or import from your store (e.g. Stripe, Paddle, App Store) products that map to these. The store product identifier can be anything; the client must send the
product_idabove when calling the CreditNexus server after purchase. - Attach these three products to your Pro entitlement (e.g.
entlfa0ee126b6).
| product_id (client sends) | Use case | Server behavior |
|---|---|---|
credit_top_up_100 | $1 worth of credits (100 pennies) | Add 100 credits (universal); no entitlement grant |
credit_top_up_500 | $5 worth (500 pennies) | Add 500 credits |
credit_top_up_1000 | $10 worth (1000 pennies) | Add 1000 credits |
credit_top_up_<N> | Any N pennies | Add N credits |
- Create consumable or one-time products in your store (e.g. “100 credits”, “500 credits”, “1000 credits”) and map them to
credit_top_up_100,credit_top_up_500,credit_top_up_1000. The client sends thatproduct_idafter purchase; the server adds that many credits (pennies). - Do not attach credit-pack products to the Pro entitlement; the server only adds credits and does not grant entitlement for these.
- Entitlements: One entitlement, e.g. identifier
entlfa0ee126b6(Pro). - Products (store): Create in your linked store:
- Subscribe: e.g. “Pro Monthly”, “Org Admin ($2)”, “Mobile Unlock” → map to
subscription_upgrade,org_admin,mobile_app. Attach all three to the Pro entitlement. - Buy credits: e.g. “100 credits”, “500 credits”, “1000 credits” → map to
credit_top_up_100,credit_top_up_500,credit_top_up_1000. Do not attach to entitlement.
- Subscribe: e.g. “Pro Monthly”, “Org Admin ($2)”, “Mobile Unlock” → map to
- Offerings: Create at least one offering (e.g. default) and add packages:
- Packages for subscribe: subscription_upgrade, org_admin, mobile_app.
- Packages for buy credits: credit_top_up_100, credit_top_up_500, credit_top_up_1000 (or more packs as you like).
- You can use one offering with all packages, or two offerings (e.g. “default” = subscription, “credits” = credit packs). Set one as current for the paywall.
- Paywall: Use RevenueCat Paywalls (or your own UI) to show “Subscribe” and “Buy credits” options. After any purchase, the client calls
POST /api/subscriptions/revenuecat/purchasewith the correspondingproduct_id.
2.5 Create an offering
An offering is a set of products you show on a paywall. Create at least one offering (e.g. default) and add packages that reference your products. The server does not require a specific offering ID; the SDK uses offerings to display the paywall. Set the offering as current if you use a single default.2.6 Configure a paywall (optional)
Use RevenueCat Paywalls to build the purchase UI remotely. The CreditNexus web app can still use x402 for web payments; the paywall is most useful for native (iOS/Android) or when you use RevenueCat’s paywall UI.3. Get the Secret API key (for the server)
The server must use a Secret API key (sk_…) — never a public key — for REST API calls.- In the RevenueCat dashboard, open your project.
- Go to Project settings → API keys (or Authentication).
- Create or copy a Secret API key (starts with
sk_).- Never expose this key in the client or in version control.
- Use it only in server-side environment variables.
4. Server configuration (.env)
In the project root.env:
| Variable | Description |
|---|---|
REVENUECAT_ENABLED | Set to true to enable entitlement checks and promotional grants. |
REVENUECAT_API_KEY | Secret API key (sk_…). Required when REVENUECAT_ENABLED=true. |
REVENUECAT_ENTITLEMENT_PRO | Entitlement identifier (e.g. entlfa0ee126b6). Must match the identifier in RevenueCat Dashboard → Entitlements. |
REVENUECAT_ENTITLEMENT_ORG_ADMIN— if you use a separate entitlement for org-admin; otherwise server falls back toREVENUECAT_ENTITLEMENT_PRO.REVENUECAT_ENTITLEMENT_MARKET_INTELLIGENCE— for surveillance/premium features; otherwise falls back toREVENUECAT_ENTITLEMENT_PRO.
app/core/config.py
5. How the server uses RevenueCat
5.1 User identification
The server identifies users to RevenueCat withapp_user_id = str(user.id) (CreditNexus user ID). When you use the RevenueCat SDK on a client (e.g. mobile), you should identify the user with the same ID after login:
5.2 Entitlement check
- Endpoint:
GET /api/subscriptions/entitlement - Server: Calls RevenueCat REST API
GET /v1/subscribers/{app_user_id}and checks the entitlement (e.g.pro) in the response. Returns e.g.{ "has_pro": true }or{ "has_pro": false }.
5.3 After x402 payment (subscription upgrade / org-admin)
When a user completes an x402 payment (e.g. subscription upgrade or org-admin signup), the server can grant a RevenueCat promotional entitlement so they get Pro (or org-admin) access in RevenueCat as well:- Server: Calls RevenueCat REST API
POST /v1/subscribers/{app_user_id}/entitlements/{entitlement_id}/promotionalwith duration (e.g. P1M, P1Y). - Code:
PaymentRouterService.after_subscription_payment()→RevenueCatService.grant_promotional_entitlement().
5.4 In-app purchase (mobile) → server
When the user pays in-app (RevenueCat SDK), the client should call the CreditNexus server so the server can grant access and allocate credits:- Endpoint:
POST /api/subscriptions/revenuecat/purchase - Body:
{ "product_id": "subscription_upgrade" | "org_admin" | "mobile_app" | "credit_top_up_500", "transaction_id": "...", "purchase_token": "..." }(transaction_id and purchase_token optional).
6. Product IDs the server expects
When callingPOST /api/subscriptions/revenuecat/purchase, the server handles product_id as follows:
Subscribe (entitlement + credits)
| product_id | Entitlement | Duration | Use case |
|---|---|---|---|
subscription_upgrade | REVENUECAT_ENTITLEMENT_PRO | P1M (1 month) | Monthly subscription upgrade. |
org_admin | REVENUECAT_ENTITLEMENT_ORG_ADMIN or REVENUECAT_ENTITLEMENT_PRO | P1Y (1 year) | Org-admin signup payment. |
mobile_app | REVENUECAT_ENTITLEMENT_PRO | P1Y | Mobile app one-time purchase; server allocates MOBILE_APP_PURCHASE_CREDITS. |
| product_id | Server behavior |
|---|---|
credit_top_up_<N> (e.g. credit_top_up_100, credit_top_up_500, credit_top_up_1000) | Add N credits (pennies) to the user; no entitlement grant. |
7. Payment flow summary
| Flow | Client | Server |
|---|---|---|
| Web (x402) | User pays via x402; server receives payment and optionally grants RevenueCat entitlement. | POST /api/subscriptions/upgrade or POST /api/subscriptions/org-admin/upgrade; after settle, after_subscription_payment() grants entitlement. |
| Mobile / Web (RevenueCat SDK) | User subscribes or buys credits in-app; client calls CreditNexus server with product_id. | POST /api/subscriptions/revenuecat/purchase with product_id; server grants entitlement + credits (subscribe) or only adds credits (credit_top_up_*). |
revenuecat_available: true and revenuecat_endpoint: "/api/subscriptions/revenuecat/purchase" so the client knows it can offer an in-app purchase path.
8. Alignment: RevenueCat, Plaid, and MetaMask
All paywalled flows use the same pattern: credits first, then 402 payment required if insufficient. Payment can be completed via MetaMask (x402), facilitator, or RevenueCat (in-app / card).| Flow | Credits / entitlement | If insufficient | Payment options |
|---|---|---|---|
| Billable feature (predictions, agents, green finance, etc.) | require_credits_or_402 spends rolling credits (pennies). | 402 with payment_request; revenuecat_available when RevenueCat enabled. | MetaMask (x402), facilitator, or RevenueCat (client calls POST /api/subscriptions/revenuecat/purchase with product_id for subscription/org_admin; credit top-up uses POST /api/credits/top-up with x402). |
| Credit top-up | User must have org unlocked (subscription or credits). | 402 with payment_request. | MetaMask (x402), facilitator. Amount in USD; server adds credits = pennies (1 USD = 100 by default, CREDITS_PENNIES_PER_USD). |
| Subscription upgrade / org-admin | N/A (user is paying to get access). | 402 with payment_request; revenuecat_available and revenuecat_endpoint. | MetaMask (x402), facilitator, or RevenueCat (client sends product_id subscription_upgrade or org_admin after in-app purchase). |
| Plaid (banking) | Banking routes use require_credits_or_402 with BILLABLE_FEATURE; 1 credit per call (or cost in USD in 402). | 402; user pays via MetaMask/RevenueCat or tops up credits. | Same as billable feature. Plaid does not “pay” directly — user consumes credits or completes 402. |
- Subscribe: User pays once (e.g. 3.60 mobile); server grants entitlement and credits (
ORG_ADMIN_SIGNUP_CREDITS,SUBSCRIPTION_UPGRADE_CREDITS,MOBILE_APP_PURCHASE_CREDITS). Credits ≈ dollar value (e.g. 200 pennies = 3.60). - Pay-as-you-go: User tops up credits via
POST /api/credits/top-up(MetaMask/facilitator or RevenueCat). Services (dashboard refresh = Plaid accounts/balances/transactions, predictions, agents, green finance, brokerage fund/withdraw) cost credits; if insufficient, 402 with payment options (MetaMask, RevenueCat). - Plaid markup:
PLAID_COST_USDis the base cost per API call;PLAID_MARKUP_PERCENTadds a percentage (e.g. 20 = 20% markup). Final charge in 402 =PLAID_COST_USD * (1 + PLAID_MARKUP_PERCENT/100). - Brokerage transfers: Optional
BROKERAGE_TRANSFER_FEE_CREDITS(0 = no fee). When > 0, each fund/withdraw deducts that many credits (subscribe or pay-as-you-go).
- RevenueCat: One entitlement (e.g.
entlfa0ee126b6), three products attached (subscription_upgrade,org_admin,mobile_app), one offering with packages. SetREVENUECAT_ENTITLEMENT_PRO=entlfa0ee126b6in.env. - Credits = pennies: Set
CREDITS_PENNIES_PER_USD=100(default) so 1 USD top-up adds 100 credits (pennies). SetORG_ADMIN_SIGNUP_CREDITS,SUBSCRIPTION_UPGRADE_CREDITS,MOBILE_APP_PURCHASE_CREDITSfor credits granted per purchase (defaults 200, 200, 360). - Billable cost:
BILLABLE_FEATURE_COST_USD(default 0.10) is the USD amount shown in 402 for predictions, agents, green finance when credits are insufficient. - x402 / MetaMask: Configure
X402_ENABLED,X402_FACILITATOR_URL,X402_NETWORK,X402_TOKENfor web/MetaMask payments. - Plaid: Configure
PLAID_*for linking;PLAID_COST_USDis the base cost per call;PLAID_MARKUP_PERCENTadds markup. Banking (dashboard refresh) uses the same credit/402 flow. - Brokerage:
BROKERAGE_TRANSFER_FEE_CREDITS(default 0) = credits per fund/withdraw; 0 = no fee.
9. Troubleshooting
| Symptom | Check |
|---|---|
| Entitlement always false | REVENUECAT_ENABLED=true, REVENUECAT_API_KEY=sk_... set in project root .env. Entitlement identifier in dashboard (e.g. entlfa0ee126b6) matches REVENUECAT_ENTITLEMENT_PRO. User identified in RevenueCat with same app_user_id (CreditNexus user ID). |
| 503 RevenueCat not enabled | Set REVENUECAT_ENABLED=true and restart the server. |
| Grant entitlement fails | Verify Secret API key has permission to grant entitlements. Check dashboard API keys and that the key is Secret (sk_). Check server logs for RevenueCat API error message. |
| Mobile purchase not reflected | Ensure client calls POST /api/subscriptions/revenuecat/purchase with the correct product_id after purchase, and that the user is logged in (so current_user.id matches the RevenueCat app_user_id). |
10. References
- RevenueCat: Getting Started, Projects & Authentication, Products Setup
- CreditNexus configuration: Configuration — RevenueCat
- Payment systems: Payment Systems