# Migrating from StoreKit

OnsideKit is modeled on StoreKit's original (`SKPaymentQueue`-based) API, so most concepts map directly. This page lists the equivalents and the differences worth knowing.

## Type mapping

<table><thead><tr><th width="340">StoreKit</th><th>OnsideKit</th></tr></thead><tbody><tr><td><code>SKPaymentQueue.default()</code></td><td><code>Onside.defaultPaymentQueue()</code></td></tr><tr><td><code>SKPayment</code></td><td><code>OnsidePayment</code></td></tr><tr><td><code>SKPaymentTransaction</code></td><td><code>OnsidePaymentTransaction</code></td></tr><tr><td><code>SKPaymentTransactionState</code></td><td><code>OnsidePaymentTransactionState</code></td></tr><tr><td><code>SKPaymentTransactionObserver</code></td><td><code>OnsidePaymentTransactionObserver</code></td></tr><tr><td><code>SKProductsRequest</code></td><td><code>OnsideProductsRequest</code> (via <code>Onside.makeProductsRequest(productIdentifiers:)</code>)</td></tr><tr><td><code>SKProductsRequestDelegate</code></td><td><code>OnsideProductsRequestDelegate</code></td></tr><tr><td><code>SKProduct</code></td><td><code>OnsideProduct</code></td></tr><tr><td><code>SKProductSubscriptionPeriod</code></td><td><code>OnsidePeriod</code></td></tr><tr><td><code>finishTransaction(_:)</code></td><td><code>finishTransaction(_:)</code></td></tr><tr><td><code>restoreCompletedTransactions()</code></td><td><code>restoreCompletedTransactions(completion:)</code></td></tr></tbody></table>

## Key differences

* **Queue accessor.** Use `Onside.defaultPaymentQueue()` — not `SKPaymentQueue.default()`, and not `Onside.paymentQueue()`.
* **Completion arguments are required.** `add(_:completion:)` and `restoreCompletedTransactions(completion:)` take a non-defaulted `completion` (pass a closure or `nil`). The completion reports only the pre-flight outcome (e.g. `.loginDiscarded`); transaction updates still arrive via the observer.
* **Login is built in.** OnsideKit presents login on demand when a purchase/restore needs it — there's no separate StoreKit-style account check. See [Authentication & User Account](/sdk/core-concepts/authentication.md).
* **Product identifiers are Onside slugs.** `OnsideProduct.productIdentifier` is the identifier you configure in the Onside console and request with — not an App Store SKU.
* **`appAccountToken` via mutation.** `OnsidePayment`'s only initializer is `init(product:)`; set `appAccountToken` by mutating the value (`var payment = OnsidePayment(product:); payment.appAccountToken = ...`).
* **Resilient enums.** OnsideKit enums are non-frozen; include `@unknown default` in `switch` statements. See [Threading & Object Lifetime](/sdk/core-concepts/threading-and-retention.md).
* **Storefront safety gate.** When the storefront/price changes for a queued purchase, OnsideKit asks your [`OnsidePaymentQueueDelegate`](/sdk/purchasing/storefront-price-changes.md) before continuing.


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.onside.io/sdk/reference/migrating-from-storekit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
