Skip to content

Commit c0439fa

Browse files
authored
Merge pull request #8136 from woocommerce/issue/8116-restore-ability-to-display-reader-messages
[Mobile Payments] Display reader input method message when reader is ready
2 parents eb9f382 + 95f5e23 commit c0439fa

21 files changed

+151
-220
lines changed

Hardware/Hardware.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
028C39E028255CFE0007BA25 /* Models+Copiable.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 028C39DF28255CFE0007BA25 /* Models+Copiable.generated.swift */; };
1111
02B5147A28254ED300750B71 /* Codegen in Frameworks */ = {isa = PBXBuildFile; productRef = 02B5147928254ED300750B71 /* Codegen */; };
1212
030338102705F7D400764131 /* ReceiptTotalLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0303380F2705F7D400764131 /* ReceiptTotalLine.swift */; };
13+
035DBA3929251ED6003E5125 /* CardReaderInputOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035DBA3829251ED6003E5125 /* CardReaderInputOptions.swift */; };
1314
039D948B2760C0660044EF38 /* NoOpCardReaderService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039D948A2760C0660044EF38 /* NoOpCardReaderService.swift */; };
1415
03B440AA2754DFC400759429 /* UnderlyingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B440A92754DFC400759429 /* UnderlyingError.swift */; };
1516
03CF78D327C6710C00523706 /* interac.svg in Resources */ = {isa = PBXBuildFile; fileRef = 03CF78D227C6710B00523706 /* interac.svg */; };
@@ -153,6 +154,7 @@
153154
02351FF56149ADCD11338B19 /* Pods-SampleReceiptPrinter.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleReceiptPrinter.release.xcconfig"; path = "Target Support Files/Pods-SampleReceiptPrinter/Pods-SampleReceiptPrinter.release.xcconfig"; sourceTree = "<group>"; };
154155
028C39DF28255CFE0007BA25 /* Models+Copiable.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Models+Copiable.generated.swift"; sourceTree = "<group>"; };
155156
0303380F2705F7D400764131 /* ReceiptTotalLine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiptTotalLine.swift; sourceTree = "<group>"; };
157+
035DBA3829251ED6003E5125 /* CardReaderInputOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderInputOptions.swift; sourceTree = "<group>"; };
156158
039D948A2760C0660044EF38 /* NoOpCardReaderService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoOpCardReaderService.swift; sourceTree = "<group>"; };
157159
03B440A92754DFC400759429 /* UnderlyingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderlyingError.swift; sourceTree = "<group>"; };
158160
03CF78D227C6710B00523706 /* interac.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = interac.svg; sourceTree = "<group>"; };
@@ -439,6 +441,7 @@
439441
D88FDB3625DD21BE00CB0DBD /* StripeCardReader */,
440442
D88FDB2725DD21B000CB0DBD /* CardReader.swift */,
441443
D88FDB2425DD21B000CB0DBD /* CardReaderEvent.swift */,
444+
035DBA3829251ED6003E5125 /* CardReaderInputOptions.swift */,
442445
D88FDB2625DD21B000CB0DBD /* CardReaderService.swift */,
443446
D88FDB1F25DD21AF00CB0DBD /* CardReaderServiceDiscoveryStatus.swift */,
444447
D88FDB2125DD21AF00CB0DBD /* CardReaderServiceStatus.swift */,
@@ -826,6 +829,7 @@
826829
D845BE54262ED7CC00A3E40F /* PrinterService.swift in Sources */,
827830
D845BDDE262DAB8300A3E40F /* PaymentMethod+Stripe.swift in Sources */,
828831
D89B8F0C25DDC9D30001C726 /* ChargeStatus.swift in Sources */,
832+
035DBA3929251ED6003E5125 /* CardReaderInputOptions.swift in Sources */,
829833
E140F61C2668CDC900FDB5FF /* Logging.swift in Sources */,
830834
03CF78D727DF9BE600523706 /* RefundParameters.swift in Sources */,
831835
03B440AA2754DFC400759429 /* UnderlyingError.swift in Sources */,

Hardware/Hardware/CardReader/CardReaderEvent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
public enum CardReaderEvent: Equatable {
33
/// The reader begins waiting for input.
44
/// The app should prompt the customer to present a payment method
5-
case waitingForInput(String)
5+
case waitingForInput(CardReaderInput)
66

77
/// Request that a prompt be displayed in the app.
88
/// For example, if the prompt is SwipeCard,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Foundation
2+
3+
public struct CardReaderInput: OptionSet {
4+
public let rawValue: Int
5+
6+
public init(rawValue: Int) {
7+
self.rawValue = rawValue
8+
}
9+
10+
public static let none = CardReaderInput([])
11+
public static let swipe = CardReaderInput(rawValue: 1 << 0)
12+
public static let insert = CardReaderInput(rawValue: 1 << 1)
13+
public static let tap = CardReaderInput(rawValue: 1 << 2)
14+
}
15+
16+
17+
#if !targetEnvironment(macCatalyst)
18+
import StripeTerminal
19+
20+
extension CardReaderInput {
21+
init(stripeReaderInputOptions: ReaderInputOptions) {
22+
let value = Int(stripeReaderInputOptions.rawValue)
23+
self.init(rawValue: value)
24+
}
25+
}
26+
#endif

Hardware/Hardware/CardReader/StripeCardReader/CardReaderEvent+Stripe.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import StripeTerminal
44
extension CardReaderEvent {
55
/// Factory method
66
/// - Parameter readerInputOptions: An instance of a StripeTerminal.ReaderInputOptions
7-
static func make(readerInputOptions: ReaderInputOptions) -> Self {
8-
.waitingForInput(Terminal.stringFromReaderInputOptions(readerInputOptions))
7+
static func make(stripeReaderInputOptions: ReaderInputOptions) -> Self {
8+
let inputOptions = CardReaderInput(stripeReaderInputOptions: stripeReaderInputOptions)
9+
return .waitingForInput(inputOptions)
910
}
1011

1112
/// Factory method

Hardware/Hardware/CardReader/StripeCardReader/StripeCardReaderService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ extension StripeCardReaderService: BluetoothReaderDelegate {
646646
/// This method is called by the Stripe Terminal SDK when it wants client apps
647647
/// to request users to tap / insert / swipe a card.
648648
public func reader(_ reader: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) {
649-
sendReaderEvent(CardReaderEvent.make(readerInputOptions: inputOptions))
649+
sendReaderEvent(CardReaderEvent.make(stripeReaderInputOptions: inputOptions))
650650
}
651651

652652
/// In this case the Stripe Terminal SDK wants us to present a string on screen

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
-----
55
- [*] In-Person Payments: Show spinner while preparing reader for payment, instead of saying it's ready before it is. [https://github.com/woocommerce/woocommerce-ios/pull/8115]
66
- [internal] In-Person Payments: update StripeTerminal from 2.7 to 2.14 [https://github.com/woocommerce/woocommerce-ios/pull/8132]
7+
- [*] In-Person Payments: Fixed payment method prompt for WisePad 3 to show only Tap and Insert options [https://github.com/woocommerce/woocommerce-ios/pull/8136]
78

89
11.2
910
-----

WooCommerce/Classes/ViewModels/CardPresentPayments/CardPresentModalReaderIsReady.swift

Lines changed: 0 additions & 98 deletions
This file was deleted.

WooCommerce/Classes/ViewModels/CardPresentPayments/CardPresentModalTapCard.swift

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,26 @@ final class CardPresentModalTapCard: CardPresentPaymentsModalViewModel {
3838

3939
let accessibilityLabel: String?
4040

41-
init(name: String, amount: String, transactionType: CardPresentTransactionType, onCancel: @escaping () -> Void) {
41+
init(name: String,
42+
amount: String,
43+
transactionType: CardPresentTransactionType,
44+
inputMethods: CardReaderInput,
45+
onCancel: @escaping () -> Void) {
4246
self.name = name
4347
self.amount = amount
44-
self.bottomSubtitle = Localization.tapInsertOrSwipe(transactionType: transactionType)
48+
49+
if inputMethods == [.swipe, .insert, .tap] {
50+
self.bottomSubtitle = Localization.tapInsertOrSwipe(transactionType: transactionType)
51+
} else if inputMethods == [.tap, .insert] {
52+
self.bottomSubtitle = Localization.tapOrInsert(transactionType: transactionType)
53+
} else if inputMethods.contains(.tap) {
54+
self.bottomSubtitle = Localization.tap(transactionType: transactionType)
55+
} else if inputMethods.contains(.insert) {
56+
self.bottomSubtitle = Localization.insert(transactionType: transactionType)
57+
} else {
58+
self.bottomSubtitle = Localization.presentCard(transactionType: transactionType)
59+
}
60+
4561
self.accessibilityLabel = Localization.readerIsReady + Localization.tapInsertOrSwipe(transactionType: transactionType)
4662
self.onCancel = onCancel
4763
}
@@ -83,6 +99,66 @@ private extension CardPresentModalTapCard {
8399
}
84100
}
85101

102+
static func tapOrInsert(transactionType: CardPresentTransactionType) -> String {
103+
switch transactionType {
104+
case .collectPayment:
105+
return NSLocalizedString(
106+
"Tap or insert card to pay",
107+
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
108+
)
109+
case .refund:
110+
return NSLocalizedString(
111+
"Tap or insert card to refund",
112+
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
113+
)
114+
}
115+
}
116+
117+
static func tap(transactionType: CardPresentTransactionType) -> String {
118+
switch transactionType {
119+
case .collectPayment:
120+
return NSLocalizedString(
121+
"Tap card to pay",
122+
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
123+
)
124+
case .refund:
125+
return NSLocalizedString(
126+
"Tap card to refund",
127+
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
128+
)
129+
}
130+
}
131+
132+
static func insert(transactionType: CardPresentTransactionType) -> String {
133+
switch transactionType {
134+
case .collectPayment:
135+
return NSLocalizedString(
136+
"Insert card to pay",
137+
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
138+
)
139+
case .refund:
140+
return NSLocalizedString(
141+
"Insert card to refund",
142+
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
143+
)
144+
}
145+
}
146+
147+
static func presentCard(transactionType: CardPresentTransactionType) -> String {
148+
switch transactionType {
149+
case .collectPayment:
150+
return NSLocalizedString(
151+
"Present card to pay",
152+
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
153+
)
154+
case .refund:
155+
return NSLocalizedString(
156+
"Present card to refund",
157+
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
158+
)
159+
}
160+
}
161+
86162
static let cancel = NSLocalizedString(
87163
"Cancel",
88164
comment: "Button to cancel a payment"

WooCommerce/Classes/ViewModels/CardPresentPayments/CardPresentRefundOrchestrator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ final class CardPresentRefundOrchestrator {
2727
func refund(amount: Decimal,
2828
charge: WCPayCharge,
2929
paymentGatewayAccount: PaymentGatewayAccount,
30-
onWaitingForInput: @escaping () -> Void,
30+
onWaitingForInput: @escaping (CardReaderInput) -> Void,
3131
onProcessingMessage: @escaping () -> Void,
3232
onDisplayMessage: @escaping (String) -> Void,
3333
onCompletion: @escaping (Result<Void, Error>) -> Void) {
@@ -40,8 +40,8 @@ final class CardPresentRefundOrchestrator {
4040
let refundAction = CardPresentPaymentAction.refundPayment(parameters: refundParameters,
4141
onCardReaderMessage: { event in
4242
switch event {
43-
case .waitingForInput:
44-
onWaitingForInput()
43+
case .waitingForInput(let inputMethods):
44+
onWaitingForInput(inputMethods)
4545
case .displayMessage(let message):
4646
onDisplayMessage(message)
4747
default:

WooCommerce/Classes/ViewModels/CardPresentPayments/PaymentCaptureOrchestrator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ final class PaymentCaptureOrchestrator {
3939
paymentGatewayAccount: PaymentGatewayAccount,
4040
paymentMethodTypes: [String],
4141
stripeSmallestCurrencyUnitMultiplier: Decimal,
42-
onWaitingForInput: @escaping () -> Void,
42+
onWaitingForInput: @escaping (CardReaderInput) -> Void,
4343
onProcessingMessage: @escaping () -> Void,
4444
onDisplayMessage: @escaping (String) -> Void,
4545
onProcessingCompletion: @escaping (PaymentIntent) -> Void,
@@ -68,8 +68,8 @@ final class PaymentCaptureOrchestrator {
6868
parameters: parameters,
6969
onCardReaderMessage: { event in
7070
switch event {
71-
case .waitingForInput:
72-
onWaitingForInput()
71+
case .waitingForInput(let inputMethods):
72+
onWaitingForInput(inputMethods)
7373
case .displayMessage(let message):
7474
onDisplayMessage(message)
7575
case .cardRemovedAfterClientSidePaymentCapture:

0 commit comments

Comments
 (0)