What does Product.PurchaseError.ineligibleForOffer mean?
Product.PurchaseError.ineligibleForOffer means the customer is not eligible for the offer that the purchase tried to use.
Quick facts#
| Error | Product.PurchaseError.ineligibleForOffer |
| Where | StoreKit 2, Swift (Product.purchase(options:)) |
| Available since | iOS 15.0, iPadOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0 |
| What the vendor says | The user is not eligible for the offer. |
Cause#
- Apple says the App Store treats customers with an existing or expired subscription in the app as eligible for a promotional offer. A customer without one is not eligible (Implementing promotional offers).
- Introductory offers have their own rule:
isEligibleForIntroOfferis true when the customer is eligible for an introductory offer on the subscription or on any subscription in the same group (isEligibleForIntroOffer). - A customer who already redeemed the introductory offer in that group is no longer eligible.
Fix#
- Check eligibility before you show the offer:
Product.SubscriptionInfo.isEligibleForIntroOfferfor introductory offers, and your own rules plus the customer's subscription history for promotional offers. - Show the standard price when the customer is not eligible, instead of an offer that will fail.
- Apple notes that eligibility can be true even when you have not set up an introductory offer, so also check that the offer exists on the product.
- Do not retry. The result stays the same until the customer's eligibility changes.
Example#
Swift
import StoreKit
// Ask the App Store whether this customer can get the introductory offer before you advertise it.
func showPrice(for product: Product) async {
guard let subscription = product.subscription else { return }
let eligible = await subscription.isEligibleForIntroOffer
print(eligible ? "Show the introductory offer" : "Show the standard price")
}
func buy(_ product: Product, options: Set<Product.PurchaseOption>) async {
do {
_ = try await product.purchase(options: options)
} catch Product.PurchaseError.ineligibleForOffer {
print("Not eligible for this offer; fall back to the standard price")
} catch {
print("Purchase failed: \(error)")
}
}Compile-checked: npm run check:snippets type-checks this snippet with swiftc against the Apple SDK (macOS target, checked 2026-10-03).
How the RevenueDot SDK reports it#
The RevenueDot purchases-ios fork maps Product.PurchaseError.ineligibleForOffer to ErrorCode.ineligibleError (code 18). See what ineligibleError means for the SDK side.
Related#
- What does Product.PurchaseError.invalidOfferIdentifier mean?
- What does Product.PurchaseError.invalidOfferSignature mean?
- What does Product.PurchaseError.purchaseNotAllowed mean?
Source#
- Apple: Implementing promotional offers in your app
- Apple: isEligibleForIntroOffer
- Apple: Product.PurchaseError.ineligibleForOffer
- Apple: Product.PurchaseError
- RevenueDot purchases-ios: StoreKitError+Extensions.swift (how the SDK maps StoreKit 2 errors)
Checked: 2026-10-03