AppActor follows the same purchase architecture you may know from RevenueCat-style systems, with one important SDK detail:
AppActor does not expose a cross-platform getProducts() SDK call. Fetch offerings, then display and purchase the packages inside those offerings.

Example catalog

Use fake values like this in docs, tutorials, and test apps: Never put project secret keys (sk_...) in a mobile app. Use them only from your backend.

The model

Product

A product is the AppActor record that points at a platform store product. It is app/platform-scoped because the App Store and Google Play have different product identifiers, base plans, offers, and setup health. Examples:
  • iOS product: com.example.fitness.pro_monthly
  • Android product: pro_monthly with an optional basePlanId and offerId
  • Product setup health: warns when the product is not attached to an entitlement
Dashboard fields to verify:

Entitlement

An entitlement is the access key your app gates on. Most apps start with one entitlement:
Your app should not ask “did the user buy the monthly product?” for access. It should ask:
That keeps access stable when you add annual, lifetime, winback, trial, or platform-specific products later.

Offering

An offering is the server-defined collection your app fetches before rendering a purchase screen. The current offering can be changed from the dashboard without shipping a new app build. Use the current offering for default paywalls:

Package

A package is what the SDK displays and purchases. It maps one paywall slot, such as monthly or annual, to the correct platform product for the running app. Packages can include:
  • id
  • packageType
  • productId
  • storeProductId
  • basePlanId
  • offerId
  • localizedPriceString
  • price
  • currencyCode
  • displayName
  • productName
  • productDescription
  • metadata
  • tokenAmount
  • position
  • offeringId

Why packages instead of product IDs

Hardcoding product IDs in your UI makes experiments and platform parity painful. Packages let you:
  • show monthly and annual without caring whether the running platform is iOS or Android
  • change paywall contents from the dashboard
  • preserve display order from the offering
  • attach metadata for badges like “Best value”
  • keep purchase calls tied to the offering and placement where the user saw the package

Quick sanity check

If a paywall is empty or a purchase does not unlock access, check this chain in order:
  1. Public app SDK key is the right pk_... key for the running app.
  2. Current offering exists for the project.
  3. Offering has packages such as monthly and annual.
  4. Each package maps to the platform store product for the running app.
  5. Each product is attached to the entitlement your app checks.
  6. After purchase, CustomerInfo.hasActiveEntitlement("premium") becomes true.
Next, fetch the catalog with Offerings, render it with Displaying Products, then purchase with Making Purchases.