Repository navigation
[in_app_purchase_storekit] Complete StoreKit 2 finish when the transaction is not found - #13037
Conversation
…ction is missing finish(id:) only called its completion when fetchTransaction found the transaction. Transaction.all excludes finished consumables by default, so a second completePurchase() for an already finished consumable never completed. Always call the completion after the lookup, and drop the unused throws from fetchTransaction so no error can be silently lost inside the Task. Fixes flutter/flutter#192400
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request modifies the StoreKit 2 implementation to ensure finish(id:completion:) completes successfully when a transaction is not found, matching StoreKit 1 behavior. It also removes the throws specifier from fetchTransaction(by:) and adds unit tests to verify finishing already completed transactions. Feedback recommends using UInt64(bitPattern:) instead of UInt64(id) to avoid potential runtime crashes from negative signed integers.
|
cc @LongCatIsLooong :) |
flutter/packages@54706bd...d8d9e97 2026-10-09 [email protected] [pigeon] Reject unsupported native interop features and fix generated code that doesn't compile (flutter/packages#13153) 2026-10-09 [email protected] [material_ui] Fix ExpansionTile WidgetSpan semantics assertion (flutter/packages#12765) 2026-10-08 [email protected] [in_app_purchase_storekit] Complete StoreKit 2 `finish` when the transaction is not found (flutter/packages#13037) 2026-10-08 [email protected] [video_player] Fix crash when videoTrack has zero-duration minFrameDuration (flutter/packages#12796) 2026-10-08 [email protected] [google_maps_flutter_platform_interface] Add map background color configuration (flutter/packages#13014) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/packages@54706bd...d8d9e97 2026-10-09 [email protected] [pigeon] Reject unsupported native interop features and fix generated code that doesn't compile (flutter/packages#13153) 2026-10-09 [email protected] [material_ui] Fix ExpansionTile WidgetSpan semantics assertion (flutter/packages#12765) 2026-10-08 [email protected] [in_app_purchase_storekit] Complete StoreKit 2 `finish` when the transaction is not found (flutter/packages#13037) 2026-10-08 [email protected] [video_player] Fix crash when videoTrack has zero-duration minFrameDuration (flutter/packages#12796) 2026-10-08 [email protected] [google_maps_flutter_platform_interface] Add map background color configuration (flutter/packages#13014) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
StoreKit 2
finish(id:completion:)only calledcompletionwhenfetchTransactionfound the transaction.fetchTransactionsearchesTransaction.all, which by default does not contain finished consumables, so a secondcompletePurchasefor a consumable that was already finished (for example after a duplicate delivery) returned aFuturethat never completed. The StoreKit 1 path already treats a missing transaction as success (testFinishTransactionSucceedsWithNilTransaction).This PR:
completion(.success(Void()))after the lookup whether or not a transaction was found.throwsfromfetchTransaction, which has no throwing call. This rules out the second hang the issue describes (an error thrown inside theTaskinfinishand never reported) and clears the Xcode 27 warningunstructured throwing task ... may accidentally ignore errors thrown inside the task. The one test caller drops its now unneededtry.testFinishTransactionSucceedsWhenAlreadyFinished, which purchases a consumable and finishes it twice; the secondfinishtimes out without the fix and passes with it.testFinishTransactionalso check that the purchase is no longer unfinished, since its completion alone no longer proves the transaction was found.Tested with the iOS
RunnerTestson an iOS 26.2 simulator, the CI destination.This only makes the
Futurecomplete; it does not change which transactions StoreKit redelivers.Fixes flutter/flutter#192400
Pre-Review Checklist
[shared_preferences]///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.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