> For the complete documentation index, see [llms.txt](https://docs.onside.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.onside.io/sdk/advanced-and-tooling/testing-installation-and-purchases.md).

# Testing Purchases

Test product loading, login, purchases, and restores with local simulation and a service-backed OnsideKit integration.

Use a bundled `.storekit` file to exercise the purchase lifecycle during development, then verify authentication and payment processing with your service-backed integration.

## Local purchase simulation

Pass the configuration file’s base name to initialization:

```swift
Onside.initialize(storeKitConfigurationName: "LocalProducts")
```

Products, purchases, and restores use the local simulation. For offline login, leave external login disabled and return `.local` from `OnsideDelegate.onsideLoginMethod()`.

The simulation uses the same payment queue, transaction states, and observer callbacks. Check product loading, cancellation, transaction finishing, restores, and your handling of storefront changes.

See [Local Testing with a .storekit File](/sdk/advanced-and-tooling/local-testing.md) for setup, supported fields, resetting purchase history, and unavailable APIs.

## External-account purchases

Use an iOS build connected to the service to verify [external login](/sdk/core-concepts/external-login.md). A `.storekit` file does not reproduce a real external profile or its purchase restrictions.

Check the following flows:

* A missing external identifier falls back to the selected `.auto` or `.local` login route.
* After external login, subscriptions and non-consumables move to `unsupportedProductIdentifiers`.
* Buying a previously loaded unsupported product fails with `.notSupportedForExternalLogin` before enqueueing.
* A consumable purchase without Apple Pay fails with `.applePayRequired`.
* The payment methods manager fails with `.notSupportedForExternalLogin`.
* A successful consumable purchase delivers transaction updates and presents the receipt reminder.

Also check your app’s account-switching behavior: changing or removing the external delegate does not replace an existing SDK session. Sign out before switching the SDK to another account.

## Phone login and presentation

The phone-login UI recognizes sandbox phone numbers in the `+999` range. Use credentials provided for your service environment; this is not an offline login bypass and does not define a universal verification code.

Test SDK screens from both portrait and landscape host views and, where applicable, while resizing the app’s window. Verify that the host window regains focus and the host’s supported orientations are restored after the SDK UI closes. See [The Onside Delegate](/sdk/customization/delegate.md#orientation-and-window-resizing).

## See also

* [Local Testing](/sdk/advanced-and-tooling/local-testing.md) — offline purchase simulation.
* [Apple Pay](/sdk/purchasing/apple-pay.md) — configure real payment processing.
* [OnsideKit vs OnsideKitLite](/sdk/advanced-and-tooling/onsidekit-lite.md) — choose the SDK build.
* [Debugging & installationId](/sdk/advanced-and-tooling/debugging.md) — logs and identifiers.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.onside.io/sdk/advanced-and-tooling/testing-installation-and-purchases.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
