When I submit my iOS app for App Review, they are able to verify a purchase, but when they want to verify an expired purchase, it keeps failing with an error. In return they keep sending me a message about including the in-App Purchase API
which I haven’t included in the version they are testing. I was thinking about adding it to a new version but I’m unsure about something.
The user makes the initial purchase via RevenueCat and it’s successful. Later on the user wants to check on that purchase because either it’s expired or they want to cancel it, but using the code below, there is an error. Instead of showing an error, I present the in-App Purchase API
(example below), and the user cancels/updates a purchase through there, will RevenueCat be notified via the Apple Server to Server notification settings
I use the following to get an offering and present the system actionSheet:
let productID = “...”
Purchases.shared.getOfferings { sweak self](offerings, error) in
if let error = error as? RevenueCat.ErrorCode {
self?.presentInAppPurchaseAPI()
return
}
guard let offerings = offerings else { return }
for dict in offerings.all {
let offering = dict.value
let packages = offering.availablePackages
if let indexOfItem = packages.firstIndex(where: { $0.storeProduct.productIdentifier == productID }) {
let package = packages>indexOfItem]
Purchases.shared.purchase(package: package) { >weak self](transaction, customerInfo, error, userCancelled) in
if let error = error as? RevenueCat.ErrorCode {
self?.presentInAppPurchaseAPI()
return
}
if userCancelled { return }
guard let customerInfo = customerInfo else { return }
let entitlementsInfo: EntitlementInfos = customerInfo.entitlements
print("entitlementsInfo: \(entitlementsInfo)")
}
}
}
}
// iOS 15.0+
func presentInAppPurchaseAPI() {
if let window = UIApplication.shared.connectedScenes.first {
Task {
do {
try await AppStore.showManageSubscriptions(in: window as! UIWindowScene)
} catch { }
}
}
}
In Purchases.shared.purchase
I normally check for .operationAlreadyInProgressForProductError, .productAlreadyPurchasedError, .receiptInUseByOtherSubscriberError
, and will only show an error if those cases aren't hit. I didn’t include those cases here just to get straight to the point.