Skip to article
ActivationPal/docs
Browse docsRevenueCat webhook

RevenueCat webhook

Wire RevenueCat to ActivationPal so revenue, trials, and churn land as rc_* events next to your client events.

SDK events carry a device_id; RevenueCat events carry the RevenueCat app user id. Pass the RevenueCat app user id to configure — Purchases.shared.appUserID in native Swift, Purchases.sharedInstance.appUserID in native Android, await Purchases.appUserID in Flutter, or await Purchases.getAppUserID() in React Native (quickstart.md, android.md, flutter.md, react-native.md) — to join them. Purchases then land on the buying device's timeline, revenue splits by country and pricing tier, and the revenue chart, revenue mix, and RevenueCat-health cards populate.

View Markdown

Setup

RevenueCat dashboard → Project → Integrations → Webhooks → New webhook:

Field Value
Webhook URL the app-specific URL shown in the ActivationPal setup checklist
Environment Production
Event types all

Enable HMAC webhook signing, then paste and save the signing secret in the ActivationPal setup checklist (also available in app settings). The secret is encrypted at rest and is never returned after saving. The checklist shows secret saved until a production event arrives; app tracking and RevenueCat delivery are verified separately. ActivationPal verifies X-RevenueCat-Webhook-Signature against the untouched request body and rejects later cross-app mismatches.

Use one webhook per store application. If a product ships separately on iOS and Android, create two ActivationPal apps and scope the matching RevenueCat webhook to each store app. The client SDK's ap_pk_... key is only for event ingest and must not be used as webhook authentication.

What arrives

Each supported lifecycle event is stored as rc_ + the lowercased RevenueCat type, with its provider fields in props:

rc_initial_purchase, rc_renewal, rc_cancellation, rc_uncancellation, rc_expiration, rc_billing_issue, rc_non_renewing_purchase, rc_product_change, rc_subscription_paused, rc_subscription_extended, rc_refund_reversed, rc_transfer

Dashboard semantics:

  • Trial start = rc_initial_purchase with period_type: "TRIAL" — price 0, counted as a trial, not revenue.
  • Trial conversion = rc_renewal with is_trial_conversion: true — counted as new-subscriber revenue, not a renewal.
  • Refund = rc_cancellation with cancel_reason: "CUSTOMER_SUPPORT".
  • One-time purchase = rc_non_renewing_purchase.
  • Transfer = rc_transfer — transferred_from/transferred_to arrays, attributed to the receiving user.
  • Revenue on every surface = sum of positive price props on rc_* events (gross).

Each event is stamped with the last device that reported the same user id (or an alias) via the SDK — that places purchases on user timelines and city-level geo. RevenueCat's event id is stored uniquely: webhook retries never double-count. Net revenue is derived from RevenueCat's tax and commission estimates when available.

Coding-agent responsibilities

Install the SDK, instrument onboarding/paywall events and 5–10 product events, and use the RevenueCat app user ID to join both sources. Verify SDK delivery separately from revenue delivery. The user creates the webhook and saves its signing secret in the setup checklist; SDK delivery alone does not complete revenue setup. Never put the webhook signing secret in app code, logs, or Git. Keep the complete webhook URL unchanged.

Gotchas

  • SANDBOX events are stored env=debug, outside release numbers — set the environment to Production. Test purchases with paywall_purchased from a DEBUG build instead.
  • No userId, no join: rc_* events still arrive and total correctly, but user timelines and funnel-to-revenue joins stay empty.
  • Rotating the SDK API key (apps.md) does not affect the webhook. Rotate the signing secret in RevenueCat and ActivationPal together.
  • ActivationPal returns non-2xx for invalid or transiently failed deliveries so RevenueCat can retry them.

Verify

After a production purchase (or the next real renewal): dashboard live feed, or with an agent API key (agent-api.md):

curl -s "https://activationpal.com/api/v1/get_events?app=myapp&source=revenuecat" \
  -H "Authorization: Bearer $AP_KEY"