-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[in_app_purchase] Fix an issue causing StoreKit 2 transactions remain unfinished #10656
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
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.
Code Review
This pull request correctly fixes an issue where StoreKit 2 transactions were left unfinished. The introduction of a restoring flag to distinguish between new and restored purchases is a solid approach, ensuring that new purchases get the correct purchased status and can be properly completed by the client. The accompanying test updates effectively validate this fix.
I've added one minor suggestion for code clarity. Also, while I understand you skipped running the auto-formatter to ease the review, please ensure it's run before merging to comply with the repository's style guidelines.
| case .verified(let purchase): | ||
| self.sendTransactionUpdate( | ||
| transaction: purchase, receipt: "\(completedPurchase.jwsRepresentation)") | ||
| transaction: purchase, receipt: "\(completedPurchase.jwsRepresentation)", restoring: true) |
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.
The string interpolation "\()" around completedPurchase.jwsRepresentation is redundant because jwsRepresentation is already a String. You can simplify the code by passing the property directly for better readability and to adhere to Swift best practices.
transaction: purchase, receipt: completedPurchase.jwsRepresentation, restoring: trueReferences
- The repository style guide requires following language-specific style guides (lines 10-12). In Swift, it's best practice to avoid redundant operations like wrapping an existing string in string interpolation for code clarity. (link)
|
I had overlooked the Swift tests under I've validated that the new assertions fail before this change. |
Also resolve an issue where SK2 purchase updates are in state `restoring`. Keep track of when TransactionMessages are created in the restorePurchases code path, instead of incorrectly inferring that transactions with receipts are from the restore code path. This keeps ordinary purcahses as state `purchased`. These purchase detail records will also have `pendingCompletePurchase` set to `true`, since this is gated by state `purchased`.
b0c41ab to
626cb28
Compare
The StoreKit 2 (iOS, MacOS) in_app_purchase backend causes ordinary client use (eg. the
in_app_purchaseexample app) to leave transactions in an unfinished state, contrary to the StoreKit contract.This happens because StoreKit 2 purchase updates have
pendingCompletePurchase == false, causing clients to not callcompletePurchase(flutter/flutter#180046). This in turn happens because purchase updates incorrectly have staterestoredinstead ofpurchased(flutter/flutter#172434).Fix this by keeping track of which TransactionMessages are created in the restorePurchases code path to set the
restoringfield correctly. Previously it was set whenever a transaction had receipt data (which is also true for ordinary purchase updates). This keeps ordinary purcahses as statepurchased. These purchase records will also havependingCompletePurchaseset totrue, since this is gated by statepurchased.Fixes:
Pre-Review Checklist
[shared_preferences]pubspec.yamlwith an appropriate new version according to the pub versioning philosophy, or I have commented below to indicate which version change exemption this PR falls under1.CHANGELOG.mdto add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.///).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2 ↩3