Skip to content

Commit 285fb58

Browse files
authored
Merge pull request #7561 from woocommerce/issue/7525-tracks-events-for-cod-prompt
[Mobile Payments] Tracks events for Cash on Delivery Onboarding prompt
2 parents 3eed6ed + eb26781 commit 285fb58

File tree

8 files changed

+283
-23
lines changed

8 files changed

+283
-23
lines changed

WooCommerce/Classes/Analytics/WooAnalyticsEvent.swift

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,8 @@ extension WooAnalyticsEvent {
745745
static let batteryLevel = "battery_level"
746746
static let cardReaderModel = "card_reader_model"
747747
static let countryCode = "country"
748+
static let reason = "reason"
749+
static let remindLater = "remind_later"
748750
static let gatewayID = "plugin_slug"
749751
static let errorDescription = "error_description"
750752
static let paymentMethodType = "payment_method_type"
@@ -1135,9 +1137,12 @@ extension WooAnalyticsEvent {
11351137
///
11361138
/// - Parameter countryCode: the country code of the store.
11371139
///
1138-
static func cardPresentOnboardingLearnMoreTapped(countryCode: String) -> WooAnalyticsEvent {
1140+
static func cardPresentOnboardingLearnMoreTapped(reason: String, countryCode: String) -> WooAnalyticsEvent {
11391141
WooAnalyticsEvent(statName: .cardPresentOnboardingLearnMoreTapped,
1140-
properties: [Keys.countryCode: countryCode])
1142+
properties: [
1143+
Keys.countryCode: countryCode,
1144+
Keys.reason: reason
1145+
])
11411146
}
11421147

11431148
/// Tracked when the In-Person Payments onboarding cannot be completed for some reason.
@@ -1150,10 +1155,66 @@ extension WooAnalyticsEvent {
11501155
WooAnalyticsEvent(statName: .cardPresentOnboardingNotCompleted,
11511156
properties: [
11521157
Keys.countryCode: countryCode,
1153-
"reason": reason
1158+
Keys.reason: reason
11541159
])
11551160
}
11561161

1162+
/// Tracked when a In-Person Payments onboarding step is skipped by the user.
1163+
///
1164+
/// - Parameters:
1165+
/// - reason: the reason why the onboarding step was shown (effectively the name of the step.)
1166+
/// - remindLater: whether the user will see this onboarding step again
1167+
/// - countryCode: the country code of the store.
1168+
///
1169+
static func cardPresentOnboardingStepSkipped(reason: String, remindLater: Bool, countryCode: String) -> WooAnalyticsEvent {
1170+
WooAnalyticsEvent(statName: .cardPresentOnboardingStepSkipped,
1171+
properties: [
1172+
Keys.countryCode: countryCode,
1173+
Keys.reason: reason,
1174+
Keys.remindLater: remindLater
1175+
])
1176+
}
1177+
1178+
/// Tracked when a In-Person Payments onboarding step's CTA is tapped by the user.
1179+
///
1180+
/// - Parameters:
1181+
/// - reason: the reason why the onboarding step was shown (effectively the name of the step.)
1182+
/// - countryCode: the country code of the store.
1183+
///
1184+
static func cardPresentOnboardingCtaTapped(reason: String, countryCode: String) -> WooAnalyticsEvent {
1185+
WooAnalyticsEvent(statName: .cardPresentOnboardingCtaTapped,
1186+
properties: [
1187+
Keys.countryCode: countryCode,
1188+
Keys.reason: reason
1189+
])
1190+
}
1191+
1192+
/// Tracked when the Cash on Delivery Payment Gateway is successfully enabled, e.g. from the IPP onboarding flow.
1193+
///
1194+
/// - Parameters:
1195+
/// - countryCode: the country code of the store.
1196+
///
1197+
static func enableCashOnDeliverySuccess(countryCode: String) -> WooAnalyticsEvent {
1198+
WooAnalyticsEvent(statName: .enableCashOnDeliverySuccess,
1199+
properties: [
1200+
Keys.countryCode: countryCode
1201+
])
1202+
}
1203+
1204+
/// Tracked when the Cash on Delivery Payment Gateway enabling fails, e.g. from the IPP onboarding flow.
1205+
///
1206+
/// - Parameters:
1207+
/// - countryCode: the country code of the store.
1208+
///
1209+
static func enableCashOnDeliveryFailed(countryCode: String,
1210+
error: Error?) -> WooAnalyticsEvent {
1211+
WooAnalyticsEvent(statName: .enableCashOnDeliveryFailed,
1212+
properties: [
1213+
Keys.countryCode: countryCode
1214+
],
1215+
error: error)
1216+
}
1217+
11571218
/// Tracked when the user taps on the "See Receipt" button to view a receipt.
11581219
/// - Parameter countryCode: the country code of the store.
11591220
///

WooCommerce/Classes/Analytics/WooAnalyticsStat.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ public enum WooAnalyticsStat: String {
184184
// MARK: Card-Present Payments Onboarding
185185
case cardPresentOnboardingLearnMoreTapped = "card_present_onboarding_learn_more_tapped"
186186
case cardPresentOnboardingNotCompleted = "card_present_onboarding_not_completed"
187+
case cardPresentOnboardingStepSkipped = "card_present_onboarding_step_skipped"
188+
case cardPresentOnboardingCtaTapped = "card_present_onboarding_cta_tapped"
189+
190+
// MARK: Cash on Delivery Enable events
191+
case enableCashOnDeliverySuccess = "enable_cash_on_delivery_success"
192+
case enableCashOnDeliveryFailed = "enable_cash_on_delivery_failed"
187193

188194
// MARK: Payment Gateways selection
189195
case cardPresentPaymentGatewaySelected = "card_present_payment_gateway_selected"

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ struct InPersonPaymentsLearnMore: View {
77
let url: URL
88
let linkText: String
99
let formatText: String
10+
let analyticReason: String?
1011

1112
init(url: URL = learnMoreURL,
1213
linkText: String = Localization.learnMoreLink,
13-
formatText: String = Localization.learnMoreText) {
14+
formatText: String = Localization.learnMoreText,
15+
analyticReason: String? = nil) {
1416
self.url = url
1517
self.linkText = linkText
1618
self.formatText = formatText
19+
self.analyticReason = analyticReason
1720
}
1821

1922
private let cardPresentConfiguration = CardPresentConfigurationLoader().configuration
@@ -28,8 +31,10 @@ struct InPersonPaymentsLearnMore: View {
2831
}
2932
.padding(.vertical, Constants.verticalPadding)
3033
.onTapGesture {
31-
ServiceLocator.analytics.track(event: WooAnalyticsEvent.InPersonPayments
32-
.cardPresentOnboardingLearnMoreTapped(countryCode: cardPresentConfiguration.countryCode))
34+
ServiceLocator.analytics.track(
35+
event: WooAnalyticsEvent.InPersonPayments.cardPresentOnboardingLearnMoreTapped(
36+
reason: analyticReason ?? "",
37+
countryCode: cardPresentConfiguration.countryCode))
3338
customOpenURL?(url)
3439
}
3540
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ final class InPersonPaymentsViewModel: ObservableObject {
1111
let stores: StoresManager
1212

1313
lazy var codStepViewModel: InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel = {
14-
InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel(completion: refresh)
14+
InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel(configuration: useCase.configurationLoader.configuration,
15+
completion: refresh)
1516
}()
1617

1718
/// Initializes the view model for a specific site

WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import SwiftUI
2+
import Yosemite
23

34
struct InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView: View {
45
@ObservedObject var viewModel: InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel
@@ -28,14 +29,16 @@ struct InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView: View {
2829
Spacer()
2930

3031
InPersonPaymentsLearnMore(url: WooConstants.URLs.cashOnDeliveryLearnMoreUrl.asURL(),
31-
formatText: Localization.cashOnDeliveryLearnMore)
32+
formatText: Localization.cashOnDeliveryLearnMore,
33+
analyticReason: viewModel.analyticReason)
3234
}
3335
}
3436
}
3537

3638
struct InPersonPaymentsCodPaymentGatewayNotSetUp_Previews: PreviewProvider {
3739
static var previews: some View {
38-
let viewModel = InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel(completion: {})
40+
let viewModel = InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel(configuration: CardPresentPaymentsConfiguration(country: "US"),
41+
completion: {})
3942
return InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView(viewModel: viewModel)
4043
}
4144
}

WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel.swift

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,61 @@ import Foundation
22
import Yosemite
33

44
final class InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel: ObservableObject {
5+
// MARK: - Dependencies
6+
struct Dependencies {
7+
let stores: StoresManager
8+
let noticePresenter: NoticePresenter
9+
let analytics: Analytics
10+
11+
init(stores: StoresManager = ServiceLocator.stores,
12+
noticePresenter: NoticePresenter = ServiceLocator.noticePresenter,
13+
analytics: Analytics = ServiceLocator.analytics) {
14+
self.stores = stores
15+
self.noticePresenter = noticePresenter
16+
self.analytics = analytics
17+
}
18+
}
19+
20+
private let dependencies: Dependencies
21+
22+
private var stores: StoresManager {
23+
dependencies.stores
24+
}
25+
26+
private var noticePresenter: NoticePresenter {
27+
dependencies.noticePresenter
28+
}
29+
30+
private var analytics: Analytics {
31+
dependencies.analytics
32+
}
33+
34+
// MARK: - Output properties
535
let completion: () -> Void
6-
private let stores: StoresManager
7-
private let noticePresenter: NoticePresenter
836

937
@Published var awaitingResponse = false
1038

39+
let analyticReason: String = CardPresentPaymentOnboardingState.codPaymentGatewayNotSetUp.reasonForAnalytics ?? ""
40+
41+
// MARK: - Configuration properties
42+
private let cardPresentPaymentsConfiguration: CardPresentPaymentsConfiguration
43+
1144
private var siteID: Int64? {
1245
stores.sessionManager.defaultStoreID
1346
}
1447

15-
init(stores: StoresManager = ServiceLocator.stores,
16-
noticePresenter: NoticePresenter = ServiceLocator.noticePresenter,
48+
init(dependencies: Dependencies = Dependencies(),
49+
configuration: CardPresentPaymentsConfiguration,
1750
completion: @escaping () -> Void) {
18-
self.stores = stores
19-
self.noticePresenter = noticePresenter
51+
self.dependencies = dependencies
52+
self.cardPresentPaymentsConfiguration = configuration
2053
self.completion = completion
2154
}
2255

56+
// MARK: - Actions
2357
func skipTapped() {
58+
trackSkipTapped()
59+
2460
guard let siteID = siteID else {
2561
return completion()
2662
}
@@ -31,6 +67,8 @@ final class InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel: Obser
3167
}
3268

3369
func enableTapped() {
70+
trackEnableTapped()
71+
3472
guard let siteID = siteID else {
3573
return completion()
3674
}
@@ -43,9 +81,11 @@ final class InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel: Obser
4381
DDLogError("💰 Could not update Payment Gateway: \(String(describing: result.failure))")
4482
self.awaitingResponse = false
4583
self.displayEnableCashOnDeliveryFailureNotice()
84+
self.trackEnableCashOnDeliveryFailed(error: result.failure)
4685
return
4786
}
4887

88+
self.trackEnableCashOnDeliverySuccess()
4989
self.completion()
5090
}
5191
stores.dispatch(action)
@@ -72,6 +112,35 @@ final class InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel: Obser
72112
}
73113
}
74114

115+
// MARK: - Analytics
116+
private extension InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel {
117+
typealias Event = WooAnalyticsEvent.InPersonPayments
118+
119+
func trackSkipTapped() {
120+
let event = Event.cardPresentOnboardingStepSkipped(reason: analyticReason,
121+
remindLater: false,
122+
countryCode: cardPresentPaymentsConfiguration.countryCode)
123+
analytics.track(event: event)
124+
}
125+
126+
func trackEnableTapped() {
127+
let event = Event.cardPresentOnboardingCtaTapped(reason: analyticReason,
128+
countryCode: cardPresentPaymentsConfiguration.countryCode)
129+
analytics.track(event: event)
130+
}
131+
132+
func trackEnableCashOnDeliverySuccess() {
133+
let event = Event.enableCashOnDeliverySuccess(countryCode: cardPresentPaymentsConfiguration.countryCode)
134+
analytics.track(event: event)
135+
}
136+
137+
func trackEnableCashOnDeliveryFailed(error: Error?) {
138+
let event = Event.enableCashOnDeliveryFailed(countryCode: cardPresentPaymentsConfiguration.countryCode,
139+
error: error)
140+
analytics.track(event: event)
141+
}
142+
}
143+
75144
private enum Localization {
76145
static let cashOnDeliveryCheckoutTitle = NSLocalizedString(
77146
"Pay in Person",

0 commit comments

Comments
 (0)