# API Reference

> Complete reference for every function, delegate, async action, struct, and enum in RevenueCat Bridge.

Markdown version of https://rigbak.com/docs/revenuecat-bridge/api-reference, a page of the RevenueCat Bridge documentation. Link that page when citing it.

Everything lives on `URevenueCatSubsystem`, a `GameInstanceSubsystem` with one instance per game session, accessible from anywhere.

**In C++:**

```cpp
URevenueCatSubsystem* RC = GetGameInstance()->GetSubsystem<URevenueCatSubsystem>();
```

**In Blueprints:** search for "RevenueCat" in the action palette. All functions are in the **RevenueCat** category.

---

## Project Settings

**Location:** Project Settings > Plugins > RevenueCat

These are stored in `URevenueCatSettings` (a `DeveloperSettings` subclass) and saved to `DefaultGame.ini`.

| Setting | Type | Description |
| --- | --- | --- |
| `AndroidApiKey` | `FString` | RevenueCat public API key for Android |
| `IosApiKey` | `FString` | RevenueCat public API key for iOS |
| `bAutoFetchOfferings` | `bool` | Fetch offerings once after configure (default `true`). |
| `bAutoFetchCustomerInfo` | `bool` | Fetch customer info once after configure (default `true`) so `IsEntitlementActive` is truthful on cold launch. |
| `bAutoFetchVirtualCurrencies` | `bool` | Fetch virtual currency balances after configure and refresh them after each purchase (default `false`). Turn on when your project uses virtual currencies. |
| `bEnableDebugLogs` | `bool` | Verbose SDK logging. Turn on during development, turn off before shipping. |

---

## Functions

### SDK Lifecycle

| Function | Returns | Description |
| --- | --- | --- |
| `ConfigureSDK(ApiKey)` | `void` | Initialize the SDK with an API key. Called automatically on startup using the key from Project Settings. You only need to call this manually if you want to override the key at runtime. |
| `IsConfigured()` | `bool` | Whether the SDK has been configured. |

### Offerings

| Function | Returns | Description |
| --- | --- | --- |
| `FetchOfferings()` | `void` | Fetch available offerings from RevenueCat. Results come back through `OnOfferingsFetched`. |
| `GetCachedOfferings()` | `TArray<FRevenueCatOffering>` | Returns offerings from the last `FetchOfferings` call. Empty if you haven't fetched yet. |
| `GetCurrentOffering(OutOffering)` | `bool` | Gets the offering marked "current" in the dashboard. Returns `false` if nothing is cached. |
| `FindPackageByID(PackageID, OutPackage)` | `bool` | Find a package by its RevenueCat PackageID (e.g. `"$rc_monthly"`). Searches all cached offerings. |
| `FindPackageByProductID(ProductID, OutPackage)` | `bool` | Find a package by the store product ID (e.g. `"com.yourapp.monthly_sub"`). Searches all cached offerings. |

### Purchases

| Function | Returns | Description |
| --- | --- | --- |
| `PurchasePackage(Package)` | `void` | Trigger the native purchase flow for a package. Results come back through `OnPurchaseCompleted`. |
| `RestorePurchases()` | `void` | Restore previous purchases (e.g. after reinstall). Results through `OnPurchasesRestored`. |
| `SyncPurchases()` | `void` | Force-sync pending receipts with RevenueCat servers. Results through `OnCustomerInfoUpdated`. |

### Customer Info

| Function | Returns | Description |
| --- | --- | --- |
| `FetchCustomerInfo(FetchPolicy)` | `void` | Fetch customer info from RevenueCat. Results through `OnCustomerInfoUpdated`. `FetchPolicy` defaults to `Default` (cached); pass `FetchCurrent` to force a live read, for example on foreground to catch an expiry. |
| `GetCachedCustomerInfo()` | `FRevenueCatCustomerInfo` | Returns cached customer info from the last fetch. |
| `IsEntitlementActive(EntitlementID)` | `bool` | Check if a specific entitlement is active. Uses cached data - call `FetchCustomerInfo()` first if you need fresh data. |

### Virtual Currencies

Virtual currencies are coin, gem, or credit balances you configure in the RevenueCat dashboard. The SDK reads balances; it cannot spend them. A balance changes through a store-purchase grant or your backend calling the RevenueCat API. Needs virtual currencies configured in the dashboard, and the bundled SDKs already meet the version floor (iOS 5.32+ / Android 9.1+).

| Function | Returns | Description |
| --- | --- | --- |
| `FetchVirtualCurrencies()` | `void` | Fetch the current user's balances from RevenueCat. Results come back through `OnVirtualCurrenciesUpdated`. |
| `GetCachedVirtualCurrencies()` | `TArray<FRevenueCatVirtualCurrency>` | Returns balances from the last fetch. Empty if you haven't fetched yet. |
| `GetVirtualCurrencyBalance(Code)` | `int32` | Balance for one currency by its dashboard code (e.g. `"GLD"`). Reads cached data; returns 0 when the code is unknown or nothing is cached. |
| `InvalidateVirtualCurrenciesCache()` | `void` | Drop the SDK's cached balances so the next `FetchVirtualCurrencies()` reads from the network. Call after your backend changes a balance. |

### User Identity

| Function | Returns | Description |
| --- | --- | --- |
| `LogIn(AppUserID)` | `void` | Identify a user with a custom ID. Links purchases to this ID across devices. Results through `OnCustomerInfoUpdated`. |
| `LogOut()` | `void` | Revert to an anonymous RevenueCat ID. Results through `OnCustomerInfoUpdated`. |
| `GetAppUserID()` | `FString` | Get the current RevenueCat App User ID (anonymous IDs start with `$RCAnonymousID:`). |
| `IsAnonymous()` | `bool` | Whether the current user is anonymous. |

### Subscriber Attributes

| Function | Description |
| --- | --- |
| `SetFirebaseAppInstanceId(AppInstanceId)` | Set Firebase App Instance ID for RevenueCat's Firebase integration. This plugin has no Firebase dependency; get the ID from your own Firebase setup. |
| `SetAttributes(Attributes)` | Set arbitrary key-value pairs as subscriber attributes. Takes a `TMap<FString, FString>`. |
| `SetEmail(Email)` | Set subscriber's email (reserved attribute). |
| `SetDisplayName(DisplayName)` | Set subscriber's display name (reserved attribute). |
| `SetPhoneNumber(PhoneNumber)` | Set subscriber's phone number (reserved attribute). |

### Attribution

| Function | Description |
| --- | --- |
| `SetMediaSource(MediaSource)` | Set media source (e.g. `"facebook_ads"`). |
| `SetCampaign(Campaign)` | Set campaign name. |
| `SetAdGroup(AdGroup)` | Set ad group. |
| `SetCreative(Creative)` | Set creative name. |
| `SetKeyword(Keyword)` | Set keyword. |
| `CollectDeviceIdentifiers()` | Auto-collect GAID (Android) / IDFA (iOS) and send to RevenueCat. Called automatically on SDK initialization - you only need to call this manually if you want to refresh identifiers later. |

All attribution functions are fire-and-forget. No callback. Verify the values in the RevenueCat dashboard under the customer's attributes.

### Subscription Management

| Function | Description |
| --- | --- |
| `ShowManageSubscriptions()` | Open the platform's subscription management page (Play Store or App Store). No-op on unsupported platforms. |
| `PresentCodeRedemptionSheet()` | iOS only. Open the App Store offer-code redemption sheet (iOS 14+). No-op on other platforms. |

### Paywall

These functions present RevenueCat's native paywall UI, designed and configured in the RevenueCat dashboard. Requires iOS 16+ or Android with Compose.

| Function | Returns | Description |
| --- | --- | --- |
| `PresentPaywall(OfferingID)` | `void` | Present the native paywall UI. Pass an empty string to show the current offering. Results through `OnPaywallCompleted`. |
| `PresentPaywallIfNeeded(EntitlementID)` | `void` | Present the paywall only when the entitlement is inactive. Checks live entitlement state and honors a cached entitlement when offline. Results through `OnPaywallCompleted`. |

---

## Events (Delegates)

Bind these in Blueprints via the **Assign** node from the subsystem's Events section, or in C++:

```cpp
RC->OnPurchaseCompleted.AddDynamic(this, &UMyClass::HandlePurchase);
```

| Delegate | Parameters | When It Fires |
| --- | --- | --- |
| `OnConfigured` | *(none)* | SDK initialization completed. |
| `OnOfferingsFetched` | `TArray<FRevenueCatOffering> Offerings` | Offerings fetched from RevenueCat. |
| `OnPurchaseCompleted` | `ERevenueCatPurchaseResult Result`, `FRevenueCatCustomerInfo CustomerInfo` | A purchase flow finished (success, cancel, error, or already owned). |
| `OnPurchasesRestored` | `FRevenueCatCustomerInfo CustomerInfo` | Restore purchases completed. |
| `OnCustomerInfoUpdated` | `FRevenueCatCustomerInfo CustomerInfo` | Customer info changed: purchase, restore, login, logout, fetch, or a background SDK update. Treat as idempotent; it can fire more than once for one change. |
| `OnVirtualCurrenciesUpdated` | `TArray<FRevenueCatVirtualCurrency> VirtualCurrencies` | Virtual currency balances fetched or refreshed. Carries all currencies; find the one you need by code. |
| `OnPaywallCompleted` | `ERevenueCatPaywallResult Result`, `FRevenueCatCustomerInfo CustomerInfo` | The native paywall was dismissed. Check the result for what happened (purchased, cancelled, restored, or error). |
| `OnError` | `FRevenueCatError Error` | Any error occurred. Check `ErrorCode` and `ErrorMessage`. |

---

## Async Blueprint Actions

These latent nodes derive from `UBlueprintAsyncActionBase` and provide **output execution pins** (OnSuccess / OnFailure / OnCancelled) directly in the Blueprint graph - no manual delegate binding needed.

Search for the node name in the Blueprint action palette (they are in the **RevenueCat** category).

### Fetch Offerings (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **OnSuccess** | `TArray<FRevenueCatOffering>` | Fired with the fetched offerings |
| **OnFailure** | `FRevenueCatError` | Fired on error |

### Purchase Package (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **Package** (input) | `FRevenueCatPackage` | The package to purchase |
| **OnSuccess** | `FRevenueCatCustomerInfo` | Fired when purchase succeeds or is already owned |
| **OnCancelled** | - | Fired when the user cancels the purchase flow |
| **OnFailure** | `FRevenueCatError` | Fired on error or pending purchase |

### Restore Purchases (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **OnSuccess** | `FRevenueCatCustomerInfo` | Fired with restored customer info |
| **OnFailure** | `FRevenueCatError` | Fired on error |

### Sync Purchases (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **OnSuccess** | `FRevenueCatCustomerInfo` | Fired with synced customer info |
| **OnFailure** | `FRevenueCatError` | Fired on error |

### Fetch Customer Info (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **FetchPolicy** (input) | `ERevenueCatCacheFetchPolicy` | Cache vs network policy (default `Default`); pass `FetchCurrent` to force a live read |
| **OnSuccess** | `FRevenueCatCustomerInfo` | Fired with the latest customer info |
| **OnFailure** | `FRevenueCatError` | Fired on error |

### Log In (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **AppUserID** (input) | `FString` | The custom user ID to log in with |
| **OnSuccess** | `FRevenueCatCustomerInfo` | Fired with the identified customer info |
| **OnFailure** | `FRevenueCatError` | Fired on error |

### Log Out (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **OnSuccess** | `FRevenueCatCustomerInfo` | Fired with the anonymous customer info |
| **OnFailure** | `FRevenueCatError` | Fired on error |

> **Note:** These async actions bind to the subsystem's delegates internally. The customer-info actions (Fetch Customer Info, Log In, Log Out, Sync Purchases) complete only on their own operation's result, not on a background SDK update. Avoid running two instances of the same action type at once, since they share a completion signal.

### Fetch Virtual Currencies (Async)

| Pin | Type | Description |
| --- | --- | --- |
| **OnSuccess** | `TArray<FRevenueCatVirtualCurrency>` | Fired with the fetched balances |
| **OnFailure** | `FRevenueCatError` | Fired on error |

### Present Paywall (Async)

Presents RevenueCat's native paywall UI. The paywall layout is configured in the RevenueCat dashboard.

| Pin | Type | Description |
| --- | --- | --- |
| **OfferingID** (input) | `FString` | Offering to display. Leave empty for the current offering. |
| **OnPurchased** | `FRevenueCatCustomerInfo` | Fired when the player completes a purchase through the paywall |
| **OnCancelled** | - | Fired when the player dismisses the paywall without purchasing |
| **OnRestored** | `FRevenueCatCustomerInfo` | Fired when the player restores purchases through the paywall |
| **OnFailure** | `FRevenueCatError` | Fired on error |

---

## Data Types

### Enums

#### `ERevenueCatPurchaseResult`

| Value | Meaning |
| --- | --- |
| `Success` | Purchase completed. |
| `UserCancelled` | User dismissed the purchase dialog. |
| `Error` | Purchase failed. Check `OnError` for details. |
| `AlreadyOwned` | User already owns this product. |
| `PendingPurchase` | Purchase is pending (e.g. parental approval, slow payment method). |

#### `ERevenueCatPaywallResult`

| Value | Meaning |
| --- | --- |
| `Purchased` | Player completed a purchase through the paywall. |
| `Cancelled` | Player dismissed the paywall without purchasing. |
| `RestoreCompleted` | Player restored purchases through the paywall. |
| `Error` | Something went wrong. Check `OnError` for details. |

#### `ERevenueCatProductType`

| Value | Meaning |
| --- | --- |
| `Subscription` | Auto-renewing subscription. |
| `NonConsumable` | One-time purchase, permanent. |
| `Consumable` | Consumable (can be bought again). |
| `Unknown` | Type not determined. |

#### `ERevenueCatPeriodType`

| Value | Meaning |
| --- | --- |
| `Normal` | Standard billing period. |
| `Intro` | Introductory offer period. |
| `Trial` | Free trial period. |

#### `ERevenueCatStore`

| Value | Meaning |
| --- | --- |
| `AppStore` | Apple App Store |
| `PlayStore` | Google Play Store |
| `Amazon` | Amazon Appstore |
| `Stripe` | Stripe (web) |
| `Promotional` | Granted via RevenueCat dashboard |
| `Unknown` | Unknown store |

#### `ERevenueCatCacheFetchPolicy`

| Value | Meaning |
| --- | --- |
| `Default` | Serve cached info if present, else fetch. Fast and offline-friendly (the SDK default). |
| `NotStaleCachedOrFetched` | Serve cached info while it is fresh, else fetch from the network. |
| `FetchCurrent` | Always fetch from the network, bypassing the cache. Use to catch a mid-session expiry. |
| `FromCacheOnly` | Serve cached info only; never hit the network. |

---

### Structs

#### `FRevenueCatProduct`

Represents a single store product (a subscription, one-time purchase, etc.).

| Field | Type | Description |
| --- | --- | --- |
| `ProductID` | `FString` | Store product identifier (e.g. `"com.yourapp.monthly"`) |
| `Title` | `FString` | Localized product title |
| `Description` | `FString` | Localized product description |
| `PriceString` | `FString` | Formatted price with currency symbol (e.g. `"$4.99"`) |
| `PriceMicros` | `int64` | Price in micros (4990000 = $4.99) |
| `CurrencyCode` | `FString` | ISO 4217 currency code (e.g. `"USD"`) |
| `ProductType` | `ERevenueCatProductType` | Subscription, NonConsumable, Consumable, or Unknown |
| `SubscriptionPeriod` | `FString` | ISO 8601 duration (e.g. `"P1M"` for monthly, `"P1Y"` for annual). Empty for non-subscriptions. |
| `IntroPriceString` | `FString` | Formatted intro price (e.g. `"$0.99"`) |
| `IntroPriceMicros` | `int64` | Intro price in micros |
| `IntroPricePeriod` | `FString` | ISO 8601 intro period (e.g. `"P1W"`) |
| `IntroPriceCycles` | `int32` | Number of intro billing cycles |
| `FreeTrialPeriod` | `FString` | ISO 8601 trial period (e.g. `"P7D"` for 7 days). Empty if no trial. |

#### `FRevenueCatPackage`

A package is a product wrapped in an offering context. This is what you pass to `PurchasePackage`.

| Field | Type | Description |
| --- | --- | --- |
| `PackageID` | `FString` | RevenueCat package identifier (e.g. `"$rc_monthly"`) |
| `PackageType` | `FString` | `MONTHLY`, `ANNUAL`, `LIFETIME`, `WEEKLY`, `CUSTOM`, etc. |
| `Product` | `FRevenueCatProduct` | The store product in this package |

#### `FRevenueCatOffering`

A group of packages. You configure these in the RevenueCat dashboard.

| Field | Type | Description |
| --- | --- | --- |
| `OfferingID` | `FString` | RevenueCat offering identifier |
| `DisplayName` | `FString` | Description you set in the dashboard |
| `bIsCurrent` | `bool` | Whether this is the "current" offering |
| `Packages` | `TArray<FRevenueCatPackage>` | Available packages in this offering |

#### `FRevenueCatEntitlement`

Represents access to a feature or content. This is what you check to gate premium content.

| Field | Type | Description |
| --- | --- | --- |
| `EntitlementID` | `FString` | The entitlement identifier (e.g. `"pro"`) |
| `bIsActive` | `bool` | Whether this entitlement is currently active |
| `ProductID` | `FString` | Product that unlocked this entitlement |
| `ExpirationDate` | `FString` | ISO 8601 expiration date. Empty if it's a lifetime purchase. |
| `bWillRenew` | `bool` | Whether the subscription will auto-renew |
| `PeriodType` | `ERevenueCatPeriodType` | Normal, Intro, or Trial |
| `Store` | `ERevenueCatStore` | Which store the purchase came from |
| `bIsSandbox` | `bool` | Whether this was purchased in sandbox/test mode |
| `PurchaseDate` | `FString` | ISO 8601 original purchase date |
| `LatestPurchaseDate` | `FString` | ISO 8601 latest purchase/renewal date |
| `UnsubscribeDetectedAt` | `FString` | ISO 8601 date unsubscribe was detected. Empty if still subscribed. |
| `BillingIssueDetectedAt` | `FString` | ISO 8601 date a billing issue was detected. Empty if no issues. |

#### `FRevenueCatCustomerInfo`

The full picture of a customer's purchases and subscriptions.

| Field | Type | Description |
| --- | --- | --- |
| `OriginalAppUserID` | `FString` | The original RevenueCat App User ID |
| `ActiveEntitlements` | `TArray<FRevenueCatEntitlement>` | Currently active entitlements (active only, mirroring RevenueCat's `entitlements.active`) |
| `AllPurchasedProductIDs` | `TArray<FString>` | Every product ID ever purchased |
| `FirstSeen` | `FString` | ISO 8601 date the user was first seen |
| `ManagementURL` | `FString` | URL to manage subscriptions. Can be empty. |
| `ActiveSubscriptions` | `TArray<FString>` | Product IDs with active subscriptions |

#### `FRevenueCatVirtualCurrency`

A virtual currency balance (coins, gems, credits) with its dashboard metadata. Read-only; the client cannot change a balance.

| Field | Type | Description |
| --- | --- | --- |
| `Code` | `FString` | Currency code from the dashboard (e.g. `"GLD"`) |
| `Name` | `FString` | Display name from the dashboard |
| `Balance` | `int32` | Current balance for this user |
| `ServerDescription` | `FString` | Optional description from the dashboard. Empty if none is set. |

#### `FRevenueCatError`

| Field | Type | Description |
| --- | --- | --- |
| `ErrorCode` | `int32` | RevenueCat error code |
| `ErrorMessage` | `FString` | Human-readable error message |

---

## Upgrading to 1.6.0

1.6.0 adds virtual currency balances. It is drop-in: no existing nodes, pins, or C++ signatures changed, so your Blueprints and code keep working after a rebuild.

- **New virtual currency API.** The `Fetch Virtual Currencies` node and `FetchVirtualCurrencies()` function read the player's balances, with `GetVirtualCurrencyBalance`, `GetCachedVirtualCurrencies`, `InvalidateVirtualCurrenciesCache`, and the `OnVirtualCurrenciesUpdated` event. See [Virtual Currencies](https://rigbak.com/docs/revenuecat-bridge/api-reference#virtual-currencies) above.
- **New `bAutoFetchVirtualCurrencies` setting** (off by default). Turn it on to fetch balances on startup and refresh them after each purchase.
- **Set up virtual currencies in the RevenueCat dashboard first.** Until you do, a fetch returns an empty array.

The client reads balances; it cannot spend them. Grant currency through a dashboard purchase rule or the RevenueCat backend API, then call `InvalidateVirtualCurrenciesCache()` and `FetchVirtualCurrencies()` after a backend change.

## Upgrading to 1.5.0

1.5.0 updates the bundled RevenueCat SDKs to Android 10.8.0 and iOS 5.78.0 (from 9.25.0 and 5.63.0). No nodes, pins, or C++ signatures changed, so your Blueprints and code keep working after a rebuild. Two things to handle on Android:

- **Set the project's Android `Minimum SDK Version` to 23 or higher.** RevenueCat 10 runs on Google Play Billing 8, which requires API 23 (Android 6.0). You set this under Project Settings > Platforms > Android. Below 23, the Android build fails at manifest merge.
- **Check your consumable product types.** RevenueCat 10 stops restoring consumed one-time products. If you sell consumables, confirm each one is set to the right type (consumable vs non-consumable) in the RevenueCat dashboard.

iOS needs nothing beyond a rebuild; the plugin ships the 5.78.0 frameworks, and the Android Compose runtime (now 1.7.0 / Material3 1.3.0) resolves through Gradle.

## Upgrading to 1.4.0

The 1.4.0 update is drop-in: no nodes or pins were removed or renamed, so existing Blueprints keep working after you refresh nodes. A few behaviors changed:

- **`Fetch Customer Info` gained a `Fetch Policy` input pin** (and the function gained an optional parameter). It defaults to `Default`, which matches the old behavior. Pass `FetchCurrent` to force a live read.
- **Bind `OnError` for purchase failures.** A failed purchase no longer reports through `OnPurchaseCompleted` with an `Error` result; it comes through `OnError` only. The Purchase Package async node already routes failures to `OnFailure`, so node users need no change.
- **Keep your `OnCustomerInfoUpdated` handler idempotent.** It now also fires after purchases and restores, and can fire more than once for a single change. Set state from `IsEntitlementActive` rather than granting additively.
- **`ActiveEntitlements` now lists active entitlements only.** If you looped over it expecting expired entries, they are gone. `IsEntitlementActive` is unchanged.
- **A cancelled or failed purchase no longer clears cached entitlements.** If you re-fetched after a cancel to work around that, you can remove it.

## Editor Stubs (Win64)

On non-mobile platforms (Win64 editor), every function in the subsystem compiles and runs. Instead of calling the native SDK (which doesn't exist on desktop), it logs a message and completes deterministically.

You can:

- Build and iterate on your Blueprint purchase flow in the editor
- Compile and test C++ code without a device
- Run PIE without crashes

The editor configures a stub on startup, so `IsConfigured()` returns `true` and `OnConfigured` fires. Every async operation completes its node instead of hanging: fetches return an empty result, and Purchase and Paywall report cancelled. There is no store, so no real entitlement is granted.

Previous page: [Getting Started](https://rigbak.com/docs/revenuecat-bridge/getting-started). Next page: [Testing & Troubleshooting](https://rigbak.com/docs/revenuecat-bridge/testing)
