> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uptopia.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# In-app Purchases

> Define IAP packages for your apps, backed by contracts managed by UptopiaKit, and integrate them using the default IAP App Event.

# In-app Purchases

In-app Purchases (IAP) in UptopiaKit let you define **packages that your users can buy inside your app**. UptopiaKit:

* Provides a dashboard to configure IAP packages for each app/version.
* Writes and keeps the package configuration **on-chain / on contract** on your behalf.
* Exposes these packages to your app via the **default `IAP` App Event**.
* Triggers a payment UI (currently using **Base Pay**) when the user initiates a purchase.

Your app remains in control of **how these packages are presented and how they affect gameplay or features**.

## Defining IAP packages

For each application, developers can create multiple IAP packages in the UptopiaKit dashboard. Every package has:

* **Name** — human-readable label shown in your app (e.g. “100 Gems”, “Premium Pass”).
* **Description** — longer text describing what the user gets.
* **Package ID** — a unique identifier you will reference from your app (e.g. `gems_100`, `season_pass_s1`).
* **Price** — the price for the package (denominated according to the payment gateway / chain).

When you save or update an IAP package, **UptopiaKit automatically writes the configuration to the underlying contract**, so the source of truth for IAP pricing and metadata is always on-chain and consistent across clients.

## How IAP works at runtime

At runtime, a typical IAP flow in your app looks like this:

1. **On app/game load**, your app asks UptopiaKit for the list of available IAP packages for the current version using the default `IAP` App Event with `type: "LIST"`.
2. UptopiaKit returns a **list of IAP packages** (name, description, price, packageId, etc.) to your app.
3. Your app **renders a shop UI** (or any in-game purchase entry points) based on that data.
4. When the user chooses a package to buy, your app sends the default `IAP` App Event with `type: "BUY"` and the target `packageId`.
5. UptopiaKit opens the **payment UI (currently via Base Pay)** and guides the user through payment.
6. When the payment finishes (success/failure), UptopiaKit sends a **result message back to your app** so you can update state, grant entitlements, and show feedback.

All communication uses the **App Events** mechanism. For full payload/response shapes, see:\
[/kit/core-concepts/app-events](/kit/core-concepts/app-events)

## Integrating IAP in your app

IAP integration is built on the default `IAP` App Event. There are two main operations: `LIST` and `BUY`.

### 1. Fetch packages with `IAP` + `LIST`

On app or scene load, request the list of IAP packages defined for the current app/version:

```js theme={null}
// Request available IAP packages
window.parent.postMessage({
  name: "IAP",
  data: {
    type: "LIST",
  },
});

// Listen for the response
window.addEventListener("message", (event) => {
  // TODO: validate event.origin in production
  const res = event.data;

  if (res?.type === "IAP_LIST") {
    const packages = res.payload;
    // packages: Array<{
    //   id: string;
    //   name: string;
    //   packageId: string;
    //   price: number;
    //   description: string;
    //   gameId: string;
    //   status: "active" | "inactive";
    // }>

    // Use this to render your in-game shop / purchase options.
  }
});
```

UptopiaKit ensures that the list corresponds to the **current app version and environment**.

### 2. Trigger a purchase with `IAP` + `BUY`

When a user clicks “Buy” in your UI, send a `BUY` request for the corresponding `packageId`:

```js theme={null}
// Trigger a purchase for a specific package
window.parent.postMessage({
  name: "IAP",
  data: {
    type: "BUY",
    packageId: "your-package-id-here",
  },
});

// Listen for the result
window.addEventListener("message", (event) => {
  const res = event.data;

  if (res?.type === "IAP_RES") {
    // { status: 0 | 1, packageId?: string }
    const { status, packageId } = res.payload;

    if (status === 1) {
      // Payment success: grant the purchased item / currency
      // grantPurchaseToUser(packageId);
    } else {
      // Payment failed or cancelled: show error or do nothing
    }
  }
});
```

* UptopiaKit will open a **payment interface via Base Pay** so the user can complete the transaction.
* Your app should **only grant items/benefits after receiving a successful result**.

For more details on the `IAP` event contract (`IAP_LIST`, `IAP_RES`), see the **IAP section** in:\
[/kit/core-concepts/app-events](/kit/core-concepts/app-events)

## Responsibilities: UptopiaKit vs your app

UptopiaKit is responsible for:

* Providing a dashboard to **create and manage IAP packages**.
* **Writing package configuration to contract** based on what you configure.
* Serving the **current list of packages** to your app via the `IAP` App Event.
* Triggering and handling the **payment UX** with supported gateways (currently **Base Pay**).
* Returning a clear **payment result** to your app.

Your app is responsible for:

* Designing and rendering the **shop / purchase UI** (what to show, where, and how).
* **Interpreting IAP packages** (how each package affects gameplay, items, or features).
* Handling **success/failure** results from UptopiaKit and updating your local state accordingly.
* Any additional **anti-fraud, entitlement sync, or inventory management** in your own systems.

In other words: **UptopiaKit provides the packages, contract integration, and payments; your app owns the logic and experience.**

## Monitoring IAP history and income

UptopiaKit also provides a dashboard view so developers can **track purchases and income over time** for each app:

* A **History** view inside the **IAP** section.
* An **Incomes** view for approved, live versions.

These two views are intentionally separated by app/version state:

* **History (inside IAP):**

  * Shows the **purchase history for app versions that are still in development** or otherwise **not yet approved** by UptopiaKit.
  * Useful for testing IAP flows, trying different prices, or running internal QA.
  * Lets you see test transactions and early-stage data without mixing them into production income.

* **Incomes:**
  * Shows **purchase history and income for app versions that have been reviewed and approved by the UptopiaKit team and are currently go-live**.
  * Includes charts and summaries of income so you can track real revenue over time.
  * If your app **does not yet have any approved/live version**, this section will be unavailable (you will not be able to view Incomes until at least one version is approved and live).

This separation helps you clearly distinguish between:

* **Test / development purchases** (visible in IAP → History).
* **Real production revenue** (visible in Incomes for approved live versions).

## Server-side validation (webhook, in development)

For apps with their own backend, you may want to **validate purchases on the server** and store purchase history in your own database.

UptopiaKit is adding support for this flow:

1. In your app’s **Settings**, you configure a **webhook URL** for IAP events.
2. When a user completes (or fails) a payment, UptopiaKit will send a **webhook request** to your backend containing:
   * User identifier info (e.g. wallet, platform userId).
   * The `packageId` and other package metadata.
   * The transaction status and relevant payment details.
3. Your backend can then:
   * Store the purchase in your own database.
   * Reconcile entitlements / inventory.
   * Combine webhook data with the in-app `IAP_RES` event to ensure consistency.

> **Important:** This webhook-based server-side validation feature is **under active development and not yet available in production**. Until it is live, you should rely on the in-app `IAP_RES` event for granting purchases and can add your own additional checks where needed.

## Related topics

* App Events (including full `IAP` event contract): [/kit/core-concepts/app-events](/kit/core-concepts/app-events)
* Apps overview: [/kit/core-concepts/apps](/kit/core-concepts/apps)
* Versioning: [/kit/core-concepts/versioning](/kit/core-concepts/versioning)
* Teams and permissions: [/kit/core-concepts/teams](/kit/core-concepts/teams)
