diff --git a/Sources/BraintreeCore/Analytics/FPTIBatchData.swift b/Sources/BraintreeCore/Analytics/FPTIBatchData.swift index 0284172c3..d4fe4845e 100644 --- a/Sources/BraintreeCore/Analytics/FPTIBatchData.swift +++ b/Sources/BraintreeCore/Analytics/FPTIBatchData.swift @@ -53,9 +53,10 @@ struct FPTIBatchData: Codable { /// 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? - /// UTC millisecond timestamp when a networking task started requesting a resource. See [Apple's docs](https://developer.apple.com/documentation/foundation/urlsessiontasktransactionmetrics#3162615). let requestStartTime: Int? + /// This value should be the shopper session ID returned from your server SDK request + let sessionID: String? /// UTC millisecond timestamp when a networking task initiated. let startTime: Int? let timestamp = String(Date().utcTimestampMilliseconds) @@ -76,6 +77,7 @@ struct FPTIBatchData: Codable { paymentMethodsDisplayed: String? = nil, payPalContextID: String? = nil, requestStartTime: Int? = nil, + sessionID: String? = nil, startTime: Int? = nil ) { self.appSwitchURL = appSwitchURL?.absoluteString @@ -92,6 +94,7 @@ struct FPTIBatchData: Codable { self.paymentMethodsDisplayed = paymentMethodsDisplayed self.payPalContextID = payPalContextID self.requestStartTime = requestStartTime + self.sessionID = sessionID self.startTime = startTime } @@ -110,6 +113,7 @@ struct FPTIBatchData: Codable { case requestStartTime = "request_start_time" case timestamp = "t" case tenantName = "tenant_name" + case sessionID = "session_id" case startTime = "start_time" case endTime = "end_time" case endpoint = "endpoint" diff --git a/Sources/BraintreeCore/BTAPIClient.swift b/Sources/BraintreeCore/BTAPIClient.swift index 1d3b04f4d..787f8d2bf 100644 --- a/Sources/BraintreeCore/BTAPIClient.swift +++ b/Sources/BraintreeCore/BTAPIClient.swift @@ -311,7 +311,8 @@ import Foundation linkType: LinkType? = nil, paymentMethodsDisplayed: String? = nil, payPalContextID: String? = nil, - appSwitchURL: URL? = nil + appSwitchURL: URL? = nil, + sessionID: String? = nil ) { analyticsService.sendAnalyticsEvent( FPTIBatchData.Event( @@ -324,7 +325,8 @@ import Foundation linkType: linkType?.rawValue, merchantExperiment: merchantExperiment, paymentMethodsDisplayed: paymentMethodsDisplayed, - payPalContextID: payPalContextID + payPalContextID: payPalContextID, + sessionID: sessionID ) ) } diff --git a/Sources/BraintreeShopperInsights/BTShopperInsightsClient.swift b/Sources/BraintreeShopperInsights/BTShopperInsightsClient.swift index e5dc83a6c..60ce1cc3c 100644 --- a/Sources/BraintreeShopperInsights/BTShopperInsightsClient.swift +++ b/Sources/BraintreeShopperInsights/BTShopperInsightsClient.swift @@ -17,6 +17,9 @@ public class BTShopperInsightsClient { // MARK: - Private Properties private let apiClient: BTAPIClient + + /// This value should be the shopper session ID returned from your server SDK request + private let shopperSessionID: String? = "" /// Creates a `BTShopperInsightsClient` /// - Parameter apiClient: A `BTAPIClient` instance. @@ -127,7 +130,8 @@ public class BTShopperInsightsClient { private func notifySuccess(with result: BTShopperInsightsResult, for experiment: String?) -> BTShopperInsightsResult { apiClient.sendAnalyticsEvent( BTShopperInsightsAnalytics.recommendedPaymentsSucceeded, - merchantExperiment: experiment + merchantExperiment: experiment, + sessionID: shopperSessionID ) return result } @@ -136,7 +140,8 @@ public class BTShopperInsightsClient { apiClient.sendAnalyticsEvent( BTShopperInsightsAnalytics.recommendedPaymentsFailed, errorDescription: error.localizedDescription, - merchantExperiment: experiment + merchantExperiment: experiment, + sessionID: shopperSessionID ) return error } diff --git a/UnitTests/BraintreeCoreTests/Analytics/FPTIBatchData_Tests.swift b/UnitTests/BraintreeCoreTests/Analytics/FPTIBatchData_Tests.swift index 72b5f2b5d..d985810cd 100644 --- a/UnitTests/BraintreeCoreTests/Analytics/FPTIBatchData_Tests.swift +++ b/UnitTests/BraintreeCoreTests/Analytics/FPTIBatchData_Tests.swift @@ -28,6 +28,7 @@ final class FPTIBatchData_Tests: XCTestCase { linkType: LinkType.universal.rawValue, payPalContextID: "fake-order-id", requestStartTime: 456, + sessionID: "123456", startTime: 999888777666 ), FPTIBatchData.Event( @@ -42,16 +43,17 @@ final class FPTIBatchData_Tests: XCTestCase { linkType: nil, payPalContextID: "fake-order-id-2", requestStartTime: nil, + sessionID: nil, startTime: nil ) ] - + override func setUp() { super.setUp() sut = FPTIBatchData(metadata: batchMetadata, events: eventParams) } - + func testInit_formatsJSONBody() throws { let jsonBody = try sut.toDictionary() @@ -59,12 +61,12 @@ final class FPTIBatchData_Tests: XCTestCase { XCTFail("JSON body missing top level `events` key.") return } - + guard let eventParams = events[0]["event_params"] as? [[String: Any]] else { XCTFail("JSON body missing `event_params` key.") return } - + guard let batchParams = events[0]["batch_params"] as? [String: Any] else { XCTFail("JSON body missing `batch_params` key.") return @@ -121,6 +123,8 @@ final class FPTIBatchData_Tests: XCTestCase { XCTAssertNil(eventParams[1]["connect_start_time"]) XCTAssertEqual(eventParams[0]["request_start_time"] as? Int, 456) XCTAssertNil(eventParams[1]["request_start_time"]) + XCTAssertEqual(eventParams[0]["session_id"] as? String, "123456") + XCTAssertNil(eventParams[1]["session_id"]) } }