diff --git a/PayPal/src/main/java/com/braintreepayments/api/paypal/PayPalClient.kt b/PayPal/src/main/java/com/braintreepayments/api/paypal/PayPalClient.kt index ccdfbd46ad..3af75e73d8 100644 --- a/PayPal/src/main/java/com/braintreepayments/api/paypal/PayPalClient.kt +++ b/PayPal/src/main/java/com/braintreepayments/api/paypal/PayPalClient.kt @@ -5,10 +5,12 @@ import android.net.Uri import android.text.TextUtils import com.braintreepayments.api.BrowserSwitchOptions import com.braintreepayments.api.core.AnalyticsEventParams +import com.braintreepayments.api.core.AnalyticsParamRepository import com.braintreepayments.api.core.BraintreeClient import com.braintreepayments.api.core.BraintreeException import com.braintreepayments.api.core.BraintreeRequestCodes import com.braintreepayments.api.core.Configuration +import com.braintreepayments.api.core.ExperimentalBetaApi import com.braintreepayments.api.core.LinkType import com.braintreepayments.api.core.MerchantRepository import com.braintreepayments.api.core.UserCanceledException @@ -24,8 +26,8 @@ class PayPalClient internal constructor( private val braintreeClient: BraintreeClient, private val internalPayPalClient: PayPalInternalClient = PayPalInternalClient(braintreeClient), private val merchantRepository: MerchantRepository = MerchantRepository.instance, + private val analyticsParamRepository: AnalyticsParamRepository = AnalyticsParamRepository.instance ) { - /** * Used for linking events from the client to server side request * In the PayPal flow this will be either an EC token or a Billing Agreement token @@ -66,11 +68,17 @@ class PayPalClient internal constructor( * @param payPalRequest a [PayPalRequest] used to customize the request. * @param callback [PayPalPaymentAuthCallback] */ + @OptIn(ExperimentalBetaApi::class) fun createPaymentAuthRequest( context: Context, payPalRequest: PayPalRequest, callback: PayPalPaymentAuthCallback ) { + // The shopper insights server SDK integration + payPalRequest.shopperSessionId?.let { + analyticsParamRepository.setSessionId(it) + } + isVaultRequest = payPalRequest is PayPalVaultRequest braintreeClient.sendAnalyticsEvent(PayPalAnalytics.TOKENIZATION_STARTED, analyticsParams) diff --git a/PayPal/src/test/java/com/braintreepayments/api/paypal/PayPalClientUnitTest.java b/PayPal/src/test/java/com/braintreepayments/api/paypal/PayPalClientUnitTest.java index ea68b5b6ed..e264dd541b 100644 --- a/PayPal/src/test/java/com/braintreepayments/api/paypal/PayPalClientUnitTest.java +++ b/PayPal/src/test/java/com/braintreepayments/api/paypal/PayPalClientUnitTest.java @@ -16,6 +16,7 @@ import com.braintreepayments.api.BrowserSwitchFinalResult; import com.braintreepayments.api.BrowserSwitchOptions; import com.braintreepayments.api.core.AnalyticsEventParams; +import com.braintreepayments.api.core.AnalyticsParamRepository; import com.braintreepayments.api.core.BraintreeClient; import com.braintreepayments.api.core.BraintreeRequestCodes; import com.braintreepayments.api.core.Configuration; @@ -43,11 +44,13 @@ public class PayPalClientUnitTest { private PayPalPaymentAuthCallback paymentAuthCallback; private MerchantRepository merchantRepository; + private AnalyticsParamRepository analyticsParamRepository; @Before public void beforeEach() throws JSONException { + analyticsParamRepository = mock(AnalyticsParamRepository.class); activity = mock(FragmentActivity.class); - + merchantRepository = mock(MerchantRepository.class); payPalEnabledConfig = Configuration.fromJson(Fixtures.CONFIGURATION_WITH_LIVE_PAYPAL); payPalDisabledConfig = Configuration.fromJson(Fixtures.CONFIGURATION_WITH_DISABLED_PAYPAL); @@ -77,7 +80,7 @@ public void createPaymentAuthRequest_callsBackPayPalResponse_sendsStartedAnalyti BraintreeClient braintreeClient = new MockBraintreeClientBuilder().configuration(payPalEnabledConfig).build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, payPalVaultRequest, paymentAuthCallback); ArgumentCaptor captor = @@ -131,7 +134,7 @@ public void createPaymentAuthRequest_whenLaunchesBrowserSwitchAsNewTaskEnabled_s new MockBraintreeClientBuilder().configuration(payPalEnabledConfig) .launchesBrowserSwitchAsNewTask(true).build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, payPalVaultRequest, paymentAuthCallback); ArgumentCaptor captor = @@ -166,7 +169,7 @@ public void createPaymentAuthRequest_setsAppLinkReturnUrl() { BraintreeClient braintreeClient = new MockBraintreeClientBuilder().configuration(payPalEnabledConfig) .build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, payPalVaultRequest, paymentAuthCallback); ArgumentCaptor captor = @@ -186,7 +189,7 @@ public void createPaymentAuthRequest_whenPayPalNotEnabled_returnsError() { BraintreeClient braintreeClient = new MockBraintreeClientBuilder().configuration(payPalDisabledConfig).build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, new PayPalCheckoutRequest("1.00", true), paymentAuthCallback); @@ -215,7 +218,7 @@ public void createPaymentAuthRequest_whenCheckoutRequest_whenConfigError_forward .configurationError(authError) .build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, new PayPalCheckoutRequest("1.00", true), paymentAuthCallback); ArgumentCaptor captor = @@ -240,7 +243,7 @@ public void requestBillingAgreement_whenConfigError_forwardsErrorToListener() { .configurationError(authError) .build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, new PayPalVaultRequest(true), paymentAuthCallback); ArgumentCaptor captor = @@ -266,7 +269,7 @@ public void createPaymentAuthRequest_whenVaultRequest_sendsPayPalRequestViaInter PayPalVaultRequest payPalRequest = new PayPalVaultRequest(true); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, payPalRequest, paymentAuthCallback); verify(payPalInternalClient).sendRequest(same(activity), same(payPalRequest), @@ -282,7 +285,7 @@ public void createPaymentAuthRequest_whenCheckoutRequest_sendsPayPalRequestViaIn PayPalCheckoutRequest payPalRequest = new PayPalCheckoutRequest("1.00", true); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, payPalRequest, paymentAuthCallback); verify(payPalInternalClient).sendRequest(same(activity), same(payPalRequest), @@ -314,7 +317,7 @@ public void createPaymentAuthRequest_whenVaultRequest_sendsAppSwitchStartedEvent BraintreeClient braintreeClient = new MockBraintreeClientBuilder().configuration(payPalEnabledConfig).build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.createPaymentAuthRequest(activity, payPalVaultRequest, paymentAuthCallback); ArgumentCaptor captor = @@ -359,7 +362,7 @@ public void tokenize_withBillingAgreement_tokenizesResponseOnSuccess() throws JS PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -403,7 +406,7 @@ public void tokenize_withOneTimePayment_tokenizesResponseOnSuccess() throws JSON PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -448,7 +451,7 @@ public void tokenize_whenCancelUriReceived_notifiesCancellationAndSendsAnalytics PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -488,7 +491,7 @@ public void tokenize_whenPayPalInternalClientTokenizeResult_callsBackResult() PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -530,7 +533,7 @@ public void tokenize_whenPayPalInternalClientTokenizeResult_sendsAppSwitchSuccee PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -569,7 +572,7 @@ public void tokenize_whenPayPalNotEnabled_sendsAppSwitchFailedEvents() throws JS PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -601,7 +604,7 @@ public void tokenize_whenCancelUriReceived_sendsAppSwitchCanceledEvents() PayPalPaymentAuthResult.Success payPalPaymentAuthResult = new PayPalPaymentAuthResult.Success( browserSwitchResult); BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository); + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); sut.tokenize(payPalPaymentAuthResult, payPalTokenizeCallback); @@ -615,4 +618,60 @@ public void tokenize_whenCancelUriReceived_sendsAppSwitchCanceledEvents() verify(braintreeClient).sendAnalyticsEvent(PayPalAnalytics.BROWSER_LOGIN_CANCELED, params); verify(braintreeClient).sendAnalyticsEvent(PayPalAnalytics.APP_SWITCH_CANCELED, params); } + + @Test + public void test_vaultRequest_shopperSessionId_sets_repository() throws JSONException { + PayPalVaultRequest payPalVaultRequest = new PayPalVaultRequest(true); + + payPalVaultRequest.setShopperSessionId("test-shopper-id"); + + PayPalPaymentAuthRequestParams paymentAuthRequest = new PayPalPaymentAuthRequestParams( + payPalVaultRequest, + null, + "https://example.com/approval/url", + "sample-client-metadata-id", + null, + "https://example.com/success/url" + ); + + PayPalInternalClient payPalInternalClient = + new MockPayPalInternalClientBuilder().sendRequestSuccess(paymentAuthRequest) + .build(); + + BraintreeClient braintreeClient = + new MockBraintreeClientBuilder().configuration(payPalEnabledConfig).build(); + + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); + sut.createPaymentAuthRequest(activity, payPalVaultRequest, paymentAuthCallback); + + verify(analyticsParamRepository).setSessionId("test-shopper-id"); + } + + @Test + public void test_checkoutRequest_shopperSessionId_sets_repository() throws JSONException { + PayPalCheckoutRequest request = new PayPalCheckoutRequest("2.00", true); + + request.setShopperSessionId("test-shopper-id"); + + PayPalPaymentAuthRequestParams paymentAuthRequest = new PayPalPaymentAuthRequestParams( + request, + null, + "https://example.com/approval/url", + "sample-client-metadata-id", + null, + "https://example.com/success/url" + ); + + PayPalInternalClient payPalInternalClient = + new MockPayPalInternalClientBuilder().sendRequestSuccess(paymentAuthRequest) + .build(); + + BraintreeClient braintreeClient = + new MockBraintreeClientBuilder().configuration(payPalEnabledConfig).build(); + + PayPalClient sut = new PayPalClient(braintreeClient, payPalInternalClient, merchantRepository, analyticsParamRepository); + sut.createPaymentAuthRequest(activity, request, paymentAuthCallback); + + verify(analyticsParamRepository).setSessionId("test-shopper-id"); + } } \ No newline at end of file