Code
1
SDK error · code 1
What it means
purchaseCancelledError (code 1) means the customer closed the purchase sheet, so nothing was bought and nothing is broken. Do not show an error. Check the userCancelled flag the SDK passes with it, leave the paywall as it was, and let the customer try again. The Test Store dialog's Cancel button raises it too.
Code
1
iOS (Swift)
ErrorCode.purchase
Android (Kotlin)
PurchasesErrorCode.Purchase
Causes
StoreKitError.userCancelled and the SDK maps it here.SKError.paymentCancelled or overlayCancelled.SKError 907 whose underlying AMSError code is 6 (payment sheet failed). The SDK treats that as a cancel as well (source).USER_CANCELED when the customer leaves the billing flow (Google docs), and the Android SDK maps it here.Fix
Do not show an error dialog. In the Swift async API, read userCancelled on the result. In the completion-handler API and on Android, the callback receives a userCancelled flag next to the error.
Leave the paywall open with its products loaded so the customer can pick again. Do not reload offerings.
Track cancels apart from failures in your analytics. A cancel is a funnel step, not a bug.
Turn on debug logs and read the underlying error. It shows whether StoreKit or Play Billing reported the cancel.
In your app
// Swift
do {
let result = try await Purchases.shared.purchase(package: package)
} catch let error as ErrorCode where error == .purchaseCancelledError {
// handle purchase cancelled
}
// Kotlin
if (error.code == PurchasesErrorCode.PurchaseCancelledError) { /* ... */ } On RevenueDot: RevenueDot never sees a cancelled purchase. The SDK stops before it posts a receipt to POST /v1/receipts, so no server setting changes this.
FAQ
No. A cancel is the customer's choice. Check the userCancelled flag, keep the paywall open, and show nothing.
In Swift, read userCancelled on the purchase result, or compare the error with ErrorCode.purchaseCancelledError in the completion-handler API. In Kotlin, PurchaseErrorCallback.onError receives the error and a userCancelled boolean.
In React Native, compare error.code with PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR. In Flutter, convert the PlatformException with PurchasesErrorHelper.getErrorCode(e) and compare the result with PurchasesErrorCode.purchaseCancelledError. The userCancelled field on the React Native error is also true for a cancel.
Get started
RevenueDot answers the same SDK calls with the same error codes. Start free on RevenueDot Cloud, free up to $10,000 a month in tracked revenue.
Already have an account? Sign in · Prefer your own servers? Self-host free