Skip to content

Commit

Permalink
Send paypal_context_id at Event Level (#1211)
Browse files Browse the repository at this point in the history
* Move paypal_context_id from batch_params to event_params
    * Cleaned up implementation
* Alphabetized parameters order in sendAnalyticsEvent
* Update tests
  • Loading branch information
jaxdesmarais authored Mar 11, 2024
1 parent e48237a commit caae093
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 40 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* If set to `true` customers will fallback to a web based Venmo flow if the Venmo app is not installed
* This method uses Universal Links instead of URL Schemes
* BraintreeCore
* Send `paypal_context_id` in `batch_params` to PayPal's analytics service (FPTI) when available
* Send `paypal_context_id` in `event_params` to PayPal's analytics service (FPTI) when available
* Send `link_type` in `event_params` to PayPal's analytics service (FPTI)
* Fix bug where FPTI analytic events were being sent multiple times

Expand Down
20 changes: 8 additions & 12 deletions Sources/BraintreeCore/Analytics/BTAnalyticsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ class BTAnalyticsService: Equatable {

private let apiClient: BTAPIClient

private var payPalContextID: String?

// MARK: - Initializer

init(apiClient: BTAPIClient) {
Expand All @@ -25,22 +23,22 @@ class BTAnalyticsService: Equatable {
/// Sends analytics event to https://api.paypal.com/v1/tracking/batch/events/ via a background task.
/// - Parameters:
/// - eventName: Name of analytic event.
/// - errorDescription: Optional. Full error description returned to merchant.
/// - correlationID: Optional. CorrelationID associated with the checkout session.
/// - payPalContextID: Optional. PayPal Context ID associated with the checkout session.
/// - errorDescription: Optional. Full error description returned to merchant.
/// - linkType: Optional. The type of link the SDK will be handling, currently deeplink or universal.
/// - payPalContextID: Optional. PayPal Context ID associated with the checkout session.
func sendAnalyticsEvent(
_ eventName: String,
errorDescription: String? = nil,
correlationID: String? = nil,
payPalContextID: String? = nil,
linkType: String? = nil
errorDescription: String? = nil,
linkType: String? = nil,
payPalContextID: String? = nil
) {
Task(priority: .background) {
await performEventRequest(
eventName,
errorDescription: errorDescription,
correlationID: correlationID,
errorDescription: errorDescription,
linkType: linkType,
payPalContextID: payPalContextID
)
Expand All @@ -50,19 +48,18 @@ class BTAnalyticsService: Equatable {
/// Exposed to be able to execute this function synchronously in unit tests
func performEventRequest(
_ eventName: String,
errorDescription: String? = nil,
correlationID: String? = nil,
errorDescription: String? = nil,
linkType: String? = nil,
payPalContextID: String? = nil
) async {
self.payPalContextID = payPalContextID

let timestampInMilliseconds = UInt64(Date().timeIntervalSince1970 * 1000)
let event = FPTIBatchData.Event(
correlationID: correlationID,
errorDescription: errorDescription,
eventName: eventName,
linkType: linkType,
payPalContextID: payPalContextID,
timestamp: String(timestampInMilliseconds)
)

Expand Down Expand Up @@ -101,7 +98,6 @@ class BTAnalyticsService: Equatable {
environment: config.fptiEnvironment,
integrationType: apiClient.metadata.integration.stringValue,
merchantID: config.merchantID,
payPalContextID: payPalContextID,
sessionID: sessionID,
tokenizationKey: apiClient.tokenizationKey
)
Expand Down
9 changes: 4 additions & 5 deletions Sources/BraintreeCore/Analytics/FPTIBatchData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ struct FPTIBatchData: Codable {
let eventName: String
/// The type of link the SDK will be handling, currently deeplink or universal
let linkType: String?
/// Used for linking events from the client to server side request
/// This value will be PayPal Order ID, Payment Token, EC token, Billing Agreement, or Venmo Context ID depending on the flow
let payPalContextID: String?
let timestamp: String
let tenantName: String = "Braintree"

Expand All @@ -40,6 +43,7 @@ struct FPTIBatchData: Codable {
case errorDescription = "error_desc"
case eventName = "event_name"
case linkType = "link_type"
case payPalContextID = "paypal_context_id"
case timestamp = "t"
case tenantName = "tenant_name"
}
Expand Down Expand Up @@ -101,10 +105,6 @@ struct FPTIBatchData: Codable {

let merchantID: String?

/// Used for linking events from the client to server side request
/// This value will be PayPal Order ID, Payment Token, EC token or Billing Agreement depending on the flow
let payPalContextID: String?

let platform = "iOS"

let sessionID: String
Expand All @@ -127,7 +127,6 @@ struct FPTIBatchData: Codable {
case isSimulator = "is_simulator"
case merchantAppVersion = "mapv"
case merchantID = "merchant_id"
case payPalContextID = "paypal_context_id"
case platform = "platform"
case sessionID = "session_id"
case tokenizationKey = "tokenization_key"
Expand Down
12 changes: 6 additions & 6 deletions Sources/BraintreeCore/BTAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -341,17 +341,17 @@ import Foundation
@_documentation(visibility: private)
public func sendAnalyticsEvent(
_ eventName: String,
errorDescription: String? = nil,
correlationID: String? = nil,
payPalContextID: String? = nil,
linkType: String? = nil
errorDescription: String? = nil,
linkType: String? = nil,
payPalContextID: String? = nil
) {
analyticsService?.sendAnalyticsEvent(
eventName,
errorDescription: errorDescription,
correlationID: correlationID,
payPalContextID: payPalContextID,
linkType: linkType
errorDescription: errorDescription,
linkType: linkType,
payPalContextID: payPalContextID
)
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/BraintreePayPal/BTPayPalClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ import BraintreeDataCollector
private func notifyFailure(with error: Error, completion: @escaping (BTPayPalAccountNonce?, Error?) -> Void) {
apiClient.sendAnalyticsEvent(
BTPayPalAnalytics.tokenizeFailed,
errorDescription: error.localizedDescription,
correlationID: clientMetadataID,
errorDescription: error.localizedDescription,
payPalContextID: payPalContextID
)
completion(nil, error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ import PayPalCheckout
private func notifyFailure(with error: Error, completion: @escaping (BTPayPalNativeCheckoutAccountNonce?, Error?) -> Void) {
apiClient.sendAnalyticsEvent(
BTPayPalNativeCheckoutAnalytics.tokenizeFailed,
errorDescription: error.localizedDescription,
correlationID: clientMetadataID,
errorDescription: error.localizedDescription,
payPalContextID: payPalContextID
)
completion(nil, error)
Expand Down
12 changes: 6 additions & 6 deletions Sources/BraintreeVenmo/BTVenmoClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,11 +352,11 @@ import BraintreeCore
shouldVault = success && vault

if success {
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.appSwitchSucceeded, linkType: linkType)
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.appSwitchSucceeded, linkType: linkType, payPalContextID: payPalContextID)
BTVenmoClient.venmoClient = self
self.appSwitchCompletion = completion
} else {
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.appSwitchFailed, linkType: linkType)
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.appSwitchFailed, linkType: linkType, payPalContextID: payPalContextID)
notifyFailure(with: BTVenmoError.appSwitchFailed, completion: completion)
}
}
Expand Down Expand Up @@ -416,22 +416,22 @@ import BraintreeCore
with result: BTVenmoAccountNonce,
completion: @escaping (BTVenmoAccountNonce?, Error?) -> Void
) {
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.tokenizeSucceeded, payPalContextID: payPalContextID, linkType: linkType)
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.tokenizeSucceeded, linkType: linkType, payPalContextID: payPalContextID)
completion(result, nil)
}

private func notifyFailure(with error: Error, completion: @escaping (BTVenmoAccountNonce?, Error?) -> Void) {
apiClient.sendAnalyticsEvent(
BTVenmoAnalytics.tokenizeFailed,
errorDescription: error.localizedDescription,
payPalContextID: payPalContextID,
linkType: linkType
linkType: linkType,
payPalContextID: payPalContextID
)
completion(nil, error)
}

private func notifyCancel(completion: @escaping (BTVenmoAccountNonce?, Error?) -> Void) {
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.appSwitchCanceled, payPalContextID: payPalContextID, linkType: linkType)
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.appSwitchCanceled, linkType: linkType, payPalContextID: payPalContextID)
completion(nil, BTVenmoError.canceled)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ final class FPTIBatchData_Tests: XCTestCase {
environment: "fake-env",
integrationType: "fake-integration-type",
merchantID: "fake-merchant-id",
payPalContextID: "fake-order-id",
sessionID: "fake-session",
tokenizationKey: "fake-auth"
)
Expand All @@ -22,13 +21,15 @@ final class FPTIBatchData_Tests: XCTestCase {
errorDescription: "fake-error-description-1",
eventName: "fake-event-1",
linkType: "universal",
payPalContextID: "fake-order-id",
timestamp: "fake-time-1"
),
FPTIBatchData.Event(
correlationID: nil,
errorDescription: nil,
eventName: "fake-event-2",
linkType: nil,
payPalContextID: "fake-order-id-2",
timestamp: "fake-time-2"
)
]
Expand Down Expand Up @@ -73,7 +74,6 @@ final class FPTIBatchData_Tests: XCTestCase {
XCTAssertNotNil(batchParams["mapv"] as? String) // Unable to specify bundle version number within test targets
XCTAssertTrue((batchParams["mobile_device_model"] as! String).matches("iPhone\\d,\\d|x86_64|arm64"))
XCTAssertEqual(batchParams["merchant_id"] as! String, "fake-merchant-id")
XCTAssertEqual(batchParams["paypal_context_id"] as! String, "fake-order-id")
XCTAssertEqual(batchParams["platform"] as? String, "iOS")
XCTAssertEqual(batchParams["session_id"] as? String, "fake-session")
XCTAssertEqual(batchParams["tokenization_key"] as! String, "fake-auth")
Expand All @@ -87,6 +87,8 @@ final class FPTIBatchData_Tests: XCTestCase {
XCTAssertEqual(eventParams[1]["tenant_name"] as? String, "Braintree")
XCTAssertEqual(eventParams[0]["link_type"] as? String, "universal")
XCTAssertNil(eventParams[1]["link_type"])
XCTAssertEqual(eventParams[0]["paypal_context_id"] as! String, "fake-order-id")
XCTAssertEqual(eventParams[1]["paypal_context_id"] as! String, "fake-order-id-2")
XCTAssertEqual(eventParams[0]["error_desc"] as? String, "fake-error-description-1")
XCTAssertNil(eventParams[1]["error_desc"])
XCTAssertEqual(eventParams[0]["correlation_id"] as? String, "fake-correlation-id-1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ class FakeAnalyticsService: BTAnalyticsService {

override func sendAnalyticsEvent(
_ eventName: String,
errorDescription: String? = nil,
correlationID: String? = nil,
payPalContextID: String? = nil,
linkType: String? = nil
errorDescription: String? = nil,
linkType: String? = nil,
payPalContextID: String? = nil
) {
self.lastEvent = eventName
}
Expand Down
6 changes: 3 additions & 3 deletions UnitTests/BraintreeTestShared/MockAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ public class MockAPIClient: BTAPIClient {

public override func sendAnalyticsEvent(
_ name: String,
errorDescription: String? = nil,
correlationID: String? = nil,
payPalContextID: String? = nil,
linkType: String? = nil
errorDescription: String? = nil,
linkType: String? = nil,
payPalContextID: String? = nil
) {
postedPayPalContextID = payPalContextID
postedLinkType = linkType
Expand Down

0 comments on commit caae093

Please sign in to comment.