Hey @philippe levieux!
Just wanted to provide this answer here since we discussed this in a support ticket. We'll send a payment pending error in the completion block of a deferred purchase. You can see this implementation in GitHub here: https://github.com/RevenueCat/purchases-ios/blob/395322ac7ef437f6b2f880b2057559b11954bdc4/Sources/Purchasing/PurchasesOrchestrator.swift#L540
For those looking for a code sample of what cody is saying... `Purchasing/purchase` will throw a `RevenueCat.ErrorCode.paymentPendingError` when the user enters the ask to buy flow. So you will need to catch that error and handle it according to your specific needs.
If you are using async/await:
do {
let (transaction, customerInfo, userCancelled) = try await Purchases.shared.purchase(package: package)
} catch(RevenueCat.ErrorCode.paymentPendingError) {
} catch(let error) {
throw error
}
If you prefer completion blocks:
Purchases.shared.purchase(package: package, completion: { transaction, customerInfo, error, userCancelled in
if let error {
if let errorCode = error as? ErrorCode {
switch errorCode {
case .paymentPendingError:
default:
}
} else {
}
}
})
The purchase will now be pending until the approving party finally approves it. You can catch this event by adopting the `PurchasesDelegate` protocol in your `AppDelegate` or elsewhere, then check for the entitlement in the updated `customerInfo`
extension AppDelegate : PurchasesDelegate {
func purchases(_ purchases: Purchases, receivedUpdated customerInfo: CustomerInfo) {
if customerInfo.entitlements["your_entitlement_id"]?.isActive == true {
// user has access to "your_entitlement_id"
}
}
}
I do question the framework design decision of throwing an error in this situation, as the purchase did not really fail. It feels like deferred should probably be part of the should probably be part of the `PurchaseResultData` tuple, much like the `userCancelled`, but this is the way the framework is designed, and this is how to handle it.