Skip to content
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

Merged
merged 12 commits into from
Feb 14, 2025

Conversation

iamgabrielma
Copy link
Contributor

@iamgabrielma iamgabrielma commented Feb 13, 2025

Closes: #15128

Description

This PR creates POSCollectOrderPaymentAnalytics, a new implementation of the CollectOrderPaymentAnalyticsTracking protocol. We use this in order to track card-payment related events and their properties from POS without interfering with IPP events. We also need to do so as the event tracking logic is very deeply embedded into the card payment service.

Since we have to keep track of time intervals for different operations (order creation, card readiness, transaction successful), we also DI this instance into the aggregate model in order to be able to pass starting and ending time for these intervals.

Only the pos_card_present_collect_payment_success and one property (milliseconds_since_customer_interaction_started) is tracked on this PR, there are more properties that we need to track for this single event, but these will come on a following PR:

// Missing properties at this point:
milliseconds_since_order_creation_success
milliseconds_since_reader_ready_to_collect_payment
milliseconds_since_card_tapped
checkout_tap_count

Testing information

  • Run POS with either physical card reader or simulated one
  • Process a card present transaction
  • Upon success, observe the event pos_card_present_collect_payment_success with property milliseconds_since_customer_interaction_started is captured:
🔵 Tracked pos_card_present_collect_payment_success, properties: [milliseconds_since_customer_interaction_started: 21879.66299057007, is_wpcom_store: false, plan: , store_id: c5bd46cc-1804-4f7b-badb-bb98c449127f, was_ecommerce_trial: false, site_url: https://indiemelon.mystagingwebsite.com, blog_id: -1]
  • Repeat for an IPP transaction in the app side. Observe that the pos event is not tracked, but the default IPP card_present_collect_payment_success instead.

  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Reviewer (or Author, in the case of optional code reviews):

Please make sure these conditions are met before approving the PR, or request changes if the PR needs improvement:

  • The PR is small and has a clear, single focus, or a valid explanation is provided in the description. If needed, please request to split it into smaller PRs.
  • Ensure Adequate Unit Test Coverage: The changes are reasonably covered by unit tests or an explanation is provided in the PR description.
  • Manual Testing: The author listed all the tests they ran, including smoke tests when needed (e.g., for refactorings). The reviewer confirmed that the PR works as expected on all devices (phone/tablet) and no regressions are added.

@dangermattic
Copy link
Collaborator

dangermattic commented Feb 13, 2025

1 Warning
⚠️ View files have been modified, but no screenshot or video is included in the pull request. Consider adding some for clarity.
1 Message
📖

This PR contains changes to Tracks-related logic. Please ensure (author and reviewer) the following are completed:

  • The tracks events must be validated in the Tracks system.
  • Verify the internal Tracks spreadsheet has also been updated.
  • Please consider registering any new events.
  • The PR must be assigned the category: tracks label.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Feb 13, 2025

WooCommerce iOS📲 You can test the changes from this Pull Request in WooCommerce iOS by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS WooCommerce iOS
Build Numberpr15138-1bf71d3
Version21.7
Bundle IDcom.automattic.alpha.woocommerce
Commit1bf71d3
App Center BuildWooCommerce - Prototype Builds #12967
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

@iamgabrielma iamgabrielma added type: task An internally driven task. category: tracks Related to analytics, including Tracks Events. feature: POS labels Feb 13, 2025
@iamgabrielma iamgabrielma added this to the 21.8 milestone Feb 13, 2025
@iamgabrielma iamgabrielma marked this pull request as ready for review February 13, 2025 15:24
@iamgabrielma iamgabrielma requested a review from staskus February 13, 2025 15:25
Copy link
Contributor

@staskus staskus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Works well 👍

I also tested IPP payments to confirm that it doesn't use POS logic.

I noticed when POS opens I get pos_pos:

image

@@ -149,6 +153,14 @@ extension PointOfSaleAggregateModel {
paymentState = .card(.idle)
cardPresentPaymentInlineMessage = nil
}

private func trackCustomerInteractionStarted() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

;nit

We can put in these trackings into a different extension for code organization

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated! 66141e4


func trackCustomerInteractionStarted()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit;

Theoretically, we could have

POSCollectOrderPaymentAnalyticsTracking: CollectOrderPaymentAnalyticsTracking that has func trackCustomerInteractionStarted(), and POSCollectOrderPaymentAnalytics would implement POSCollectOrderPaymentAnalyticsTracking. This way non-POS parts of the code, such as various preflight controllers wouldn't have knowledge of trackCustomerInteractionStarted. POS aggregate model would expect POSCollectOrderPaymentAnalyticsTracking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, playing a bit more with the conformances here looks a good idea since we have so much shared logic 🤔

@@ -136,6 +136,7 @@ final class HubMenuViewModel: ObservableObject {
}()

private(set) var cardPresentPaymentService: CardPresentPaymentFacade?
private(set) var collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't love that we use HubMenuViewModel as POS factory but we can deal with both creation of cardPresentPaymentService and collectOrderPaymentAnalyticsTracker in some future improvement PR if needed.

private 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should clearing the cart reset the customer interaction time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

func trackSuccessfulPayment(capturedPaymentData: CardPresentCapturedPaymentData) {
let elapsedTime = calculateElapsedTimeInMilliseconds(start: customerInteractionStarted, end: Date().timeIntervalSince1970)
ServiceLocator.analytics.track(event:
.PointOfSale.cardPresentCollectPaymentSuccess(millisecondsSinceCustomerIteractionStated: elapsedTime))
Copy link
Contributor

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 part 16712?

Copy link
Contributor Author

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

🔵 Tracked pos_card_present_collect_payment_success, properties: [plan: , site_url: https://indiemelon.mystagingwebsite.com, milliseconds_since_customer_interaction_started: 27589.0, blog_id: -1, is_wpcom_store: false, was_ecommerce_trial: false, store_id: c5bd46cc-1804-4f7b-badb-bb98c449127f]

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.

Copy link
Contributor

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.

@iamgabrielma
Copy link
Contributor Author

Thanks for the review!

I noticed when POS opens I get pos_pos:

Yes, this duplication was triggering me a bit but was the "official" event 😅 (Ref: pdfdoF-6hn#comment-7556-p2 ) , it's resolved now: b5fd2b3

@iamgabrielma iamgabrielma merged commit a477857 into trunk Feb 14, 2025
12 checks passed
@iamgabrielma iamgabrielma deleted the task/15128-resolve-card-present-events-from-pos branch February 14, 2025 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: tracks Related to analytics, including Tracks Events. feature: POS type: task An internally driven task.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Woo POS] MVP Analytics: Resolve card-related events in payment service that use POS properties
4 participants