TROUBLESHOOTING
Troubleshooting - iOS
Common integration issues, their causes, and how to resolve them. If you're coming from Apple StoreKit, a few behaviors differ — those are called out below.
Products don't appear or the catalog is empty​
SKProductsRequest returns no products (or fewer than expected), usually without an error. This is almost always a configuration mismatch on the Xsolla side rather than a code issue. Check, in order:
- Wrong
projectId. An incorrectprojectIdstill connects successfully and simply returns an empty catalog — no error is thrown. Verify it against your Publisher Account. - Items not published. Every item must be published / active in Publisher Account. Draft items are not returned.
- SKU mismatch. The SKUs you request must match the Publisher Account SKUs exactly, including case and separators (for example, dots vs. underscores).
Purchases don't restore, or there's no "Restore" button to wire up​
Restoration in this SDK is automatic, and there is no manual restore call to invoke — restoreCompletedTransactions() is a no-op. See Purchase Restoration Settings for how local restoration and the Xsolla Events API work. Consumable balances are recovered through your own backend or the Xsolla Inventory.
"Application doesn't support login scheme" / "...payments redirect scheme"​
The SDK routes login and Pay Station redirects back to your app through a URL scheme, and logs one of these errors if the scheme isn't registered. The SDK cannot modify your Info.plist — register the scheme once:
- Add a URL scheme equal to your bundle identifier (
$(PRODUCT_BUNDLE_IDENTIFIER)). See URL scheme setup. The single bundle-id scheme covers both login and payments. - The redirect URLs (
redirectUrl,paymentsRedirectUrl) already default to bundle-id-based values, so you don't normally need to set them.
Device ID login needs no return URL. Device-ID (anonymous) login is a client-side identifier exchange — there is no browser redirect and nothing to register in Publisher Account for it. Just enable Device ID login for your project. A redirect URL only becomes relevant for browser-based login flows.
"User is not logged in" when starting a purchase​
The SDK requires an authenticated session before it can create an order, and a purchase attempted before authentication fails with User is not logged in. Make sure authentication completes at startup, before the first purchase:
- If your game authenticates with device-ID login, confirm Device ID login is enabled for your project.
- If your game supplies its own Xsolla Login token, confirm
settings.customLoginTokenis set to a valid, non-expired token before you start the payment queue — see Setting the Login Token.
Main Thread Checker warning when starting a purchase​
SKPaymentQueue.default().add(_:) drives UIKit presentation and should be called on the main thread. If you start a purchase from an async Task or a background queue, the Main Thread Checker may flag it. Dispatch to the main thread:
- Objective-C
- Swift
dispatch_async(dispatch_get_main_queue(), ^{
[[SKPaymentQueue defaultQueue] addPayment:payment];
});
await MainActor.run {
SKPaymentQueue.default().add(payment)
}
Hosts the SDK connects to (firewall / allowlisting)​
If your network tooling or firewall restricts outbound traffic, allowlist the Xsolla hosts the SDK uses:
| Purpose | Host |
|---|---|
| Store API (catalog, orders, inventory) | store.xsolla.com |
| Pay Station (checkout) | secure.xsolla.com — or sandbox-secure.xsolla.com when useSandbox = true |
| Login | login.xsolla.com |
Harmless console warnings​
Console output such as Couldn't read values in CFPrefsPlistSource... kCFPreferencesAnyUser... is harmless and can be safely ignored — it does not affect payments or SDK behavior.