Skip to content

Commit 5d5677d

Browse files
authored
Merge pull request #8633 from woocommerce/issue/8290-ttpoi-setup-connection-loop
[Mobile Payments] Fix Tap to Pay on iPhone setup failures on second account
2 parents 2a0a022 + 009a740 commit 5d5677d

File tree

8 files changed

+158
-222
lines changed

8 files changed

+158
-222
lines changed

Hardware/Hardware/CardReader/StripeCardReader/StripeCardReaderService.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,11 @@ private extension StripeCardReaderService {
862862

863863
private extension StripeCardReaderService {
864864
private func setConfigProvider(_ configProvider: CardReaderConfigProvider) {
865-
readerLocationProvider = configProvider
865+
if !Terminal.hasTokenProvider() {
866+
readerLocationProvider = configProvider
866867

867-
let tokenProvider = DefaultConnectionTokenProvider(provider: configProvider)
868+
let tokenProvider = DefaultConnectionTokenProvider(provider: configProvider)
868869

869-
if !Terminal.hasTokenProvider() {
870870
Terminal.setTokenProvider(tokenProvider)
871871
}
872872
}

WooCommerce/Classes/ServiceLocator/ServiceLocator.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ final class ServiceLocator {
7979
private static var _cardReader: CardReaderService = NoOpCardReaderService()
8080
#endif
8181

82+
private static var _cardReaderConfigProvider: CommonReaderConfigProviding = CommonReaderConfigProvider()
83+
8284
/// Support for printing receipts
8385
///
8486
private static var _receiptPrinter: PrinterService = AirPrintReceiptPrinterService()
@@ -207,6 +209,10 @@ final class ServiceLocator {
207209
_cardReader
208210
}
209211

212+
static var cardReaderConfigProvider: CommonReaderConfigProviding {
213+
_cardReaderConfigProvider
214+
}
215+
210216
/// Provides the access point to the ReceiptPrinterService.
211217
/// - Returns: An implementation of the ReceiptPrinterService protocol.
212218
static var receiptPrinterService: PrinterService {
@@ -336,6 +342,14 @@ extension ServiceLocator {
336342
#endif
337343
}
338344

345+
static func setCardReaderConfigProvider(_ mock: CommonReaderConfigProviding) {
346+
guard isRunningTests() else {
347+
return
348+
}
349+
350+
_cardReaderConfigProvider = mock
351+
}
352+
339353
static func setReceiptPrinter(_ mock: PrinterService) {
340354
guard isRunningTests() else {
341355
return

WooCommerce/Classes/Yosemite/AuthenticatedState.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ class AuthenticatedState: StoresManagerState {
7575
CardPresentPaymentStore(dispatcher: dispatcher,
7676
storageManager: storageManager,
7777
network: network,
78-
cardReaderService: ServiceLocator.cardReaderService),
78+
cardReaderService: ServiceLocator.cardReaderService,
79+
cardReaderConfigProvider: ServiceLocator.cardReaderConfigProvider),
7980
ReceiptStore(dispatcher: dispatcher,
8081
storageManager: storageManager,
8182
network: network,

Yosemite/Yosemite.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@
108108
02FF056B23DED3670058E6E7 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 02FF056A23DED3670058E6E7 /* Media.xcassets */; };
109109
02FF056D23DEDCB90058E6E7 /* MockImageSourceWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02FF056C23DEDCB90058E6E7 /* MockImageSourceWriter.swift */; };
110110
02FF056F23E04F320058E6E7 /* MockMediaExportService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02FF056E23E04F320058E6E7 /* MockMediaExportService.swift */; };
111+
030C94A62971C73700F7F65D /* MockCommonReaderConfigProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 030C94A52971C73700F7F65D /* MockCommonReaderConfigProviding.swift */; };
112+
030C94A82971C96F00F7F65D /* CommonReaderConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 030C94A72971C96F00F7F65D /* CommonReaderConfigProvider.swift */; };
111113
031C1EAA27B1702800298699 /* WCPayCharge+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031C1EA927B1702800298699 /* WCPayCharge+ReadOnlyConvertible.swift */; };
112114
031C1EAC27B1873200298699 /* WCPayCardPresentReceiptDetails+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031C1EAB27B1873200298699 /* WCPayCardPresentReceiptDetails+ReadOnlyConvertible.swift */; };
113115
031C1EAE27B1877000298699 /* WCPayCardPresentPaymentDetails+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031C1EAD27B1877000298699 /* WCPayCardPresentPaymentDetails+ReadOnlyConvertible.swift */; };
@@ -541,6 +543,8 @@
541543
02FF056A23DED3670058E6E7 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
542544
02FF056C23DEDCB90058E6E7 /* MockImageSourceWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageSourceWriter.swift; sourceTree = "<group>"; };
543545
02FF056E23E04F320058E6E7 /* MockMediaExportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaExportService.swift; sourceTree = "<group>"; };
546+
030C94A52971C73700F7F65D /* MockCommonReaderConfigProviding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCommonReaderConfigProviding.swift; sourceTree = "<group>"; };
547+
030C94A72971C96F00F7F65D /* CommonReaderConfigProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonReaderConfigProvider.swift; sourceTree = "<group>"; };
544548
031C1EA927B1702800298699 /* WCPayCharge+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WCPayCharge+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
545549
031C1EAB27B1873200298699 /* WCPayCardPresentReceiptDetails+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WCPayCardPresentReceiptDetails+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
546550
031C1EAD27B1877000298699 /* WCPayCardPresentPaymentDetails+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WCPayCardPresentPaymentDetails+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
@@ -1382,6 +1386,7 @@
13821386
B56C1EC120EAE2E500D749F9 /* ReadOnlyConvertible.swift */,
13831387
B52E002D211A3F5500700FDE /* ReadOnlyType.swift */,
13841388
0271E1652509CF0100633F7A /* AnyError.swift */,
1389+
030C94A72971C96F00F7F65D /* CommonReaderConfigProvider.swift */,
13851390
);
13861391
path = Tools;
13871392
sourceTree = "<group>";
@@ -1727,6 +1732,7 @@
17271732
isa = PBXGroup;
17281733
children = (
17291734
D88303EF25E45E6F00C877F9 /* MockCardReaderService.swift */,
1735+
030C94A52971C73700F7F65D /* MockCommonReaderConfigProviding.swift */,
17301736
D87F27DA25E7E8EA006EC8C9 /* MockCardReader.swift */,
17311737
D8652E4726307A5000350F37 /* MockReceiptPrinterService.swift */,
17321738
);
@@ -2057,6 +2063,7 @@
20572063
02124DAE2431C11600980D74 /* Media+ProductImage.swift in Sources */,
20582064
DEFD6D9526443CA100E51E0D /* SitePluginStore.swift in Sources */,
20592065
26577517243D5E42003168A5 /* ProductCategoryUpdated.swift in Sources */,
2066+
030C94A82971C96F00F7F65D /* CommonReaderConfigProvider.swift in Sources */,
20602067
261CF1F1255B389F0090D8D3 /* PaymentGatewayStore.swift in Sources */,
20612068
E18FDAFE28F97EB9008519BA /* AppAccountToken.swift in Sources */,
20622069
02FF055023D983F30058E6E7 /* ExportableAsset.swift in Sources */,
@@ -2300,6 +2307,7 @@
23002307
B9AECD482851F28E00E78584 /* Order+CardPresentPaymentTests.swift in Sources */,
23012308
02124DB02431C18700980D74 /* Media+ProductImageTests.swift in Sources */,
23022309
0248B3672459020500A271A4 /* ResultsController+FilterProductTests.swift in Sources */,
2310+
030C94A62971C73700F7F65D /* MockCommonReaderConfigProviding.swift in Sources */,
23032311
B54EAF2121188C470029C35E /* EntityListenerTests.swift in Sources */,
23042312
02FF056F23E04F320058E6E7 /* MockMediaExportService.swift in Sources */,
23052313
DE6831DD26445B2B00E88B9E /* SitePluginStoreTests.swift in Sources */,

Yosemite/Yosemite/Stores/CardPresentPaymentStore.swift

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public final class CardPresentPaymentStore: Store {
1515

1616
/// Card reader config provider
1717
///
18-
private let commonReaderConfigProvider: CommonReaderConfigProvider
18+
private let commonReaderConfigProvider: CommonReaderConfigProviding
1919

2020
private var paymentGatewayAccount: PaymentGatewayAccount? {
2121
didSet {
@@ -51,10 +51,11 @@ public final class CardPresentPaymentStore: Store {
5151
dispatcher: Dispatcher,
5252
storageManager: StorageManagerType,
5353
network: Network,
54-
cardReaderService: CardReaderService
54+
cardReaderService: CardReaderService,
55+
cardReaderConfigProvider: CommonReaderConfigProviding
5556
) {
5657
self.cardReaderService = cardReaderService
57-
self.commonReaderConfigProvider = CommonReaderConfigProvider()
58+
self.commonReaderConfigProvider = cardReaderConfigProvider
5859
self.remote = WCPayRemote(network: network)
5960
self.stripeRemote = StripeRemote(network: network)
6061
super.init(dispatcher: dispatcher, storageManager: storageManager, network: network)
@@ -370,74 +371,6 @@ private extension CardPresentPaymentStore {
370371
onCompletion(publisher)
371372
}
372373
}
373-
private extension CardPresentPaymentStore {
374-
final class CommonReaderConfigProvider: CardReaderConfigProvider {
375-
var siteID: Int64?
376-
var readerConfigRemote: CardReaderCapableRemote?
377-
378-
public func setContext(siteID: Int64, remote: CardReaderCapableRemote) {
379-
self.siteID = siteID
380-
self.readerConfigRemote = remote
381-
}
382-
383-
public func fetchToken(completion: @escaping(Result<String, Error>) -> Void) {
384-
guard let siteID = self.siteID else {
385-
return
386-
}
387-
388-
readerConfigRemote?.loadConnectionToken(for: siteID) { result in
389-
switch result {
390-
case .success(let token):
391-
completion(.success(token.token))
392-
case .failure(let error):
393-
if let configError = CardReaderConfigError(error: error) {
394-
completion(.failure(configError))
395-
} else {
396-
completion(.failure(error))
397-
}
398-
}
399-
}
400-
}
401-
402-
public func fetchDefaultLocationID(completion: @escaping(Result<String, Error>) -> Void) {
403-
guard let siteID = self.siteID else {
404-
return
405-
}
406-
407-
readerConfigRemote?.loadDefaultReaderLocation(for: siteID) { result in
408-
switch result {
409-
case .success(let location):
410-
let readerLocation = location.toReaderLocation(siteID: siteID)
411-
completion(.success(readerLocation.id))
412-
case .failure(let error):
413-
if let configError = CardReaderConfigError(error: error) {
414-
completion(.failure(configError))
415-
} else {
416-
completion(.failure(error))
417-
}
418-
}
419-
}
420-
}
421-
}
422-
}
423-
424-
private extension CardReaderConfigError {
425-
init?(error: Error) {
426-
guard let dotcomError = error as? DotcomError else {
427-
return nil
428-
}
429-
switch dotcomError {
430-
case .unknown("store_address_is_incomplete", let message):
431-
self = .incompleteStoreAddress(adminUrl: URL(string: message ?? ""))
432-
return
433-
case .unknown("postal_code_invalid", _):
434-
self = .invalidPostalCode
435-
return
436-
default:
437-
return nil
438-
}
439-
}
440-
}
441374

442375
// MARK: Networking Methods
443376
private extension CardPresentPaymentStore {
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import Foundation
2+
import Hardware
3+
import Networking
4+
5+
public protocol CardReaderRemoteConfigLoading {
6+
func setContext(siteID: Int64, remote: CardReaderCapableRemote)
7+
}
8+
9+
public protocol CommonReaderConfigProviding: CardReaderRemoteConfigLoading & CardReaderConfigProvider {}
10+
11+
12+
final public class CommonReaderConfigProvider: CommonReaderConfigProviding {
13+
var siteID: Int64?
14+
var readerConfigRemote: CardReaderCapableRemote?
15+
16+
public init(siteID: Int64? = nil, readerConfigRemote: CardReaderCapableRemote? = nil) {
17+
self.siteID = siteID
18+
self.readerConfigRemote = readerConfigRemote
19+
}
20+
21+
public func setContext(siteID: Int64, remote: CardReaderCapableRemote) {
22+
self.siteID = siteID
23+
self.readerConfigRemote = remote
24+
}
25+
26+
public func fetchToken(completion: @escaping(Result<String, Error>) -> Void) {
27+
guard let siteID = self.siteID else {
28+
return
29+
}
30+
31+
readerConfigRemote?.loadConnectionToken(for: siteID) { result in
32+
switch result {
33+
case .success(let token):
34+
completion(.success(token.token))
35+
case .failure(let error):
36+
if let configError = CardReaderConfigError(error: error) {
37+
completion(.failure(configError))
38+
} else {
39+
completion(.failure(error))
40+
}
41+
}
42+
}
43+
}
44+
45+
public func fetchDefaultLocationID(completion: @escaping(Result<String, Error>) -> Void) {
46+
guard let siteID = self.siteID else {
47+
return
48+
}
49+
50+
readerConfigRemote?.loadDefaultReaderLocation(for: siteID) { result in
51+
switch result {
52+
case .success(let location):
53+
let readerLocation = location.toReaderLocation(siteID: siteID)
54+
completion(.success(readerLocation.id))
55+
case .failure(let error):
56+
if let configError = CardReaderConfigError(error: error) {
57+
completion(.failure(configError))
58+
} else {
59+
completion(.failure(error))
60+
}
61+
}
62+
}
63+
}
64+
}
65+
66+
private extension CardReaderConfigError {
67+
init?(error: Error) {
68+
guard let dotcomError = error as? DotcomError else {
69+
return nil
70+
}
71+
switch dotcomError {
72+
case .unknown("store_address_is_incomplete", let message):
73+
self = .incompleteStoreAddress(adminUrl: URL(string: message ?? ""))
74+
return
75+
case .unknown("postal_code_invalid", _):
76+
self = .invalidPostalCode
77+
return
78+
default:
79+
return nil
80+
}
81+
}
82+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Foundation
2+
3+
@testable import Yosemite
4+
5+
final class MockCommonReaderConfigProviding: CommonReaderConfigProviding {
6+
func fetchToken(completion: @escaping (Result<String, Error>) -> Void) {
7+
completion(.success("mock_token"))
8+
}
9+
10+
func fetchDefaultLocationID(completion: @escaping (Result<String, Error>) -> Void) {
11+
completion(.success("mock_location"))
12+
}
13+
14+
func setContext(siteID: Int64, remote: Yosemite.CardReaderCapableRemote) {
15+
// no-op
16+
}
17+
}

0 commit comments

Comments
 (0)