Skip to content

Conversation

baubrey91
Copy link
Contributor

@baubrey91 baubrey91 commented Jul 7, 2025

Thank you for your contribution to Braintree.

Before submitting this PR, note we cannot accept language translation PRs. We support the same languages that are supported by PayPal, and have a dedicated localization team to provide the translations. If there is an error in a specific translation, you may open an issue and we will escalate it to the localization team.

Summary of changes

When sending up analytics we will also record the application state ie background, active, inactive.

Checklist

  • Added a changelog entry
  • Tested and confirmed payment flows affected by this change are functioning as expected

Authors

List GitHub usernames for everyone who contributed to this pull request.

FPTI

image

@baubrey91 baubrey91 requested a review from a team as a code owner July 7, 2025 18:14
@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch 2 times, most recently from 76de656 to 5265b44 Compare July 16, 2025 21:00
@jaxdesmarais
Copy link
Contributor

@baubrey91 I have added the do not review tag, please ensure CI is passing before we re-review.

@baubrey91 baubrey91 marked this pull request as draft July 22, 2025 18:14
@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch from 6bce253 to 1cdef7f Compare July 22, 2025 18:33
@baubrey91 baubrey91 marked this pull request as ready for review July 22, 2025 18:59
@baubrey91
Copy link
Contributor Author

The two tests failing for me are testThreeDSecurePaymentFlowV2_challengeFlow_andFails and testGetRewardsBalance_returnsResult. Are theses generally flaky tests? testGetRewardsBalance_returnsResult passes for me locally and testThreeDSecurePaymentFlowV2_challengeFlow_andFails fails on main.

@stechiu
Copy link
Contributor

stechiu commented Jul 23, 2025

The two tests failing for me are testThreeDSecurePaymentFlowV2_challengeFlow_andFails and testGetRewardsBalance_returnsResult. Are theses generally flaky tests? testGetRewardsBalance_returnsResult passes for me locally and testThreeDSecurePaymentFlowV2_challengeFlow_andFails fails on main.

Yes, these tests are flaky in CI. Try "re-run failed tests"

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch from 1cdef7f to 25e39e9 Compare July 25, 2025 20:42
@baubrey91 baubrey91 marked this pull request as draft July 25, 2025 20:44
@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch 3 times, most recently from edbc07a to 7f1502e Compare July 25, 2025 21:09
@baubrey91 baubrey91 marked this pull request as ready for review July 28, 2025 16:30
@baubrey91 baubrey91 marked this pull request as draft July 28, 2025 16:31
@baubrey91 baubrey91 marked this pull request as ready for review July 28, 2025 17:29
let payPalInstalled: Bool = application.isPayPalAppInstalled()

let platform = "iOS"

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't need this newline:

Suggested change

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch 2 times, most recently from ae7ebaa to 470efb8 Compare July 30, 2025 17:16
@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch 4 times, most recently from f50b4eb to 547b8e4 Compare July 30, 2025 17:22
@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch 2 times, most recently from 953ee3f to e7e5f92 Compare August 15, 2025 23:50
/// Encapsulates a single event by it's name and timestamp.
struct Event: Codable {

/// The app's state within the device's lifecycle (ie active, inactive, background)
Copy link
Contributor

Choose a reason for hiding this comment

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

small nit:

Suggested change
/// The app's state within the device's lifecycle (ie active, inactive, background)
/// The app's state within the device's lifecycle (i.e active, inactive, background)

@agedd
Copy link
Contributor

agedd commented Aug 19, 2025

looking good - ty for addressing the comments above! two quick notes - and happy to pair on this:

  • can we resolve the merge conflicts within BTPayPalClient
  • can we also verify that this new tag is sent to FPTI by running a checkout or vault flow

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch 2 times, most recently from 054119f to d50ff8f Compare August 19, 2025 20:11
@agedd
Copy link
Contributor

agedd commented Aug 19, 2025

nit: can we also add a unit test in BTPayPalClient_Tests to make sure that the applicationState in the analytics event is being sent

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch from d50ff8f to 64c3b8b Compare August 20, 2025 15:19
@baubrey91
Copy link
Contributor Author

nit: can we also add a unit test in BTPayPalClient_Tests to make sure that the applicationState in the analytics event is being sent

I added a test in BTPayPalClient_Tests but am not positive if its the right naming convention or if you wanted me to just add an assert in another test. May need help. Thanks!

XCTAssertEqual(mockAPIClient.postedShopperSessionID, "fake-shopper-session-id")
}

func testTokenize_applicationStateAnalytics() async {
Copy link
Contributor

Choose a reason for hiding this comment

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

small nit:

Suggested change
func testTokenize_applicationStateAnalytics() async {
func testTokenize_whenSuccess_ sendsapplicationStateInAnalytics() async {

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch from 64c3b8b to 7db62da Compare August 20, 2025 17:04
Copy link
Contributor

@jaxdesmarais jaxdesmarais left a comment

Choose a reason for hiding this comment

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

Lets add a changelog entry for this. There should be several similar entries when adding new tags to reference.

Also to confirm we have tested that doing something like backgrounding the app while sending an event fetches the correct state and does not cause a crash?

@baubrey91
Copy link
Contributor Author

Lets add a changelog entry for this. There should be several similar entries when adding new tags to reference.

Also to confirm we have tested that doing something like backgrounding the app while sending an event fetches the correct state and does not cause a crash?

@jaxdesmarais I updated the changelog, wasn't sure if we wanted to do that as this is an internal feature for FPTI. For testing I set a repeated task to continue send up an analytic and checked to see if it was sent while background. Are you asking to test if the state changes while we are sending? Do you have an idea how to test that? Would this require setting up an async task in the app delegate. Thanks!

        Task {
            repeat {
                apiClient.sendAnalyticsEvent(
                    BTPayPalAnalytics.tokenizeStarted,
                    applicationState: UIApplication.shared.applicationStateString,
                    contextType: contextType,
                    didEnablePayPalAppSwitch: payPalRequest?.enablePayPalAppSwitch,
                    isVaultRequest: isVaultRequest,
                    shopperSessionID: payPalRequest?.shopperSessionID
                )
                try? await Task.sleep(nanoseconds: 5_000_000_000) // Sleep for 5 second
            } while !Task.isCancelled //
        }

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch from fed2f4c to 4b02d57 Compare August 22, 2025 16:46
@jaxdesmarais
Copy link
Contributor

I updated the changelog, wasn't sure if we wanted to do that as this is an internal feature for FPTI.

It's generally helpful for us to know what version a FPTI change was made in, so still worth having one.

For testing I set a repeated task to continue send up an analytic and checked to see if it was sent while background. Are you asking to test if the state changes while we are sending? Do you have an idea how to test that? Would this require setting up an async task in the app delegate. Thanks!

Sorry should have been more clear. I more meant backgrounding the app and ensuring the application state is correct since it's sent on main. So something like:

  1. Open app
  2. Click on paypal and immediately background the app
  3. Ensure the application state is correct (should be background) and does not crash the app when attempting to fetch the state on main as the app is backgrounded

CHANGELOG.md Outdated
* Analytics updates for PayPal's analytics service (FPTI)
* Add `space_key` and `product_name` to `batch_params`
* Add `context_type` to `event_params`
* Add `application_state` to PayPal analytics for tracking UIApplication state
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be moved under ## unreleased

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aw man I did that initially, must have broke it when I rebased

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aw man I did that initially, must have broke it when I rebased


let eventParams = [
FPTIBatchData.Event(
applicationState: UIApplication.shared.applicationStateString,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can hardcode this value for the test

@baubrey91
Copy link
Contributor Author

I updated the changelog, wasn't sure if we wanted to do that as this is an internal feature for FPTI.

It's generally helpful for us to know what version a FPTI change was made in, so still worth having one.

For testing I set a repeated task to continue send up an analytic and checked to see if it was sent while background. Are you asking to test if the state changes while we are sending? Do you have an idea how to test that? Would this require setting up an async task in the app delegate. Thanks!

Sorry should have been more clear. I more meant backgrounding the app and ensuring the application state is correct since it's sent on main. So something like:

  1. Open app
  2. Click on paypal and immediately background the app
  3. Ensure the application state is correct (should be background) and does not crash the app when attempting to fetch the state on main as the app is backgrounded

So I did test this previously, when vaulting the app is backgrounded regardless, but now I have also tested with web checkout. Attached is a video and FTPI however out of curiosity do you guys use feature switches. We could wrap this behind one and ramp it up incase there is an issue.

Simulator.Screen.Recording.-.iPhone.16.-.2025-08-26.at.10.14.52.mp4
image

@baubrey91 baubrey91 force-pushed the feature/application-state-analytics branch from 4b02d57 to 5917c97 Compare August 27, 2025 16:02
Copy link
Contributor

@jaxdesmarais jaxdesmarais left a comment

Choose a reason for hiding this comment

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

Thanks for addressing comments and doing thorough testing! 🚀

Copy link
Contributor

@agedd agedd left a comment

Choose a reason for hiding this comment

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

lgtm ~ just left a small nit comment 🚀

@jaxdesmarais jaxdesmarais merged commit 87bd410 into braintree:main Aug 27, 2025
11 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants