Skip to content

Commit dfbdb2d

Browse files
authored
Merge pull request #7858 from woocommerce/issue/7856-utm-params-on-card-reader-links
[Just In Time Messages] Send UTM params on card reader purchase links
2 parents 3be1e11 + b09fdf1 commit dfbdb2d

File tree

17 files changed

+260
-15
lines changed

17 files changed

+260
-15
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
10.8
44
-----
55
- [***] Stats: Now you can add a Today's Stats Widget to your lock screen (iOS 16 only) to monitor your sales. [https://github.com/woocommerce/woocommerce-ios/pull/7839]
6+
- [internal] In-Person Payments: add UTM parameters to card reader purchase URLs to allow attribution [https://github.com/woocommerce/woocommerce-ios/pull/7858]
67

78
10.7
89
-----

WooCommerce/Classes/Authentication/AuthenticatedWebViewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ private extension AuthenticatedWebViewController {
128128
guard let url = viewModel.initialURL else {
129129
return
130130
}
131+
131132
if let credentials = ServiceLocator.stores.sessionManager.defaultCredentials {
132133
webView.authenticateForWPComAndRedirect(to: url, credentials: credentials)
133134
} else {

WooCommerce/Classes/ViewModels/Feature Announcement Cards/FeatureAnnouncementCardViewModel.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Foundation
22
import UIKit
33
import Yosemite
4+
import WooFoundation
45

56
private typealias FeatureCardEvent = WooAnalyticsEvent.FeatureCard
67

WooCommerce/Classes/ViewModels/Feature Announcement Cards/UpsellCardReadersCampaign.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Foundation
2+
import WooFoundation
23

34
struct UpsellCardReadersCampaign {
45
let source: WooAnalyticsEvent.FeatureCard.Source
@@ -52,3 +53,17 @@ extension UpsellCardReadersCampaign {
5253
comment: "Message for a dismissal alert on the upsell card reader feature announcement banner")
5354
}
5455
}
56+
57+
extension UpsellCardReadersCampaign {
58+
var utmProvider: WooCommerceComUTMProvider {
59+
WooCommerceComUTMProvider(
60+
campaign: Constants.utmCampaign,
61+
source: source.rawValue,
62+
content: configuration.campaign.rawValue,
63+
siteID: ServiceLocator.stores.sessionManager.defaultStoreID)
64+
}
65+
}
66+
67+
private enum Constants {
68+
static let utmCampaign = "feature_announcement_card"
69+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
import Yosemite
3+
import WooFoundation
34

45
final class InPersonPaymentsMenuViewModel {
56
// MARK: - Dependencies
@@ -52,8 +53,18 @@ final class InPersonPaymentsMenuViewModel {
5253
func orderCardReaderPressed() {
5354
analytics.track(.paymentsMenuOrderCardReaderTapped)
5455
showWebView = PurchaseCardReaderWebViewViewModel(configuration: cardPresentPaymentsConfiguration,
56+
utmProvider: WooCommerceComUTMProvider(
57+
campaign: Constants.utmCampaign,
58+
source: Constants.utmSource,
59+
content: nil,
60+
siteID: siteID),
5561
onDismiss: { [weak self] in
5662
self?.showWebView = nil
5763
})
5864
}
5965
}
66+
67+
private enum Constants {
68+
static let utmCampaign = "payments_menu_item"
69+
static let utmSource = "payments_menu"
70+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Foundation
22
import Yosemite
33
import WebKit
4+
import WooFoundation
45

56
struct PurchaseCardReaderWebViewViewModel: AuthenticatedWebViewModel {
67
var title: String
@@ -10,9 +11,10 @@ struct PurchaseCardReaderWebViewViewModel: AuthenticatedWebViewModel {
1011
let onDismiss: () -> Void
1112

1213
init(configuration: CardPresentPaymentsConfiguration = CardPresentConfigurationLoader().configuration,
14+
utmProvider: UTMParametersProviding,
1315
onDismiss: @escaping () -> Void) {
1416
self.title = Localization.title
15-
self.initialURL = configuration.purchaseCardReaderUrl()
17+
self.initialURL = configuration.purchaseCardReaderUrl(utmProvider: utmProvider)
1618
self.onDismiss = onDismiss
1719
}
1820

WooCommerce/Classes/ViewRelated/Orders/OrderListViewController.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import Gridicons
44
import Yosemite
55
import WordPressUI
66
import SafariServices
7-
import StoreKit
87
import SwiftUI
8+
import WooFoundation
99

1010
// Used for protocol conformance of IndicatorInfoProvider only.
1111
import XLPagerTabStrip
@@ -418,7 +418,10 @@ extension OrderListViewController: SyncingCoordinatorDelegate {
418418
self?.viewModel.dismissUpsellCardReadersBanner()
419419
}, callToAction: {
420420
let configuration = CardPresentConfigurationLoader().configuration
421-
WebviewHelper.launch(configuration.purchaseCardReaderUrl(), with: self)
421+
WebviewHelper.launch(
422+
configuration.purchaseCardReaderUrl(
423+
utmProvider: self.viewModel.upsellCardReadersCampaign.utmProvider),
424+
with: self)
422425
})
423426
.background(Color(.listForeground))
424427

WooCommerce/Classes/ViewRelated/Orders/OrderListViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class OrderListViewModel {
2626

2727
/// Used to show the upsell card readers banner and discern its visibility
2828
///
29-
private let upsellCardReadersCampaign = UpsellCardReadersCampaign(source: .orderList)
29+
let upsellCardReadersCampaign = UpsellCardReadersCampaign(source: .orderList)
3030
let upsellCardReadersAnnouncementViewModel: FeatureAnnouncementCardViewModel
3131

3232
/// Used for cancelling the observer for Remote Notifications when `self` is deallocated.

WooCommerce/Classes/ViewRelated/Orders/Payment Methods/PaymentMethodsViewModel.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//import Experiments
21
import Foundation
32
import Yosemite
43
import Combine
54
import UIKit
5+
import WooFoundation
66

77
import protocol Storage.StorageManagerType
88

@@ -51,7 +51,7 @@ final class PaymentMethodsViewModel: ObservableObject {
5151
/// Returns the URL where the merchant can purchase a card reader based on store country code
5252
///
5353
var purchaseCardReaderUrl: URL {
54-
cardPresentPaymentsConfiguration.purchaseCardReaderUrl()
54+
cardPresentPaymentsConfiguration.purchaseCardReaderUrl(utmProvider: upsellCardReadersCampaign.utmProvider)
5555
}
5656

5757
/// Store's ID.
@@ -103,7 +103,7 @@ final class PaymentMethodsViewModel: ObservableObject {
103103

104104
private let cardPresentPaymentsConfiguration: CardPresentPaymentsConfiguration
105105

106-
private let upsellCardReadersCampaign = UpsellCardReadersCampaign(source: .paymentMethods)
106+
private let upsellCardReadersCampaign = UpsellCardReadersCampaign(source: .paymentMethods)
107107

108108
var upsellCardReadersAnnouncementViewModel: FeatureAnnouncementCardViewModel {
109109
.init(analytics: analytics,

WooCommerce/WooCommerceTests/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsMenuViewModelTests.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ class InPersonPaymentsMenuViewModelTests: XCTestCase {
6666
sut.orderCardReaderPressed()
6767

6868
// Then
69-
let cardReaderViewModel = try XCTUnwrap(sut.showWebView)
70-
assertEqual(configuration.purchaseCardReaderUrl(), cardReaderViewModel.initialURL)
69+
let cardReaderPurchaseURL = try XCTUnwrap(sut.showWebView?.initialURL)
70+
assertEqual("https", cardReaderPurchaseURL.scheme)
71+
assertEqual("woocommerce.com", cardReaderPurchaseURL.host)
72+
assertEqual("/products/hardware/US", cardReaderPurchaseURL.path)
73+
let query = try XCTUnwrap(cardReaderPurchaseURL.query)
74+
XCTAssert(query.contains("utm_medium=woo_ios"))
75+
XCTAssert(query.contains("utm_campaign=payments_menu_item"))
76+
XCTAssert(query.contains("utm_source=payments_menu"))
7177
}
7278
}

0 commit comments

Comments
 (0)