Skip to content

Commit ee76bac

Browse files
committed
Track more detailed with POS card present collect payment success event
Track gatewayID, countryCode, paymentMethod, cardReaderModel, and siteID to match IPP and Android implementation
1 parent 07919b7 commit ee76bac

File tree

8 files changed

+115
-12
lines changed

8 files changed

+115
-12
lines changed

WooCommerce/Classes/Analytics/WooAnalyticsEvent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2414,7 +2414,7 @@ extension WooAnalyticsEvent {
24142414
}
24152415
}
24162416

2417-
private extension PaymentMethod {
2417+
extension PaymentMethod {
24182418
var analyticsValue: String {
24192419
switch self {
24202420
case .card, .cardPresent:

WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalytics.swift

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import protocol WooFoundation.Analytics
33
import Yosemite
44

55
final class POSCollectOrderPaymentAnalytics: POSCollectOrderPaymentAnalyticsTracking {
6-
var connectedReaderModel: String?
7-
86
private var customerInteractionStarted: Double = 0
97
private var orderSync: Double = 0
108
private var cardReaderReady: Double = 0
@@ -14,11 +12,35 @@ final class POSCollectOrderPaymentAnalytics: POSCollectOrderPaymentAnalyticsTrac
1412

1513
private let analytics: Analytics
1614

17-
init(analytics: Analytics = ServiceLocator.analytics) {
15+
private let siteID: Int64
16+
private var paymentGatewayAccount: PaymentGatewayAccount?
17+
private let configuration: CardPresentPaymentsConfiguration
18+
private var connectedReader: CardReader?
19+
var connectedReaderModel: String? {
20+
connectedReader?.readerType.model
21+
}
22+
23+
init(siteID: Int64,
24+
analytics: Analytics = ServiceLocator.analytics,
25+
configuration: CardPresentPaymentsConfiguration = CardPresentConfigurationLoader().configuration) {
26+
self.siteID = siteID
1827
self.analytics = analytics
28+
self.configuration = configuration
29+
}
30+
31+
func preflightResultReceived(_ result: CardReaderPreflightResult?) {
32+
switch result {
33+
case .completed(let connectedReader, let paymentGatewayAccount):
34+
self.connectedReader = connectedReader
35+
self.paymentGatewayAccount = paymentGatewayAccount
36+
case .canceled(_, let paymentGatewayAccount):
37+
self.connectedReader = nil
38+
self.paymentGatewayAccount = paymentGatewayAccount
39+
case .none:
40+
break
41+
}
1942
}
2043

21-
func preflightResultReceived(_ result: CardReaderPreflightResult?) { }
2244
func trackProcessingCompletion(intent: Yosemite.PaymentIntent) { }
2345

2446
func trackSuccessfulCardPayment(capturedPaymentData: CardPresentCapturedPaymentData) {
@@ -35,6 +57,11 @@ final class POSCollectOrderPaymentAnalytics: POSCollectOrderPaymentAnalyticsTrac
3557
let elapsedTimeSinceCardTapped = calculateElapsedTimeInMilliseconds(since: cardReaderTapped)
3658

3759
analytics.track(event: .PointOfSale.cardPresentCollectPaymentSuccess(
60+
forGatewayID: paymentGatewayAccount?.gatewayID,
61+
countryCode: configuration.countryCode,
62+
paymentMethod: capturedPaymentData.paymentMethod,
63+
cardReaderModel: connectedReaderModel,
64+
siteID: siteID,
3865
millisecondsSinceCustomerIteractionStarted: elapsedTimeSinceCustomerInteraction,
3966
millisecondsSinceOrderSyncSuccess: elapsedTimeSinceOrderSync,
4067
millisecondsSinceReaderReadyToCollect: elapsedTimeSinceCardReaderReady,

WooCommerce/Classes/POS/Analytics/WooAnalyticsEvent+PointOfSale.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import enum Yosemite.POSItemType
33
import enum Yosemite.POSItem
44
import struct Yosemite.POSSimpleProduct
55
import struct Yosemite.POSVariation
6+
import enum WooFoundation.CountryCode
7+
import enum Yosemite.PaymentMethod
68

79
extension WooAnalyticsEvent {
810
enum PointOfSale {
@@ -25,6 +27,11 @@ extension WooAnalyticsEvent {
2527
static let resultsCount = "results_count"
2628
static let millisecondsSinceRequestSent = "milliseconds_since_request_sent"
2729
static let totalItems = "total_items"
30+
static let cardReaderModel = "card_reader_model"
31+
static let countryCode = "country"
32+
static let paymentMethodType = "payment_method_type"
33+
static let siteID = "site_id"
34+
static let gatewayID = "plugin_slug"
2835
}
2936

3037
static func paymentsOnboardingShown() -> WooAnalyticsEvent {
@@ -100,12 +107,22 @@ extension WooAnalyticsEvent {
100107
WooAnalyticsEvent(statName: .pointOfSaleReaderReadyForCardPayment, properties: [Key.waitingTime: "\(waitingTime)"])
101108
}
102109

103-
static func cardPresentCollectPaymentSuccess(millisecondsSinceCustomerIteractionStarted: Double,
110+
static func cardPresentCollectPaymentSuccess(forGatewayID: String?,
111+
countryCode: CountryCode,
112+
paymentMethod: PaymentMethod,
113+
cardReaderModel: String?,
114+
siteID: Int64,
115+
millisecondsSinceCustomerIteractionStarted: Double,
104116
millisecondsSinceOrderSyncSuccess: Double,
105117
millisecondsSinceReaderReadyToCollect: Double,
106118
millisecondsSinceCardTapped: Double,
107119
checkoutTapCount: Int) -> WooAnalyticsEvent {
108120
WooAnalyticsEvent(statName: .collectPaymentSuccess, properties: [
121+
Key.cardReaderModel: readerModel(for: cardReaderModel),
122+
Key.countryCode: countryCode.rawValue,
123+
Key.gatewayID: safeGatewayID(for: forGatewayID),
124+
Key.paymentMethodType: paymentMethod.analyticsValue,
125+
Key.siteID: siteID,
109126
Key.millisecondsSinceCustomerInteractionStarted: "\(millisecondsSinceCustomerIteractionStarted)",
110127
Key.millisecondsSinceOrderSyncSuccess: "\(millisecondsSinceOrderSyncSuccess)",
111128
Key.millisecondsSinceReaderReadyToCollect: "\(millisecondsSinceReaderReadyToCollect)",
@@ -183,6 +200,16 @@ extension WooAnalyticsEvent {
183200
}
184201
}
185202

203+
private extension WooAnalyticsEvent.PointOfSale {
204+
static func readerModel(for connectedReaderModel: String?) -> String {
205+
connectedReaderModel ?? "none_connected"
206+
}
207+
208+
static func safeGatewayID(for gatewayID: String?) -> String {
209+
gatewayID ?? "unknown"
210+
}
211+
}
212+
186213
extension WooAnalyticsEvent.PointOfSale {
187214
/// Source of the event where the event is triggered
188215
/// Views: Product, Variation, and Coupon Lists. Cart view and Checkout error.

WooCommerce/Classes/POS/Presentation/PointOfSaleEntryPointView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct PointOfSaleEntryPointView: View {
105105
onPointOfSaleModeActiveStateChange: { _ in },
106106
cardPresentPaymentService: CardPresentPaymentPreviewService(),
107107
orderController: PointOfSalePreviewOrderController(),
108-
collectOrderPaymentAnalyticsTracker: POSCollectOrderPaymentAnalytics(),
108+
collectOrderPaymentAnalyticsTracker: POSCollectOrderPaymentPreviewAnalytics(),
109109
searchHistoryService: PointOfSalePreviewHistoryService(),
110110
popularPurchasableItemsController: PointOfSalePreviewItemsController(),
111111
barcodeScanService: PointOfSalePreviewBarcodeScanService(),

WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private extension POSTabCoordinator {
8888
func presentPOSView() {
8989
Task { @MainActor [weak self] in
9090
guard let self else { return }
91-
let collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics()
91+
let collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics(siteID: siteID)
9292
let cardPresentPaymentService = await CardPresentPaymentService(siteID: siteID,
9393
stores: storesManager,
9494
collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker)

WooCommerce/Classes/POS/Utils/PreviewHelpers.swift

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import enum Yosemite.POSItemType
2121
import protocol Yosemite.PointOfSaleBarcodeScanServiceProtocol
2222
import enum Yosemite.PointOfSaleBarcodeScanError
2323
import Combine
24+
import struct Yosemite.PaymentIntent
2425

2526
// MARK: - PreviewProvider helpers
2627
//
@@ -212,7 +213,7 @@ struct POSPreviewHelpers {
212213
couponsSearchController: PointOfSaleCouponsControllerProtocol = PointOfSalePreviewCouponsController(),
213214
cardPresentPaymentService: CardPresentPaymentFacade = CardPresentPaymentPreviewService(),
214215
orderController: PointOfSaleOrderControllerProtocol = PointOfSalePreviewOrderController(),
215-
collectOrderPaymentAnalyticsTracker: POSCollectOrderPaymentAnalyticsTracking = POSCollectOrderPaymentAnalytics(),
216+
collectOrderPaymentAnalyticsTracker: POSCollectOrderPaymentAnalyticsTracking = POSCollectOrderPaymentPreviewAnalytics(),
216217
searchHistoryService: POSSearchHistoryProviding = PointOfSalePreviewHistoryService(),
217218
popularItemsController: PointOfSaleItemsControllerProtocol = PointOfSalePreviewItemsController(),
218219
barcodeScanService: PointOfSaleBarcodeScanServiceProtocol = PointOfSalePreviewBarcodeScanService()
@@ -239,4 +240,42 @@ final class PointOfSalePreviewBarcodeScanService: PointOfSaleBarcodeScanServiceP
239240
}
240241
}
241242

243+
final class POSCollectOrderPaymentPreviewAnalytics: POSCollectOrderPaymentAnalyticsTracking {
244+
func trackCustomerInteractionStarted() {}
245+
246+
func trackOrderSyncSuccess() {}
247+
248+
func trackCardReaderReady() {}
249+
250+
func trackCardReaderTapped() {}
251+
252+
func trackCheckoutTapped() {}
253+
254+
func resetCheckoutTapCountTracker() {}
255+
256+
func trackSuccessfulCashPayment() {}
257+
258+
var connectedReaderModel: String?
259+
260+
func preflightResultReceived(_ result: CardReaderPreflightResult?) {}
261+
262+
func trackProcessingCompletion(intent: PaymentIntent) {}
263+
264+
func trackSuccessfulCardPayment(capturedPaymentData: CardPresentCapturedPaymentData) {}
265+
266+
func trackPaymentFailure(with error: any Error) {}
267+
268+
func trackPaymentCancelation(cancelationSource: WooAnalyticsEvent.InPersonPayments.CancellationSource) {}
269+
270+
func trackEmailTapped() {}
271+
272+
func trackReceiptPrintTapped() {}
273+
274+
func trackReceiptPrintSuccess() {}
275+
276+
func trackReceiptPrintCanceled() {}
277+
278+
func trackReceiptPrintFailed(error: any Error) {}
279+
}
280+
242281
#endif

WooCommerce/Classes/ViewRelated/Hub Menu/HubMenuViewModel.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ final class HubMenuViewModel: ObservableObject {
154154
}()
155155

156156
private(set) var cardPresentPaymentService: CardPresentPaymentFacade?
157-
private(set) var collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics()
157+
private(set) var collectOrderPaymentAnalyticsTracker: POSCollectOrderPaymentAnalytics
158158
private let analytics: Analytics
159159

160160
init(siteID: Int64,
@@ -181,6 +181,7 @@ final class HubMenuViewModel: ObservableObject {
181181
currencySettings: ServiceLocator.currencySettings,
182182
featureFlagService: featureFlagService)
183183
self.analytics = analytics
184+
self.collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics(siteID: siteID)
184185
observeSiteForUIUpdates()
185186
observePlanName()
186187
observeGoogleAdsEntryPointAvailability()

WooCommerce/WooCommerceTests/POS/Analytics/POSCollectOrderPaymentAnalyticsTests.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@testable import WooCommerce
22
import protocol WooFoundation.Analytics
3+
import struct Yosemite.CardPresentPaymentsConfiguration
4+
import enum WooFoundation.CountryCode
35
import Testing
46

57
struct POSCollectOrderPaymentAnalyticsTests {
@@ -13,15 +15,22 @@ struct POSCollectOrderPaymentAnalyticsTests {
1315

1416
@Test func POSCollectOrderPaymentAnalyticsTests_when_successful_payment_then_tracks_event_and_properties() {
1517
// Given
16-
let sut = POSCollectOrderPaymentAnalytics(analytics: analytics)
18+
let siteID: Int64 = 123
19+
let configuration = CardPresentPaymentsConfiguration(country: .US)
20+
let sut = POSCollectOrderPaymentAnalytics(siteID: siteID, analytics: analytics, configuration: configuration)
1721
let capturedPaymentData = CardPresentCapturedPaymentData(paymentMethod: .cardPresent(details: .fake()), receiptParameters: nil)
1822
let expectedEvent = "card_present_collect_payment_success"
1923
let expectedProperties = [
2024
"milliseconds_since_order_sync_success",
2125
"milliseconds_since_reader_ready_to_collect_payment",
2226
"milliseconds_since_card_tapped",
2327
"milliseconds_since_customer_interaction_started",
24-
"checkout_tap_count"
28+
"checkout_tap_count",
29+
"card_reader_model",
30+
"country",
31+
"payment_method_type",
32+
"site_id",
33+
"plugin_slug"
2534
]
2635

2736
// When

0 commit comments

Comments
 (0)