-
Notifications
You must be signed in to change notification settings - Fork 412
Add purchaseInterruptedError for UPI/external payment app flows #6207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
When users complete purchases via third-party payment apps (e.g., UPI in India), switching to the external app causes AMSError.paymentSheetFailed to be returned. This error was previously mapped to PURCHASE_CANCELLED, even though the user may be completing (not cancelling) the payment. This change: - Adds new error code `purchaseInterruptedError` (code 43) - Tracks app background state during in-flight purchases - When AMSError.paymentSheetFailed is received AND app was backgrounded, returns `purchaseInterruptedError` instead of `purchaseCancelledError` - `purchaseInterruptedError.isCancelledError` returns false, so `userCancelled` will be false for interrupted purchases Developers should handle this error by calling `getCustomerInfo()` to verify actual entitlement status. Fixes #6194 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Store notification observer and remove in deinit to prevent leaks - Clean up purchaseBackgroundedState in handlePurchasedTransaction (SK1) - Clean up purchaseBackgroundedState in handleDeferredTransaction - Add test for UPI/external payment app interrupted flow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add purchaseInterruptedError (code 43) to the public API baseline. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The error message for storeProblemError differs between macOS and iOS. Update test to handle both platforms. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7d51c3d to
03569a2
Compare
…ction Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| Logger.debug(Strings.purchase.purchase_interrupted_external_app( | ||
| productIdentifier: skError.userInfo["productId"] as? String ?? "unknown" | ||
| )) | ||
| return ErrorUtils.purchaseInterruptedError(error: error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I think changing the return error code in this case is a kind of behavioral breaking change... For example, we will likely need to update our hybrids to handle this appropriately as well... Maybe we could do it if we do a major, but maybe it's worth exposing this information some other way for now...
Could we maybe add this information as part of the error's userInfo or something like that? for devs that want to handle this differently than a normal cancellation? Not sure how common this use case would be. If developer should handle this case differently than a cancellation, then maybe this is ok. If it's uncommon, let's avoid the behavior change if we can 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, cc @ajpallares , not sure if this can have any effects on the RCT project we're working on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think about this 🤔
I think I like it? Given that introducing a breaking change will most likely open other doors for issues.
rickvdl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting edge case, thanks for digging into this!
Maybe this also affects RCT and / or is a potential case we should cover there, so it might make sense if @ajpallares could also have a look at it.
Summary
When users complete purchases via third-party payment apps (e.g., UPI in India), switching to the external app causes
AMSError.paymentSheetFailedto be returned. This error was previously mapped toPURCHASE_CANCELLED, even though the user may be completing (not cancelling) the payment.Changes
purchaseInterruptedError(code 43, codeNamePURCHASE_INTERRUPTED)purchaseBackgroundedStateAMSError.paymentSheetFailedis received AND app was backgrounded during purchase, returnspurchaseInterruptedErrorinstead ofpurchaseCancelledErrorpurchaseInterruptedError.isCancelledErrorreturnsfalse, souserCancelledwill befalsefor interrupted purchasesBehavior
userCancelledpurchaseCancelledErrortruepurchaseInterruptedErrorfalseDeveloper Guidance
When receiving
purchaseInterruptedError, developers should callgetCustomerInfo()to verify actual entitlement status, as the payment may have succeeded in the external app.Test plan
ErrorCodeTestspass (including newtestPurchaseInterruptedError)Addresses #6194