Skip to content

Commit

Permalink
Shopper insights rp1 feature include session (#1235)
Browse files Browse the repository at this point in the history
* Add shopper insights session ID to paypalRequest

* Update factory for paypal request

* remove extra setting of email address

* Remove optional null and check for null in PayPalRequestFactory

* Use String type and fix check for null to prevent run time crashes

* Remove DEMO UI updates

* Update comment for shopperSessionId

* Add experimentalAPI for shopper session Id

* Remove unused shopperInsightsSessionIdNullSwitch

* Check for null and empty string

* Update to use putOpt method for shopperId

* Update changelog

* Check for null and empty strings for request properties.

* Update unit tests

* Update test

* Update unit tests

* Update changelog
  • Loading branch information
warmkesselj authored Dec 9, 2024
1 parent fb4455d commit 8427bcd
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* ShopperInsights (BETA)
* Add `isPayPalAppInstalled` and `isVenmoAppInstalled` methods
* Add `shopperSessionId` parameter to `ShopperInsightsClient`
* BraintreePayPal
* Add `shopperSessionId` to `PayPalCheckoutRequest` and `PayPalVaultRequest`

## 5.2.0 (2024-10-30)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,17 @@ private void launchPayPal(
activity,
buyerEmailAddress,
buyerPhoneCountryCode,
buyerPhoneNationalNumber
buyerPhoneNationalNumber,
null
);
} else {
payPalRequest = createPayPalCheckoutRequest(
activity,
amount,
buyerEmailAddress,
buyerPhoneCountryCode,
buyerPhoneNationalNumber
buyerPhoneNationalNumber,
null
);
}
payPalClient.createPaymentAuthRequest(requireContext(), payPalRequest,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,27 @@ public static PayPalVaultRequest createPayPalVaultRequest(
Context context,
String buyerEmailAddress,
String buyerPhoneCountryCode,
String buyerPhoneNationalNumber
String buyerPhoneNationalNumber,
String shopperInsightsSessionId
) {

PayPalVaultRequest request = new PayPalVaultRequest(true);

if (!buyerEmailAddress.isEmpty()) {
if (buyerEmailAddress != null && !buyerEmailAddress.isEmpty()) {
request.setUserAuthenticationEmail(buyerEmailAddress);
}

if (!buyerPhoneCountryCode.isEmpty() && !buyerPhoneNationalNumber.isEmpty()) {
request.setUserPhoneNumber(new PayPalPhoneNumber(buyerPhoneCountryCode, buyerPhoneNationalNumber));
if ((buyerPhoneCountryCode != null && !buyerPhoneCountryCode.isEmpty())
&& (buyerPhoneNationalNumber != null && !buyerPhoneNationalNumber.isEmpty())) {

request.setUserPhoneNumber(new PayPalPhoneNumber(
buyerPhoneCountryCode,
buyerPhoneNationalNumber)
);
}

if (shopperInsightsSessionId != null && !shopperInsightsSessionId.isEmpty()) {
request.setShopperSessionId(shopperInsightsSessionId);
}

if (Settings.isPayPalAppSwithEnabled(context)) {
Expand Down Expand Up @@ -111,16 +121,25 @@ public static PayPalCheckoutRequest createPayPalCheckoutRequest(
String amount,
String buyerEmailAddress,
String buyerPhoneCountryCode,
String buyerPhoneNationalNumber
String buyerPhoneNationalNumber,
String shopperInsightsSessionId
) {
PayPalCheckoutRequest request = new PayPalCheckoutRequest(amount, true);

if (!buyerEmailAddress.isEmpty()) {
if (buyerEmailAddress != null && !buyerEmailAddress.isEmpty()) {
request.setUserAuthenticationEmail(buyerEmailAddress);
}

if (!buyerPhoneCountryCode.isEmpty() && !buyerPhoneNationalNumber.isEmpty()) {
request.setUserPhoneNumber(new PayPalPhoneNumber(buyerPhoneCountryCode, buyerPhoneNationalNumber));
if ((buyerPhoneCountryCode != null && !buyerPhoneCountryCode.isEmpty())
&& (buyerPhoneNationalNumber != null && !buyerPhoneNationalNumber.isEmpty())) {
request.setUserPhoneNumber(new PayPalPhoneNumber(
buyerPhoneCountryCode,
buyerPhoneNationalNumber)
);
}

if (shopperInsightsSessionId != null && !shopperInsightsSessionId.isEmpty()) {
request.setShopperSessionId(shopperInsightsSessionId);
}

request.setDisplayName(Settings.getPayPalDisplayName(context));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ class ShopperInsightsFragment : BaseFragment() {
private lateinit var venmoStartedPendingRequest: VenmoPendingRequest.Started
private lateinit var paypalStartedPendingRequest: PayPalPendingRequest.Started

private var shopperSessionId: String = "test-shopper-session-id"

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
shopperInsightsClient = ShopperInsightsClient(requireContext(), authStringArg, "test-shopper-session-id")
shopperInsightsClient = ShopperInsightsClient(requireContext(), authStringArg, shopperSessionId)

venmoClient = VenmoClient(requireContext(), super.getAuthStringArg(), null)
payPalClient = PayPalClient(
Expand Down Expand Up @@ -229,7 +231,9 @@ class ShopperInsightsFragment : BaseFragment() {
activity,
emailInput.editText?.text.toString(),
countryCodeInput.editText?.text.toString(),
nationalNumberInput.editText?.text.toString()
nationalNumberInput.editText?.text.toString(),
shopperSessionId

)
) { authRequest ->
when (authRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.text.TextUtils
import com.braintreepayments.api.core.Authorization
import com.braintreepayments.api.core.ClientToken
import com.braintreepayments.api.core.Configuration
import com.braintreepayments.api.core.ExperimentalBetaApi
import com.braintreepayments.api.core.PostalAddress
import com.braintreepayments.api.core.PostalAddressParser
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -91,6 +92,7 @@ class PayPalCheckoutRequest @JvmOverloads constructor(
lineItems = lineItems
) {

@OptIn(ExperimentalBetaApi::class)
@Throws(JSONException::class)
@Suppress("LongMethod", "CyclomaticComplexMethod")
override fun createRequestBody(
Expand Down Expand Up @@ -126,6 +128,8 @@ class PayPalCheckoutRequest @JvmOverloads constructor(

userPhoneNumber?.let { parameters.put(PHONE_NUMBER_KEY, it.toJson()) }

parameters.putOpt(SHOPPER_SESSION_ID, shopperSessionId)

if (currencyCode == null) {
currencyCode = configuration?.payPalCurrencyIsoCode
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Parcelable
import androidx.annotation.RestrictTo
import com.braintreepayments.api.core.Authorization
import com.braintreepayments.api.core.Configuration
import com.braintreepayments.api.core.ExperimentalBetaApi
import com.braintreepayments.api.core.PostalAddress
import org.json.JSONException

Expand Down Expand Up @@ -72,6 +73,8 @@ import org.json.JSONException
* where the user has a PayPal Account with the same email.
* @property userPhoneNumber User phone number used to initiate a quicker authentication flow in
* cases where the user has a PayPal Account with the phone number.
* @property shopperSessionId the shopper session ID returned from your shopper insights server SDK
* integration
* @property lineItems The line items for this transaction. It can include up to 249 line items.
*/
abstract class PayPalRequest internal constructor(
Expand All @@ -87,6 +90,9 @@ abstract class PayPalRequest internal constructor(
open var riskCorrelationId: String? = null,
open var userAuthenticationEmail: String? = null,
open var userPhoneNumber: PayPalPhoneNumber? = null,

@property:ExperimentalBetaApi
open var shopperSessionId: String? = null,
open var lineItems: List<PayPalLineItem> = emptyList()
) : Parcelable {

Expand Down Expand Up @@ -132,5 +138,6 @@ abstract class PayPalRequest internal constructor(
internal const val PLAN_TYPE_KEY: String = "plan_type"
internal const val PLAN_METADATA_KEY: String = "plan_metadata"
internal const val PHONE_NUMBER_KEY: String = "phone_number"
internal const val SHOPPER_SESSION_ID: String = "shopper_session_id"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.text.TextUtils
import com.braintreepayments.api.core.Authorization
import com.braintreepayments.api.core.ClientToken
import com.braintreepayments.api.core.Configuration
import com.braintreepayments.api.core.ExperimentalBetaApi
import com.braintreepayments.api.core.PostalAddress
import com.braintreepayments.api.core.PostalAddressParser
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -65,6 +66,7 @@ class PayPalVaultRequest
lineItems = lineItems
) {

@OptIn(ExperimentalBetaApi::class)
@Throws(JSONException::class)
@Suppress("LongMethod")
override fun createRequestBody(
Expand Down Expand Up @@ -92,6 +94,8 @@ class PayPalVaultRequest

parameters.putOpt(PAYER_EMAIL_KEY, userAuthenticationEmail)

parameters.putOpt(SHOPPER_SESSION_ID, shopperSessionId)

userPhoneNumber?.let { parameters.put(PHONE_NUMBER_KEY, it.toJson()) }

if (enablePayPalAppSwitch && !appLink.isNullOrEmpty() && !userAuthenticationEmail.isNullOrEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.braintreepayments.api.paypal;

import android.os.Build;
import android.os.Parcel;

import com.braintreepayments.api.core.Authorization;
Expand Down Expand Up @@ -27,6 +28,7 @@ public class PayPalCheckoutRequestUnitTest {
public void newPayPalCheckoutRequest_setsDefaultValues() {
PayPalCheckoutRequest request = new PayPalCheckoutRequest("1.00", false);

assertNull(request.getShopperSessionId());
assertNotNull(request.getAmount());
assertNull(request.getCurrencyCode());
assertNull(request.getLocaleCode());
Expand All @@ -44,6 +46,7 @@ public void newPayPalCheckoutRequest_setsDefaultValues() {
public void setsValuesCorrectly() {
PostalAddress postalAddress = new PostalAddress();
PayPalCheckoutRequest request = new PayPalCheckoutRequest("1.00", true);
request.setShopperSessionId("shopper-insights-id");
request.setCurrencyCode("USD");
request.setShouldOfferPayLater(true);
request.setIntent(PayPalPaymentIntent.SALE);
Expand All @@ -58,6 +61,7 @@ public void setsValuesCorrectly() {
request.setRiskCorrelationId("123-correlation");
request.setLandingPageType(PayPalLandingPageType.LANDING_PAGE_TYPE_LOGIN);

assertEquals("shopper-insights-id", request.getShopperSessionId());
assertEquals("1.00", request.getAmount());
assertEquals("USD", request.getCurrencyCode());
assertEquals("US", request.getLocaleCode());
Expand Down Expand Up @@ -156,6 +160,21 @@ public void createRequestBody_does_not_set_userAuthenticationEmail_when_email_is
assertFalse(requestBody.contains("\"payer_email\":" + "\"" + payerEmail + "\""));
}

@Test
public void createRequestBody_sets_shopper_insights_session_id() throws JSONException {
PayPalCheckoutRequest request = new PayPalCheckoutRequest("1.00", true);
request.setShopperSessionId("shopper-insights-id");
String requestBody = request.createRequestBody(
mock(Configuration.class),
mock(Authorization.class),
"success_url",
"cancel_url",
"universal_url"
);

assertTrue(requestBody.contains("\"shopper_session_id\":" + "\"shopper-insights-id\""));
}

@Test
public void createRequestBody_sets_userPhoneNumber_when_not_null() throws JSONException {
PayPalCheckoutRequest request = new PayPalCheckoutRequest("1.00", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.braintreepayments.api.testutils.Fixtures;

import org.json.JSONException;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
Expand All @@ -32,6 +33,7 @@ public class PayPalVaultRequestUnitTest {
public void newPayPalVaultRequest_setsDefaultValues() {
PayPalVaultRequest request = new PayPalVaultRequest(false);

assertNull(request.getShopperSessionId());
assertNull(request.getLocaleCode());
assertFalse(request.isShippingAddressRequired());
assertNull(request.getShippingAddressOverride());
Expand All @@ -46,6 +48,7 @@ public void newPayPalVaultRequest_setsDefaultValues() {
public void setsValuesCorrectly() {
PostalAddress postalAddress = new PostalAddress();
PayPalVaultRequest request = new PayPalVaultRequest(true);
request.setShopperSessionId("shopper-insights-id");
request.setLocaleCode("US");
request.setBillingAgreementDescription("Billing Agreement Description");
request.setShippingAddressRequired(true);
Expand Down Expand Up @@ -75,6 +78,7 @@ public void setsValuesCorrectly() {
request.setRecurringBillingDetails(billingDetails);
request.setRecurringBillingPlanType(PayPalRecurringBillingPlanType.RECURRING);

assertEquals("shopper-insights-id", request.getShopperSessionId());
assertEquals("US", request.getLocaleCode());
assertEquals("Billing Agreement Description", request.getBillingAgreementDescription());
assertTrue(request.isShippingAddressRequired());
Expand Down Expand Up @@ -212,11 +216,11 @@ public void createRequestBody_sets_userAuthenticationEmail_when_not_null() throw
assertTrue(requestBody.contains("\"payer_email\":" + "\"" + payerEmail + "\""));
}

@Test
public void createRequestBody_sets_enablePayPalSwitch_and_userAuthenticationEmail_not_null() throws JSONException {
String versionSDK = String.valueOf(Build.VERSION.SDK_INT);
String payerEmail = "[email protected]";
PayPalVaultRequest request = new PayPalVaultRequest(true);

request.setEnablePayPalAppSwitch(true);
request.setUserAuthenticationEmail(payerEmail);
String requestBody = request.createRequestBody(
Expand All @@ -233,6 +237,21 @@ public void createRequestBody_sets_enablePayPalSwitch_and_userAuthenticationEmai
assertTrue(requestBody.contains("\"merchant_app_return_url\":" + "\"universal_url\""));
}

@Test
public void createRequestBody_sets_shopper_insights_session_id() throws JSONException {
PayPalVaultRequest request = new PayPalVaultRequest(true);
request.setShopperSessionId("shopper-insights-id");
String requestBody = request.createRequestBody(
mock(Configuration.class),
mock(Authorization.class),
"success_url",
"cancel_url",
"universal_url"
);

assertTrue(requestBody.contains("\"shopper_session_id\":" + "\"shopper-insights-id\""));
}

@Test
public void createRequestBody_correctlyFormatsJSON() throws JSONException {
PayPalVaultRequest request = new PayPalVaultRequest(true);
Expand Down

0 comments on commit 8427bcd

Please sign in to comment.