link,[object Object]
Skip to content

RevenueCat (BYO) – Implementation Plan

Scope: verify mobile IAP/subscription revenue by connecting sellers’ own RevenueCat accounts (BYO – Bring Your Own). Zero cost for AcqMarketplace; sellers cover any RevenueCat plan costs.


1. Goals / Non‑Goals

  • Goals
    • Enable “Verified via RevenueCat” for listings monetized via IAP/subscriptions (Apple/Google, optionally Stripe web via RC).
    • Safely collect aggregates: MTR, net revenue, refunds, active subscribers, churn, ARPU, trends.
    • Zero PII in UI; strict RLS; store read‑only keys in Vault.
    • Hourly cron sync for free plans; near‑real‑time only if the seller has webhooks enabled.
  • Non‑Goals
    • No verification for ads, affiliate revenue, or off‑platform marketplace fees.
    • No guarantee of total business revenue; only IAP/subscription via RC.

2. User Stories

  • As a Seller, I can connect my RevenueCat account (read‑only key), select the project/app, and see a “Verified via RevenueCat (IAP only)” badge.
  • As a Buyer, I can see a badge and a clear tooltip about what is verified (IAP only) plus aggregated trends.
  • As an Admin, I can see sanity checks (production vs sandbox, refund rate, spikes) and last sync status.

3. Constraints & Risks

  • Coverage: IAP/subscriptions only; mixed monetization remains partially verified.
  • Ownership: require bundleId/packageName ≈ listing match; otherwise risk of “fake project”.
  • Latency: without webhooks → hourly cron; UI displays "Last synced".
  • Currency: normalize to platform currency (USD) with historical FX.
  • Rate limits: backoff + pagination; staggered initial backfill.

4. High‑Level Architecture

  • UI (Seller):
    • Settings → Integrations → RevenueCat: form with read‑only key, "Test connection" button, Project/App selector, environment toggle (Production only).
  • Edge Functions (Supabase):
    • revenuecat-test-connection: validates the key and enumerates allowed Projects/Apps.
    • revenuecat-sync: runs via hourly cron, fetches day windows, aggregates and stores.
    • (optional) revenuecat-webhook: if the seller’s plan supports webhooks, ingest events and perform idempotent upserts.
  • DB (Supabase): tables for integration config and daily aggregates (see §5).
  • Security: keys in Vault; RLS on seller‑scoped rows; UI shows aggregates only.

5. Data Model (Supabase)

  • Table: seller_integrations

    • id uuid pk
    • seller_id uuid ref users
    • type text check in ('revenuecat')
    • project_id text
    • app_id text
    • environment text check in ('production')
    • api_key_readonly_secret_ref text (Vault reference)
    • bundle_ids text[] (for matching/ownership)
    • connected_at timestamptz, last_synced_at timestamptz, status text ('active'|'error')
  • Table: revenues_daily

    • id uuid pk
    • seller_id uuid
    • app_id text
    • date date
    • currency text (original)
    • mtr_gross numeric
    • refunds numeric
    • net_revenue numeric (mtr_gross - refunds)
    • active_subscribers integer
    • new_subscriptions integer
    • churn_rate numeric
    • arpu numeric
    • currency_usd_rate numeric
    • net_revenue_usd numeric (derived)
    • unique (seller_id,app_id,date)
  • Table: integration_audit

    • id uuid pk, seller_id, source text ('revenuecat'), at timestamptz, level text, message text, meta jsonb
  • RLS

    • seller_id = auth.uid() for user‑scoped rows; admin role sees all.

6. API Surface (Edge Functions)

  • POST /functions/v1/revenuecat-test-connection

    • body: { apiKey: string }
    • response: { ok: boolean, projects: Array<{id,name,apps:Array<{id,name,bundleIds}>}> }
  • POST /functions/v1/revenuecat-sync

    • body: { sellerId?: string } (invoked by cron per seller)
    • action: fetch metrics by day (last N days/backfill), upsert revenues_daily, update last_synced_at
  • POST /functions/v1/revenuecat-webhook (optional)

    • validates signature (if enabled), performs idempotent upserts
  • Notes

    • All functions validate role; sellers can only act on own seller_id.
    • Idempotency via composite keys (seller_id, app_id, date) + safe upserts.

7. RevenueCat API Usage

  • Auth: Authorization: Bearer <read-only-key>
  • Endpoints (indicative; match current API):
    • List Projects/Apps: enumerate for setup flow.
    • Metrics: daily aggregates for MTR, subscribers, refunds.
  • Pagination & Rate Limits: implement cursor‑based pagination, exponential backoff.
  • Environments: accept only production on setup; filter sandbox/test.

8. Security & Privacy

  • Store key in Supabase Vault; never log secrets.
  • Mask secrets in UI; support revoke/regenerate.
  • Aggregate‑only in UI; no App User IDs/PII.
  • Audit logs in integration_audit.
  • RLS enforced; admin can see cross‑seller metrics in Admin panel.

9. UX Spec

  • Seller → Settings → Integrations → RevenueCat
    • Step 1: Paste read‑only key → Test connection
    • Step 2: Select Project + App (with bundleIds visible) → Confirm
    • Step 3: Verify bundleId matches listing → Save → Start initial sync
    • State: "Last synced X minutes ago"; status badges (OK/Error); Re‑sync button
  • Listing Page
    • Badge: "Verified via RevenueCat (IAP only)" + clarifying tooltip
    • Charts: 30/90d net revenue (USD), active subs, churn, refunds rate
    • Empty/Fallback states for sellers not connected

10. Rollout Plan

  1. Data model + RLS + Edge function skeletons
  2. Seller UI for connection + test connection
  3. Cron hourly sync (Supabase Scheduler)
  4. Listing badges + minimal charts (lazy load)
  5. Admin sanity checks dashboard
  6. Optional webhooks support

11. Testing

  • Unit: RC response parsing, currency normalization, idempotent upserts
  • E2E: connect flow, sync visible in UI, RLS off‑role denial
  • Observability: audit logs, error rates, sync duration, rate‑limit handling
  • Sandbox hygiene: strict environment=production filtering

12. Risks & Mitigations

  • Partial revenue (non‑IAP): communicate clearly via badge + tooltip
  • Ownership spoofing: bundleId checks + optional DNS/app‑file verification
  • Sync latency: hourly cron + visible timestamp; webhook optional
  • Currency variance: daily FX snapshot; recompute on view if missing

13. Open Questions

  • Support Stripe‑via‑RC for web or ask for direct Stripe as alternative?
  • Minimum threshold for public metrics (k‑anonymity)?
  • Initial backfill window (90d? 180d?) and rate‑limit caps?

14. Acceptance Criteria (MVP)

  • Seller can connect RC, select Project/App, save config in Vault + DB.
  • Cron sync runs and produces rows in revenues_daily with net_revenue_usd.
  • Listing shows badge + at least 2 charts (revenue, active subs) with "Last synced".
  • Admin sees sanity checks (refund rate, sandbox ratio, spikes) per seller/app.
  • RLS tested; no secrets/PII in UI or logs.