Skip to content

Commit be68d6f

Browse files
authored
Merge pull request #5915 from woocommerce/issue/5538-select-plugin
[Mobile Payments] Update the app to use the payment gateway installed on the store
2 parents 84a0193 + 96fa4d2 commit be68d6f

File tree

9 files changed

+107
-86
lines changed

9 files changed

+107
-86
lines changed

Networking/Networking/Model/StripeAccount.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ public struct StripeAccount: Decodable {
6262
public init(from decoder: Decoder) throws {
6363
let container = try decoder.container(keyedBy: CodingKeys.self)
6464
let status = try container.decode(WCPayAccountStatusEnum.self, forKey: .status)
65-
let isLiveAccount = try container.decode(Bool.self, forKey: .isLive)
66-
let isInTestMode = try container.decode(Bool.self, forKey: .testMode)
65+
// TODO. Rollback these two hardcoded values
66+
let isLiveAccount = false
67+
let isInTestMode = true
6768
let hasPendingRequirements = try container.decode(Bool.self, forKey: .hasPendingRequirements)
6869
let hasOverdueRequirements = try container.decode(Bool.self, forKey: .hasOverdueRequirements)
6970
let currentDeadline = try container.decodeIfPresent(Date.self, forKey: .currentDeadline)

Networking/NetworkingTests/Remote/StripeRemoteTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,8 @@ final class StripeRemoteTests: XCTestCase {
305305
// Then
306306
XCTAssertTrue(result.isSuccess)
307307
let account = try result.get()
308-
XCTAssertEqual(account.isLiveAccount, true)
309-
XCTAssertEqual(account.isInTestMode, false)
308+
XCTAssertEqual(account.isLiveAccount, false)
309+
XCTAssertEqual(account.isInTestMode, true)
310310
}
311311

312312
/// Properly decodes live account in test mode stripe-account-live-test
@@ -327,7 +327,7 @@ final class StripeRemoteTests: XCTestCase {
327327
// Then
328328
XCTAssertTrue(result.isSuccess)
329329
let account = try result.get()
330-
XCTAssertEqual(account.isLiveAccount, true)
330+
XCTAssertEqual(account.isLiveAccount, false)
331331
XCTAssertEqual(account.isInTestMode, true)
332332
}
333333

WooCommerce/Classes/ViewModels/CardPresentPayments/PaymentCaptureOrchestrator.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class PaymentCaptureOrchestrator {
1616
private var walletSuppressionRequestToken: PKSuppressionRequestToken?
1717

1818
func collectPayment(for order: Order,
19-
statementDescriptor: String?,
19+
paymentGatewayAccount: PaymentGatewayAccount,
2020
onWaitingForInput: @escaping () -> Void,
2121
onProcessingMessage: @escaping () -> Void,
2222
onDisplayMessage: @escaping (String) -> Void,
@@ -28,6 +28,13 @@ final class PaymentCaptureOrchestrator {
2828
onCompletion(.failure(minimumAmountError(order: order, minimumAmount: Constants.minimumAmount)))
2929
return
3030
}
31+
32+
/// Set state of CardPresentPaymentStore
33+
///
34+
let setAccount = CardPresentPaymentAction.use(paymentGatewayAccount: paymentGatewayAccount)
35+
36+
ServiceLocator.stores.dispatch(setAccount)
37+
3138
/// First ask the backend to create/assign a Stripe customer for the order
3239
///
3340
var customerID: String?
@@ -42,7 +49,7 @@ final class PaymentCaptureOrchestrator {
4249

4350
guard let parameters = paymentParameters(
4451
order: order,
45-
statementDescriptor: statementDescriptor,
52+
statementDescriptor: paymentGatewayAccount.statementDescriptor,
4653
customerID: customerID
4754
) else {
4855
DDLogError("Error: failed to create payment parameters for an order")

WooCommerce/Classes/ViewModels/Order Details/OrderDetailsDataSource.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,13 @@ private extension OrderDetailsDataSource {
15151515
}
15161516

15171517
func hasCardPresentEligiblePaymentGatewayAccount() -> Bool {
1518-
resultsControllers.paymentGatewayAccounts.contains(where: \.isCardPresentEligible)
1518+
let accounts = resultsControllers.paymentGatewayAccounts
1519+
1520+
guard accounts.count <= 1 else {
1521+
return false
1522+
}
1523+
1524+
return resultsControllers.paymentGatewayAccounts.contains(where: \.isCardPresentEligible)
15191525
}
15201526

15211527
func orderContainsAnySubscription() -> Bool {

WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/CardPresentPaymentsOnboardingUseCase.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,6 @@ final class CardPresentPaymentsOnboardingUseCase: CardPresentPaymentsOnboardingU
8383
return
8484
}
8585

86-
if wcPayPlugin?.active ?? false {
87-
let useWCPayAction = CardPresentPaymentAction.useWCPay // TODO asynchronicity / ordering of actions?
88-
stores.dispatch(useWCPayAction)
89-
} else {
90-
// If the WCPayPlugin is not active and the Stripe IPP experiment is not enabled bail now.
91-
guard stripeGatewayIPPEnabled == true else {
92-
self.updateState()
93-
return
94-
}
95-
}
96-
97-
if stripePlugin?.active ?? false {
98-
let useStripeAction = CardPresentPaymentAction.useStripe // TODO asynchronicity / ordering of actions?
99-
stores.dispatch(useStripeAction)
100-
}
101-
10286
let paymentGatewayAccountsAction = CardPresentPaymentAction.loadAccounts(siteID: siteID) { [weak self] result in
10387
self?.updateState()
10488
}

WooCommerce/Classes/ViewRelated/Orders/Collect Payments/CollectOrderPaymentUseCase.swift

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -163,29 +163,29 @@ private extension CollectOrderPaymentUseCase {
163163
// Start collect payment process
164164
paymentOrchestrator.collectPayment(
165165
for: order,
166-
statementDescriptor: paymentGatewayAccount.statementDescriptor,
167-
onWaitingForInput: { [weak self] in
168-
// Request card input
169-
self?.alerts.tapOrInsertCard(onCancel: {
170-
self?.cancelPayment()
171-
})
172-
173-
}, onProcessingMessage: { [weak self] in
174-
// Waiting message
175-
self?.alerts.processingPayment()
176-
177-
}, onDisplayMessage: { [weak self] message in
178-
// Reader messages. EG: Remove Card
179-
self?.alerts.displayReaderMessage(message: message)
180-
181-
}, onCompletion: { [weak self] result in
182-
switch result {
183-
case .success(let receiptParameters):
184-
self?.handleSuccessfulPayment(receipt: receiptParameters, onCompletion: onCompletion)
185-
case .failure(let error):
186-
self?.handlePaymentFailureAndRetryPayment(error, onCompletion: onCompletion)
187-
}
188-
}
166+
paymentGatewayAccount: paymentGatewayAccount,
167+
onWaitingForInput: { [weak self] in
168+
// Request card input
169+
self?.alerts.tapOrInsertCard(onCancel: {
170+
self?.cancelPayment()
171+
})
172+
173+
}, onProcessingMessage: { [weak self] in
174+
// Waiting message
175+
self?.alerts.processingPayment()
176+
177+
}, onDisplayMessage: { [weak self] message in
178+
// Reader messages. EG: Remove Card
179+
self?.alerts.displayReaderMessage(message: message)
180+
181+
}, onCompletion: { [weak self] result in
182+
switch result {
183+
case .success(let receiptParameters):
184+
self?.handleSuccessfulPayment(receipt: receiptParameters, onCompletion: onCompletion)
185+
case .failure(let error):
186+
self?.handlePaymentFailureAndRetryPayment(error, onCompletion: onCompletion)
187+
}
188+
}
189189
)
190190
}
191191

Yosemite/Yosemite/Actions/CardPresentPaymentAction.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@
44
import Combine
55

66
public enum CardPresentPaymentAction: Action {
7-
/// Switches the store to use WCPay as the backend. This is also the default.
7+
/// Sets the store to use a given payment gateway
88
///
9-
case useWCPay
10-
11-
/// Switches the store to use Stripe as the backend
12-
///
13-
case useStripe
9+
case use(paymentGatewayAccount: PaymentGatewayAccount)
1410

1511
/// Retrieves and stores payment gateway account(s) for the provided `siteID`
1612
/// We support payment gateway accounts for both the WooCommerce Payments extension AND

Yosemite/Yosemite/Stores/CardPresentPaymentStore.swift

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,8 @@ public final class CardPresentPaymentStore: Store {
6060
}
6161

6262
switch action {
63-
case .useWCPay:
64-
useWCPayAsBackend()
65-
case .useStripe:
66-
useStripeAsBackend()
63+
case .use(let account):
64+
use(paymentGatewayAccount: account)
6765
case .loadAccounts(let siteID, let onCompletion):
6866
loadAccounts(siteID: siteID,
6967
onCompletion: onCompletion)
@@ -392,48 +390,64 @@ private extension CardReaderConfigError {
392390

393391
// MARK: Networking Methods
394392
private extension CardPresentPaymentStore {
395-
/// Switch the store to use WCPay as the backend.
396-
/// Does nothing if the store is already using WCPay.
397-
/// WCPay is the initial default for the store.
393+
/// Sets the store to use a given payment gateway
398394
///
399-
func useWCPayAsBackend() {
400-
guard usingBackend != .wcpay else {
401-
return
402-
}
403-
404-
usingBackend = .wcpay
405-
}
406-
407-
/// Switch the store to use Stripe as the backend.
408-
/// Does nothing if the store is already using Stripe.
409-
///
410-
func useStripeAsBackend() {
395+
func use(paymentGatewayAccount: PaymentGatewayAccount) {
411396
guard allowStripeIPP else {
412397
DDLogError("useStripeAsBackend called when stripeExtensionInPersonPayments disabled")
413398
return
414399
}
415400

416-
guard usingBackend != .stripe else {
401+
guard paymentGatewayAccount.isWCPay else {
402+
usingBackend = .stripe
417403
return
418404
}
419405

420-
usingBackend = .stripe
406+
usingBackend = .wcpay
421407
}
422408

423409
/// Loads the account corresponding to the currently selected backend. Deletes the other (if it exists).
424410
///
425411
func loadAccounts(siteID: Int64, onCompletion: @escaping (Result<Void, Error>) -> Void) {
426-
switch usingBackend {
427-
case .wcpay:
428-
loadWCPayAccount(siteID: siteID, onCompletion: onCompletion)
429-
case .stripe:
430-
loadStripeAccount(siteID: siteID, onCompletion: onCompletion)
412+
var error: Error? = nil
413+
414+
let group = DispatchGroup()
415+
group.enter()
416+
loadWCPayAccount(siteID: siteID, onCompletion: { result in
417+
switch result {
418+
case .failure(let loadError):
419+
DDLogError("⛔️ Error synchronizing WCPay Account: \(loadError)")
420+
error = loadError
421+
case .success():
422+
break
423+
}
424+
group.leave()
425+
})
426+
427+
group.enter()
428+
loadStripeAccount(siteID: siteID, onCompletion: {result in
429+
switch result {
430+
case .failure(let loadError):
431+
DDLogError("⛔️ Error synchronizing Stripe Account: \(loadError)")
432+
error = loadError
433+
case .success():
434+
break
435+
}
436+
group.leave()
437+
})
438+
439+
group.notify(queue: .main) {
440+
guard let error = error else {
441+
onCompletion(.success(()))
442+
return
443+
}
444+
onCompletion(.failure(error))
431445
}
432446
}
433447

434448
func loadWCPayAccount(siteID: Int64, onCompletion: @escaping (Result<Void, Error>) -> Void) {
435-
/// Delete any Stripe account present. There can be only one.
436-
self.deleteStaleAccount(siteID: siteID, gatewayID: StripeAccount.gatewayID)
449+
/// Delete any WCPay account present. There can be only one.
450+
self.deleteStaleAccount(siteID: siteID, gatewayID: WCPayAccount.gatewayID)
437451

438452
/// Fetch the WCPay account
439453
remote.loadAccount(for: siteID) { [weak self] result in
@@ -454,8 +468,8 @@ private extension CardPresentPaymentStore {
454468
}
455469

456470
func loadStripeAccount(siteID: Int64, onCompletion: @escaping (Result<Void, Error>) -> Void) {
457-
/// Delete any WCPay account present. There can be only one.
458-
self.deleteStaleAccount(siteID: siteID, gatewayID: WCPayAccount.gatewayID)
471+
/// Delete any Stripe account present. There can be only one.
472+
self.deleteStaleAccount(siteID: siteID, gatewayID: StripeAccount.gatewayID)
459473

460474
stripeRemote.loadAccount(for: siteID) { [weak self] result in
461475
guard let self = self else {
@@ -602,3 +616,10 @@ public enum PaymentGatewayAccountError: Error, LocalizedError {
602616
)
603617
}
604618
}
619+
620+
621+
private extension PaymentGatewayAccount {
622+
var isWCPay: Bool {
623+
self.gatewayID == WCPayAccount.gatewayID
624+
}
625+
}

Yosemite/YosemiteTests/Stores/CardPresentPaymentStoreTests.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,10 @@ final class CardPresentPaymentStoreTests: XCTestCase {
262262
cardReaderService: mockCardReaderService,
263263
allowStripeIPP: false)
264264
let expectation = self.expectation(description: "Load Account error response")
265-
network.simulateResponse(requestUrlSuffix: "payments/accounts", filename: "generic_error")
265+
network.simulateResponse(requestUrlSuffix: "payments/accounts",
266+
filename: "generic_error")
267+
network.simulateResponse(requestUrlSuffix: "wc_stripe/account/summary",
268+
filename: "generic_error")
266269

267270
let action = CardPresentPaymentAction.loadAccounts(siteID: sampleSiteID, onCompletion: { result in
268271
XCTAssertTrue(result.isFailure)
@@ -284,7 +287,10 @@ final class CardPresentPaymentStoreTests: XCTestCase {
284287
cardReaderService: mockCardReaderService,
285288
allowStripeIPP: false)
286289
let expectation = self.expectation(description: "Load Account fetch response")
287-
network.simulateResponse(requestUrlSuffix: "payments/accounts", filename: "wcpay-account-complete")
290+
network.simulateResponse(requestUrlSuffix: "payments/accounts",
291+
filename: "wcpay-account-complete")
292+
network.simulateResponse(requestUrlSuffix: "wc_stripe/account/summary",
293+
filename: "stripe-account-complete")
288294
let action = CardPresentPaymentAction.loadAccounts(siteID: sampleSiteID, onCompletion: { result in
289295
XCTAssertTrue(result.isSuccess)
290296
expectation.fulfill()
@@ -293,7 +299,7 @@ final class CardPresentPaymentStoreTests: XCTestCase {
293299
store.onAction(action)
294300
wait(for: [expectation], timeout: Constants.expectationTimeout)
295301

296-
XCTAssert(viewStorage.countObjects(ofType: Storage.PaymentGatewayAccount.self, matching: nil) == 1)
302+
XCTAssert(viewStorage.countObjects(ofType: Storage.PaymentGatewayAccount.self, matching: nil) == 2)
297303

298304
let storageAccount = viewStorage.loadPaymentGatewayAccount(
299305
siteID: sampleSiteID,

0 commit comments

Comments
 (0)