Before you write app code, make sure the AppActor project, apps, store connections, and catalog behind that code actually exist. This page uses a safe fake catalog so you can copy the structure without exposing a real app. If offerings.current is null, a helper like monthly is empty, or a purchase screen has nothing to render, the issue is often upstream catalog setup rather than SDK installation.
Start with Project and Store Setup if you have not added your iOS or Android app yet. Add Server Notifications before launch so renewals, refunds, billing retry, and voided purchases reach AppActor quickly.

Safe example catalog

Use example project/app names in docs and tutorials. Do not screenshot real app names, secret keys, webhook URLs, JWTs, or store credentials.

What your app expects

Your mobile app expects AppActor to already know:
  • which public app SDK key belongs to the running app
  • which store products belong to iOS and Android
  • which entitlement keys represent premium access
  • which offering should be returned as current
  • which package slots such as monthly and annual are populated inside the offering
  • which products unlock which entitlements

First catalog recipe

For a RevenueCat/Qonversion-style starter catalog, create this exact shape first:
  1. Entitlement: premium.
  2. iOS products: com.example.fitness.pro_monthly and com.example.fitness.pro_annual.
  3. Android products: pro_monthly and pro_annual, with basePlanId and offerId filled when Google Play uses them.
  4. Product mapping: every monthly and annual product unlocks premium.
  5. Offering: default, marked as current.
  6. Packages: monthly and annual, each mapped to the correct iOS and Android products.
  7. SDK key: use the platform app’s public pk_... key in the client.
Once this works, you can add lifetime products, custom packages, experiments, or additional offerings without changing the entitlement key your app checks. Sanitized product mapping and current offering dashboard state

Done-when checklist

Use this checklist before you open app code:

1. Copy the public SDK key

The pk_... value used in configure(...) is the public client key for a specific AppActor app. Use the matching key for the app you are integrating. If you run different keys per platform, wrappers should use the platform-key surfaces instead of one shared string. Flutter and React Native wrappers should use AppActorPlatformKeys when iOS and Android apps have separate public keys.
Never use project secret keys (sk_...) in a mobile app. Secret keys are only for your backend.

2. Define entitlements first

Entitlements are the access concepts your app gates on, such as:
  • premium
  • pro
  • plus
Your client app should make access decisions from customer entitlements, not from product IDs alone. That means the entitlement model needs to be defined before the app can reason about premium state correctly. Dashboard fields to keep stable:
  • Display name: human-friendly, such as Premium.
  • Key: stable app-facing identifier, such as premium.
  • Attached products: every product that should unlock the entitlement.
  • Notes: optional internal explanation for support or billing teams.

3. Connect store products

Create the real products in:
  • App Store Connect for iOS
  • Google Play Console for Android
Then connect those products into AppActor so the purchase catalog can map store items back to entitlements and offerings. If store credentials or package identifiers are not healthy yet, finish Project and Store Setup before trying to debug SDK calls. Product fields to verify:

4. Attach products to entitlements

Every product that should unlock premium access must be attached to the entitlement your app checks. If the customer buys com.example.fitness.pro_monthly but that product is not attached to premium, the purchase can finish while hasActiveEntitlement("premium") still returns false.

5. Build at least one offering

An offering is the server-defined purchase bundle your app fetches before it renders UI. For a basic rollout, make sure you have:
  • one current offering
  • one or more package entries inside that offering
  • package-to-product mappings that line up with the store products you created
Offering fields to verify:
  • Offering ID or lookup key, such as default or onboarding.
  • Current offering flag for the default paywall.
  • Package order, so the paywall renders intentionally.
  • Optional metadata for badges, copy, placement-specific labels, or experiment variants.

6. Populate package slots intentionally

Most quickstarts use helpers like:
  • current?.monthly
  • current?.annual
  • current?.lifetime
Those helpers only work when the matching package slot exists in the offering. If your app uses custom package identifiers instead of the common slot names, document that in your app code and avoid assuming the built-in helpers will be present.

7. Sanity-check the catalog before app integration

Before you debug client code, confirm all of these are true:
  • the public app SDK key is the one you expect to ship
  • the app has at least one current offering
  • the offering contains the packages your paywall expects
  • the package slots used in code are actually populated
  • the mapped products unlock the entitlement keys your app gates on

Runtime chain

Common failure patterns

If the SDK configures correctly but your paywall is empty, check this order:
  1. Is the SDK using the right pk_... key?
  2. Does the project have a current offering?
  3. Does that offering include the package slot your code reads?
  4. Does the package map to a real store product for that platform?
If purchase succeeds but access does not unlock, check this order:
  1. Is the product attached to the premium entitlement?
  2. Did the app refresh customer info after purchase?
  3. Is the entitlement status active or valid grace?
  4. Is the customer using the same stable appUserId?
  5. Is verification trusted enough for the feature you are unlocking?

Debug by symptom

Next pages

Entitlements

Define stable access keys and attach products before checking access in app code.

Products and Packages

Learn why AppActor fetches offerings and packages instead of exposing a cross-platform getProducts() call.

Offerings

Fetch the current offering and select monthly, annual, lifetime, or custom package slots.

Displaying Products

Map packages into your own paywall cards with prices, descriptions, metadata, and empty states.

Making Purchases

Purchase a package, handle success/cancelled/pending, and unlock from customer info.
After catalog setup, continue with Install the SDKs and Quickstart. Before release, verify Server Notifications and run through Testing and Go Live.