-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Woo POS] MVP analytics: Handle card present events from POS #15138
Changes from all commits
f346fac
94eae8e
3e3424a
f43fb21
da2729f
f958e4f
5fd196f
b5fd2b3
66141e4
4748a30
bfac5ec
1bf71d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import Yosemite | ||
|
||
final class POSCollectOrderPaymentAnalytics: CollectOrderPaymentAnalyticsTracking { | ||
var connectedReaderModel: String? | ||
|
||
private var customerInteractionStarted: Double = 0 | ||
|
||
func preflightResultReceived(_ result: CardReaderPreflightResult?) { } | ||
func trackProcessingCompletion(intent: Yosemite.PaymentIntent) { } | ||
|
||
func trackSuccessfulPayment(capturedPaymentData: CardPresentCapturedPaymentData) { | ||
let elapsedTime = calculateElapsedTimeInMilliseconds(start: customerInteractionStarted, end: Date().timeIntervalSince1970) | ||
ServiceLocator.analytics.track(event: | ||
.PointOfSale.cardPresentCollectPaymentSuccess(millisecondsSinceCustomerIteractionStated: elapsedTime)) | ||
} | ||
|
||
func trackPaymentFailure(with error: any Error) { } | ||
func trackPaymentCancelation(cancelationSource: WooAnalyticsEvent.InPersonPayments.CancellationSource) { } | ||
func trackEmailTapped() { } | ||
func trackReceiptPrintTapped() { } | ||
func trackReceiptPrintSuccess() { } | ||
func trackReceiptPrintCanceled() { } | ||
func trackReceiptPrintFailed(error: any Error) { } | ||
|
||
func trackCustomerInteractionStarted() { | ||
customerInteractionStarted = Date().timeIntervalSince1970 | ||
} | ||
|
||
private func calculateElapsedTimeInMilliseconds(start: Double, end: Double) -> Double { | ||
floor((end - start) * 1000) | ||
} | ||
} | ||
|
||
// Protocol conformance. These events are not needed for IPP, only for POS. | ||
extension CollectOrderPaymentAnalytics { | ||
func trackCustomerInteractionStarted() { } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,7 @@ protocol PointOfSaleAggregateModelProtocol { | |
private let cardPresentPaymentService: CardPresentPaymentFacade | ||
private let orderController: PointOfSaleOrderControllerProtocol | ||
private let analytics: Analytics | ||
private let collectOrderPaymentAnalyticsTracker: CollectOrderPaymentAnalyticsTracking | ||
|
||
private var startPaymentOnCardReaderConnection: AnyCancellable? | ||
private var cardReaderDisconnection: AnyCancellable? | ||
|
@@ -72,11 +73,13 @@ protocol PointOfSaleAggregateModelProtocol { | |
cardPresentPaymentService: CardPresentPaymentFacade, | ||
orderController: PointOfSaleOrderControllerProtocol, | ||
analytics: Analytics = ServiceLocator.analytics, | ||
collectOrderPaymentAnalyticsTracker: CollectOrderPaymentAnalyticsTracking, | ||
paymentState: PointOfSalePaymentState = .card(.idle)) { | ||
self.itemsController = itemsController | ||
self.cardPresentPaymentService = cardPresentPaymentService | ||
self.orderController = orderController | ||
self.analytics = analytics | ||
self.collectOrderPaymentAnalyticsTracker = collectOrderPaymentAnalyticsTracker | ||
self.paymentState = paymentState | ||
publishCardReaderConnectionStatus() | ||
publishPaymentMessages() | ||
|
@@ -121,6 +124,7 @@ private extension POSItem { | |
@available(iOS 17.0, *) | ||
extension PointOfSaleAggregateModel { | ||
func addToCart(_ item: POSItem) { | ||
trackCustomerInteractionStarted() | ||
guard let cartItem = item.cartItem else { return } | ||
cart.insert(cartItem, at: cart.startIndex) | ||
} | ||
|
@@ -151,6 +155,18 @@ extension PointOfSaleAggregateModel { | |
} | ||
} | ||
|
||
// MARK: - Track events | ||
@available(iOS 17.0, *) | ||
private extension PointOfSaleAggregateModel { | ||
func trackCustomerInteractionStarted() { | ||
// At the moment we're assumming that an interaction starts simply when the cart is zero | ||
// but a more complex logic will be needed for other cases | ||
if cart.count == 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should clearing the cart reset the customer interaction time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question, I don't think we're clear on that yet. Initially it would seem we would, but I have some doubts about it. Context: pdfdoF-6hn#comment-7582-p2 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Lets sync with Android. Otherwise, in some cases we could have inconclusive data. |
||
collectOrderPaymentAnalyticsTracker.trackCustomerInteractionStarted() | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Card payments | ||
@available(iOS 17.0, *) | ||
extension PointOfSaleAggregateModel { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We send value such as
16712.467908859253
, should we floor it, and send only the millisecond part16712
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good to me. Updated here: 4748a30
Since we floor the value and we return a Double, we always get the
.0
which I don't think it's necessary, perhaps returning an Int here is enough as the event key already tells is milliseconds. I'll iterate on this when adding the rest of properties.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Lets sync with Android on this.