Open
Conversation
- Add CardReaderReconnectionState enum with idle, reconnecting, succeeded, and failed states - Add reconnectionEvents publisher and cancelReconnection() to CardReaderService protocol - Add reconnectionCancellation error case to CardReaderServiceError - Implement reconnection delegate methods in StripeCardReaderService - Add no-op implementations to NoOpCardReaderService
- Add observeCardReaderReconnectionState action to publish reconnection state changes - Add cancelReconnection action to cancel in-progress auto-reconnection - Add CardReaderReconnectionState typealias to Model.swift - Implement action handlers in CardPresentPaymentStore
- Add reconnecting case to CardPresentPaymentReaderConnectionStatus - Add cancelReconnection() to CardPresentPaymentFacade protocol - Implement no-op cancelReconnection in CardPresentPaymentPreviewService - Handle reconnectionCancellation error in CardPresentPaymentsRetryApproach
- Subscribe to reconnection state publisher and map to connection status - Implement cancelReconnection() to dispatch cancel action - Cancel any ongoing reconnection before starting manual connection
- Add reconnecting case to CardReaderConnectionStatusView with spinner and cancel menu - Handle reconnecting case in TotalsView payment UI logic - Add cancelReconnection() method to PointOfSaleAggregateModel
- Add reconnection simulation methods to MockCardReaderService - Add tests for observeCardReaderReconnectionState action - Add test for cancelReconnection action - Update MockCardPresentPaymentService with cancelReconnection - Add cancelReconnection test to PointOfSaleAggregateModelTests - Update CardPresentPaymentServiceScreenshotMock
Collaborator
Generated by 🚫 Danger |
Collaborator
|
|
- Observe reconnection state in BluetoothCardReaderSettingsConnectedViewModel - Keep showing connected reader view during reconnection - Disable update/disconnect buttons and show spinner during reconnection
Cancel any ongoing auto-reconnection before initiating a new Bluetooth reader discovery to prevent conflicts.
Add cancelReconnection action handling to MockCardPresentPaymentsStoresManager and RefundSubmissionUseCaseTests to prevent test timeouts.
Update MainTabBarControllerTests to handle the .observeCardReaderReconnectionState action in the test action handler. Otherwise, initialization of CardPresentPaymentService stalls the test.
Configure the Stripe Terminal SDK to automatically attempt reconnection when a Bluetooth reader unexpectedly disconnects.
Update the didStartReconnect delegate method to use the new Stripe SDK signature that includes the disconnect reason parameter. Also clear connected readers when reconnection starts so the UI correctly shows the reconnecting state instead of connected.
When canceling reconnection, if the Stripe SDK returns error code cancelFailedAlreadyCompleted (1010), treat it as success rather than an error. This race condition occurs when reconnection completes naturally just before the cancel request is processed. Since the user's intent to stop reconnection was effectively achieved, there's no need to log an error.
Stripe: Adjust reconnection cancellation handler to avoid clearing connectedReaders when cancellation failed due to already-completed reconnection; only clear readers when cancellation actually succeeded or failed for other reasons, and ensure reconnectionState is set to .idle in the appropriate branches. Yosemite store: Replace .subscribe(Subscribers.Sink(...)) with .sink(...) and store the returned AnyCancellable in the cancellables set to retain the subscription. WooCommerce adaptor: Remove the preemptive await cancelReconnection() call from connectReader to avoid unnecessarily cancelling/interrupting concurrent reconnection logic before starting a manual connection.
- Show "Reconnecting to card reader..." status in connected view - Add "Cancel Reconnection" button during reconnection - Preserve reader info (name, battery, firmware) during reconnection - Prevent searching view from showing during reconnection - Refactor button states using enums for cleaner code
- Show reader info during reconnection via PointOfSaleSettingsController - Add reconnecting menu button with cancel option - Disable firmware update during reconnection - Add test for reconnecting state providing reader info - Update mock to support connection status directly
Show "Reconnecting reader..." message when reader is reconnecting during checkout. This prevents the confusing "Scanning for readers" popup by not auto-starting payment collection during reconnection.
Collaborator
|
Version |
Resolve merge conflicts between trunk's POSPaymentModel refactoring and the reconnection feature. Keep trunk's delegation pattern while preserving reconnection support (cancelReconnection, reconnecting UI state, and reconnection tests). Add reconnection handling to POSCardPaymentContentView and fix missing .reconnecting case in POSPaymentModel's switch statement.
…ment Cancel active reconnection before cancelling payment to prevent UI hangs when reader is in reconnecting state.
- Add cancelReconnection() to POSPaymentModel so both cart and bookings flows can cancel reconnection - Pass cancelReconnectionAction in POSPaymentContentView - Delegate cancelReconnection through paymentModel in aggregate model - Add @mainactor since calling paymentModel synchronously requires it
Set connected reader and reconnecting status before creating the aggregate model to avoid needing Task.sleep for state propagation.
…y async Merge the two separate Task blocks into one sequential block so cancellation completes before preflight starts. Use withCheckedContinuation to actually await the store action completion.
Replace inline TotalsViewHelper() and POSPaymentViewHelper() instantiations inside computed properties with existing stored properties to avoid redundant allocations on every SwiftUI body evaluation.
Set connectionStatus before creating the SUT so the initial publisher value is already .connected when the subscription starts, removing the need for a fragile 100ms sleep.
…edViewModel Log the error and reset readerReconnectionCancellationInProgress on failure to prevent the UI from being stuck in a permanent cancelling state.
Use .onChange(of: cardReaderConnectionStatus) so the flag resets whenever the connection status transitions, not only when the view appears.
Change from title case "Cancel Reconnection" to sentence case "Cancel reconnection" for consistency with all other button labels in the reconnection flow. Update localization key accordingly.
A no-op cancel should succeed rather than fail, consistent with how the real service treats cancellation when no reconnection is in progress.
All call sites provide a non-nil value, so the optional adds no safety and silently no-ops if accidentally nil. Matches connectCardReaderAction.
Only log the error when a reconnection was actually in progress to avoid noisy log output from expected SDK callbacks.
Contributor
Author
|
@joshheald @iamgabrielma I integrated the new pos payment model changes, retested everything, and made a few fixes. |
Collaborator
|
Version |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

WOOMOB-2028
Description
Implements Stripe Terminal SDK auto-reconnection delegate methods for Bluetooth card readers. When a reader unexpectedly disconnects, the SDK automatically attempts to reconnect. Previously, the app did not handle these events, leaving the app state out-of-sync with the card reader connection.
Android PR: woocommerce/woocommerce-android#15047
The PR:
I didn't make any changes to the IPP payment flow. The way it's structured is that the payment would just fail if the card reader is disconnected. User can just dismiss it, turn on / reconnect the reader, and start a card reader flow again.
Tests
Tested on
Scenarios
I implemented explicit handling in these scenarios:
Do you think there are any other places I should explicitly handle reconnection state? Otherwise, it happens in the background and immediately reconnects if the card reader connects again.
Cases
In different scenarios, attempt to connect, and then disconnect (turn off) the reader.
Videos
POS Floating Button
POS.-.Floating.bar.MP4
POS Settings
ScreenRecording_01-30-2026.18-09-38_1.MP4
POS Payment
reconnection.in.payment.MP4
Payment -> Manage Card Reader
ScreenRecording_01-30-2026.17-37-54_1.MP4
POS Bookings
pos.bookings.reconnection.MP4
POS Payment Flow with disconnection and reconnection during the payment
ScreenRecording_03-10-2026.16-23-27_1.MP4
IPP Payment flow with disconnection and manual reconnection
It's not handled explicitly. The PR is large enough, but most importantly, the flow is not blocked.
IPP.Flow.mov