Skip to content

Commit decc41e

Browse files
authored
[Woo POS] Include more information in pos_card_present_collect_payment_success event (#15892)
2 parents 8c09e5f + 030b0a5 commit decc41e

File tree

8 files changed

+116
-13
lines changed

8 files changed

+116
-13
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: 12 additions & 3 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 {
@@ -11,17 +13,24 @@ struct POSCollectOrderPaymentAnalyticsTests {
1113
analytics = WooAnalytics(analyticsProvider: analyticsProvider)
1214
}
1315

14-
@Test func POSCollectOrderPaymentAnalyticsTests_when_successful_payment_then_tracks_event_and_properties() {
16+
@Test func analytics_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)