Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Hardware/Hardware.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
028C39E028255CFE0007BA25 /* Models+Copiable.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 028C39DF28255CFE0007BA25 /* Models+Copiable.generated.swift */; };
02B5147A28254ED300750B71 /* Codegen in Frameworks */ = {isa = PBXBuildFile; productRef = 02B5147928254ED300750B71 /* Codegen */; };
030338102705F7D400764131 /* ReceiptTotalLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0303380F2705F7D400764131 /* ReceiptTotalLine.swift */; };
035DBA3929251ED6003E5125 /* CardReaderInputOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035DBA3829251ED6003E5125 /* CardReaderInputOptions.swift */; };
039D948B2760C0660044EF38 /* NoOpCardReaderService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039D948A2760C0660044EF38 /* NoOpCardReaderService.swift */; };
03B440AA2754DFC400759429 /* UnderlyingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B440A92754DFC400759429 /* UnderlyingError.swift */; };
03CF78D327C6710C00523706 /* interac.svg in Resources */ = {isa = PBXBuildFile; fileRef = 03CF78D227C6710B00523706 /* interac.svg */; };
Expand Down Expand Up @@ -153,6 +154,7 @@
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>"; };
028C39DF28255CFE0007BA25 /* Models+Copiable.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Models+Copiable.generated.swift"; sourceTree = "<group>"; };
0303380F2705F7D400764131 /* ReceiptTotalLine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiptTotalLine.swift; sourceTree = "<group>"; };
035DBA3829251ED6003E5125 /* CardReaderInputOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderInputOptions.swift; sourceTree = "<group>"; };
039D948A2760C0660044EF38 /* NoOpCardReaderService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoOpCardReaderService.swift; sourceTree = "<group>"; };
03B440A92754DFC400759429 /* UnderlyingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderlyingError.swift; sourceTree = "<group>"; };
03CF78D227C6710B00523706 /* interac.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = interac.svg; sourceTree = "<group>"; };
Expand Down Expand Up @@ -439,6 +441,7 @@
D88FDB3625DD21BE00CB0DBD /* StripeCardReader */,
D88FDB2725DD21B000CB0DBD /* CardReader.swift */,
D88FDB2425DD21B000CB0DBD /* CardReaderEvent.swift */,
035DBA3829251ED6003E5125 /* CardReaderInputOptions.swift */,
D88FDB2625DD21B000CB0DBD /* CardReaderService.swift */,
D88FDB1F25DD21AF00CB0DBD /* CardReaderServiceDiscoveryStatus.swift */,
D88FDB2125DD21AF00CB0DBD /* CardReaderServiceStatus.swift */,
Expand Down Expand Up @@ -826,6 +829,7 @@
D845BE54262ED7CC00A3E40F /* PrinterService.swift in Sources */,
D845BDDE262DAB8300A3E40F /* PaymentMethod+Stripe.swift in Sources */,
D89B8F0C25DDC9D30001C726 /* ChargeStatus.swift in Sources */,
035DBA3929251ED6003E5125 /* CardReaderInputOptions.swift in Sources */,
E140F61C2668CDC900FDB5FF /* Logging.swift in Sources */,
03CF78D727DF9BE600523706 /* RefundParameters.swift in Sources */,
03B440AA2754DFC400759429 /* UnderlyingError.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Hardware/Hardware/CardReader/CardReaderEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
public enum CardReaderEvent: Equatable {
/// The reader begins waiting for input.
/// The app should prompt the customer to present a payment method
case waitingForInput(String)
case waitingForInput(CardReaderInput)

/// Request that a prompt be displayed in the app.
/// For example, if the prompt is SwipeCard,
Expand Down
26 changes: 26 additions & 0 deletions Hardware/Hardware/CardReader/CardReaderInputOptions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

public struct CardReaderInput: OptionSet {
public let rawValue: Int

public init(rawValue: Int) {
self.rawValue = rawValue
}

public static let none = CardReaderInput([])
public static let swipe = CardReaderInput(rawValue: 1 << 0)
public static let insert = CardReaderInput(rawValue: 1 << 1)
public static let tap = CardReaderInput(rawValue: 1 << 2)
}


#if !targetEnvironment(macCatalyst)
import StripeTerminal

extension CardReaderInput {
init(stripeReaderInputOptions: ReaderInputOptions) {
let value = Int(stripeReaderInputOptions.rawValue)
self.init(rawValue: value)
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import StripeTerminal
extension CardReaderEvent {
/// Factory method
/// - Parameter readerInputOptions: An instance of a StripeTerminal.ReaderInputOptions
static func make(readerInputOptions: ReaderInputOptions) -> Self {
.waitingForInput(Terminal.stringFromReaderInputOptions(readerInputOptions))
static func make(stripeReaderInputOptions: ReaderInputOptions) -> Self {
let inputOptions = CardReaderInput(stripeReaderInputOptions: stripeReaderInputOptions)
return .waitingForInput(inputOptions)
}

/// Factory method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ extension StripeCardReaderService: BluetoothReaderDelegate {
/// This method is called by the Stripe Terminal SDK when it wants client apps
/// to request users to tap / insert / swipe a card.
public func reader(_ reader: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) {
sendReaderEvent(CardReaderEvent.make(readerInputOptions: inputOptions))
sendReaderEvent(CardReaderEvent.make(stripeReaderInputOptions: inputOptions))
}

/// In this case the Stripe Terminal SDK wants us to present a string on screen
Expand Down
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-----
- [*] 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]
- [internal] In-Person Payments: update StripeTerminal from 2.7 to 2.14 [https://github.com/woocommerce/woocommerce-ios/pull/8132]
- [*] 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]

11.2
-----
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,26 @@ final class CardPresentModalTapCard: CardPresentPaymentsModalViewModel {

let accessibilityLabel: String?

init(name: String, amount: String, transactionType: CardPresentTransactionType, onCancel: @escaping () -> Void) {
init(name: String,
amount: String,
transactionType: CardPresentTransactionType,
inputMethods: CardReaderInput,
onCancel: @escaping () -> Void) {
self.name = name
self.amount = amount
self.bottomSubtitle = Localization.tapInsertOrSwipe(transactionType: transactionType)

if inputMethods == [.swipe, .insert, .tap] {
self.bottomSubtitle = Localization.tapInsertOrSwipe(transactionType: transactionType)
} else if inputMethods == [.tap, .insert] {
self.bottomSubtitle = Localization.tapOrInsert(transactionType: transactionType)
} else if inputMethods.contains(.tap) {
self.bottomSubtitle = Localization.tap(transactionType: transactionType)
} else if inputMethods.contains(.insert) {
self.bottomSubtitle = Localization.insert(transactionType: transactionType)
} else {
self.bottomSubtitle = Localization.presentCard(transactionType: transactionType)
}

self.accessibilityLabel = Localization.readerIsReady + Localization.tapInsertOrSwipe(transactionType: transactionType)
self.onCancel = onCancel
}
Expand Down Expand Up @@ -83,6 +99,66 @@ private extension CardPresentModalTapCard {
}
}

static func tapOrInsert(transactionType: CardPresentTransactionType) -> String {
switch transactionType {
case .collectPayment:
return NSLocalizedString(
"Tap or insert card to pay",
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
)
case .refund:
return NSLocalizedString(
"Tap or insert card to refund",
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
)
}
}

static func tap(transactionType: CardPresentTransactionType) -> String {
switch transactionType {
case .collectPayment:
return NSLocalizedString(
"Tap card to pay",
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
)
case .refund:
return NSLocalizedString(
"Tap card to refund",
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
)
}
}

static func insert(transactionType: CardPresentTransactionType) -> String {
switch transactionType {
case .collectPayment:
return NSLocalizedString(
"Insert card to pay",
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
)
case .refund:
return NSLocalizedString(
"Insert card to refund",
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
)
}
}

static func presentCard(transactionType: CardPresentTransactionType) -> String {
switch transactionType {
case .collectPayment:
return NSLocalizedString(
"Present card to pay",
comment: "Label asking users to present a card. Presented to users when a payment is going to be collected"
)
case .refund:
return NSLocalizedString(
"Present card to refund",
comment: "Label asking users to present a card. Presented to users when an in-person refund is going to be executed"
)
}
}

static let cancel = NSLocalizedString(
"Cancel",
comment: "Button to cancel a payment"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ final class CardPresentRefundOrchestrator {
func refund(amount: Decimal,
charge: WCPayCharge,
paymentGatewayAccount: PaymentGatewayAccount,
onWaitingForInput: @escaping () -> Void,
onWaitingForInput: @escaping (CardReaderInput) -> Void,
onProcessingMessage: @escaping () -> Void,
onDisplayMessage: @escaping (String) -> Void,
onCompletion: @escaping (Result<Void, Error>) -> Void) {
Expand All @@ -40,8 +40,8 @@ final class CardPresentRefundOrchestrator {
let refundAction = CardPresentPaymentAction.refundPayment(parameters: refundParameters,
onCardReaderMessage: { event in
switch event {
case .waitingForInput:
onWaitingForInput()
case .waitingForInput(let inputMethods):
onWaitingForInput(inputMethods)
case .displayMessage(let message):
onDisplayMessage(message)
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ final class PaymentCaptureOrchestrator {
paymentGatewayAccount: PaymentGatewayAccount,
paymentMethodTypes: [String],
stripeSmallestCurrencyUnitMultiplier: Decimal,
onWaitingForInput: @escaping () -> Void,
onWaitingForInput: @escaping (CardReaderInput) -> Void,
onProcessingMessage: @escaping () -> Void,
onDisplayMessage: @escaping (String) -> Void,
onProcessingCompletion: @escaping (PaymentIntent) -> Void,
Expand Down Expand Up @@ -68,8 +68,8 @@ final class PaymentCaptureOrchestrator {
parameters: parameters,
onCardReaderMessage: { event in
switch event {
case .waitingForInput:
onWaitingForInput()
case .waitingForInput(let inputMethods):
onWaitingForInput(inputMethods)
case .displayMessage(let message):
onDisplayMessage(message)
case .cardRemovedAfterClientSidePaymentCapture:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import MessageUI
import UIKit
import WordPressUI
import Yosemite
import enum Hardware.CardReaderServiceError
import enum Hardware.UnderlyingError

Expand Down Expand Up @@ -50,18 +51,16 @@ final class OrderDetailsPaymentAlerts: OrderDetailsPaymentAlertsProtocol {
presentViewModel(viewModel: CardPresentModalPreparingReader(cancelAction: onCancel))
}

func readerIsReady(title: String, amount: String, onCancel: @escaping () -> Void) {
func tapOrInsertCard(title: String,
amount: String,
inputMethods: CardReaderInput,
onCancel: @escaping () -> Void) {
self.name = title
self.amount = amount

// Initial presentation of the modal view controller. We need to provide
// a customer name and an amount.
let viewModel = readerIsReady(onCancel: onCancel)
presentViewModel(viewModel: viewModel)
}

func tapOrInsertCard(onCancel: @escaping () -> Void) {
let viewModel = tapOrInsert(onCancel: onCancel)
let viewModel = tapOrInsert(readerInputMethods: inputMethods, onCancel: onCancel)
presentViewModel(viewModel: viewModel)
}

Expand Down Expand Up @@ -99,15 +98,12 @@ final class OrderDetailsPaymentAlerts: OrderDetailsPaymentAlertsProtocol {
}

private extension OrderDetailsPaymentAlerts {
func readerIsReady(onCancel: @escaping () -> Void) -> CardPresentPaymentsModalViewModel {
CardPresentModalReaderIsReady(name: name,
amount: amount,
transactionType: transactionType,
cancelAction: onCancel)
}

func tapOrInsert(onCancel: @escaping () -> Void) -> CardPresentPaymentsModalViewModel {
CardPresentModalTapCard(name: name, amount: amount, transactionType: transactionType, onCancel: onCancel)
func tapOrInsert(readerInputMethods: CardReaderInput, onCancel: @escaping () -> Void) -> CardPresentPaymentsModalViewModel {
CardPresentModalTapCard(name: name,
amount: amount,
transactionType: transactionType,
inputMethods: readerInputMethods,
onCancel: onCancel)
}

func displayMessage(message: String) -> CardPresentPaymentsModalViewModel {
Expand Down
Loading