Skip to content

Commit

Permalink
Nxo feature (#570)
Browse files Browse the repository at this point in the history
* Create PayPalNativeCheckout Module (#551)

* Create module

Signed-off-by: Matt Wylder <[email protected]>

* Add PayPalNativeCheckout to Rakefile

Signed-off-by: Steven Shropshire <[email protected]>

* Remove unecessary gitignore

Signed-off-by: Sarah Koop <[email protected]>

* Add empty files for folder structure

Signed-off-by: Matt Wylder <[email protected]>

Co-authored-by: Matt Wylder <[email protected]>
Co-authored-by: Steven Shropshire <[email protected]>

* Add PayPalNativeCheckoutNonce and PayPalNativeCheckoutRequest. (#553)

Signed-off-by: Sarah Koop <[email protected]>

Co-authored-by: Steven Shropshire <[email protected]>

* Add PayPalNativeFragment to Demo App  (#556)

* Added navigation to new fragment

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* Adding button to PayPalNativeFragment

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* added functionality to button

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* conforming names of PayPal Native Checkout classes and variables into conformance with iOS

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* conform naming of PayPal Native Checkout strings

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* renamed pay_pal to paypal

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* Reorganizing Native Checkout button on main fragment

Signed-off-by: Jax DesMarais-Leder <[email protected]>

* Checkout feature (#560)

* Add PayPalNative Module and support through the Braintree SDK

Co-authored-by: Tim Chow <[email protected]>
Co-authored-by: Kelay <[email protected]>

* -Removing returnUrl and adding onShippingChange callback

* -Updating native version

* -Fixing tests

* update changelog nesting

* -Reverting room update

* -Updating java

* -Removing shipping callback

* -Updating java version

* -Upgrading java 11 git actions

* -Reverting java 11 update

* -Updating to java 11

* -Testing

* -Testing

* -Updating native version

* -Fixing buttons

* -Adding returnUrl to account object
-Adding in java 11 to changelog

* -New tests for account

* -Adding source compatability

* -Renaming java version

Co-authored-by: Sarah Koop <[email protected]>
Co-authored-by: Matt Wylder <[email protected]>
Co-authored-by: Steven Shropshire <[email protected]>
Co-authored-by: sshropshire <[email protected]>
Co-authored-by: Matthew Wylder <[email protected]>
Co-authored-by: Tim Chow <[email protected]>
Co-authored-by: Kelay <[email protected]>
Co-authored-by: Jax DesMarais-Leder <[email protected]>
  • Loading branch information
9 people authored Jul 19, 2022
1 parent 73ebe94 commit bf990e0
Show file tree
Hide file tree
Showing 63 changed files with 3,944 additions and 24 deletions.
10 changes: 5 additions & 5 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Setup Java 8
description: 'Sets up Java 8'
name: Setup Java 11
description: 'Sets up Java 11'
runs:
using: "composite"
steps:
- name: Set up Java 8
uses: actions/setup-java@v2
- name: Set up Java 11
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'zulu'
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Set up Java 8
uses: actions/setup-java@v2
uses: actions/checkout@v3
- name: Set up Java 11
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'zulu'
- name: Unit Tests
run: ./gradlew --stacktrace testRelease
5 changes: 5 additions & 0 deletions AmericanExpress/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ android {
}
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}

dependencies {
Expand Down
5 changes: 5 additions & 0 deletions BraintreeCore/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ android {
textReport true
textOutput 'stdout'
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}


Expand Down
5 changes: 5 additions & 0 deletions BraintreeDataCollector/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ android {
}
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}

dependencies {
Expand Down
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@

## unreleased

* Adds `invalidateClientToken` method to `BraintreeClient`, which invalidates the cached client
token authorization provided by the `ClientTokenProvider`
* Add `isExplicitCancelation` parameter to `UserCanceledException`
* Trim tokenization key and client token before parsing

* PayPalNativeCheckout
* Requirement - Needs to be built on Java 11
* Adding in [PayPalNativeCheckout] module to use the native checkout for PayPal
* Adds `PayPalNativeCheckoutClient` that handles launching the native checkout session, the session
start parameters are similar to that of `PaypalClient` with the main difference being it doesn't
use the browserSwitch to checkout on web but instead consumes the native checkout sdk. This provides
a much more native feel to checking out with PayPal.
* Adds `PayPalNativeCheckoutAccount` to represent tokenizing a PayPal request
* Adds `PayPalNativeCheckoutAccountNonce` that represents the value returned from the web
* Adds `PayPalNativeCheckoutFragment` that shows how to launch the native checkout sdk
* Adds `PayPalNativeCheckoutCreditFinancing` to represent the PayPal credit financing response
* Adds `PayPalNativeCheckoutCreditFinancingAmount` to represent the PayPal finance amount
* Adds `PayPalNativeCheckoutLineItem` to represent a line item for checkout flows
* Adds `PayPalNativeCheckoutListener` to receive result notifications
* Adds `PayPalNativeCheckoutPaymentIntent` to represent the payment intent for an order
* Adds `PayPalNativeCheckoutPaymentResource` to represent the data returned from the internal checkout client
to fetch the return url
* Adds `PayPalNativeCheckoutRequest` to represent all items needed to begin the native checkout flow
* Adds `PayPalNativeCheckoutVaultRequest` to represent all items needed to begin the native vault flow
* Adds `PayPalNativeRequest` to represent the base items needed for checkout and vault requests
* Adds `PayPalNativeCheckoutResultCallback` to listen to the result returned from the checkout response

* DataCollector
* Reference Kount library only when needed to prevent JVM from loading it when it isn't being used by a merchant.
* SEPADirectDebit
Expand Down
5 changes: 5 additions & 0 deletions Card/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ android {
}
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}

dependencies {
Expand Down
1 change: 1 addition & 0 deletions Demo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ dependencies {
implementation project(':GooglePay')
implementation project(':LocalPayment')
implementation project(':PayPal')
implementation project(':PayPalNativeCheckout')
implementation project(':SamsungPay')
implementation project(':SEPADirectDebit')
implementation project(':ThreeDSecure')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
Button preferredPaymentMethodsButton = view.findViewById(R.id.preferred_payment_methods);
Button samsungButton = view.findViewById(R.id.samsung_pay);
Button sepaDirectDebitButton = view.findViewById(R.id.sepa_debit);
Button payPalNativeCheckoutButton = view.findViewById(R.id.paypal_native_checkout);

cardsButton.setOnClickListener(this::launchCards);
payPalButton.setOnClickListener(this::launchPayPal);
Expand All @@ -46,6 +47,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
venmoButton.setOnClickListener(this::launchVenmo);
preferredPaymentMethodsButton.setOnClickListener(this::launchPreferredPaymentMethods);
samsungButton.setOnClickListener(this::launchSamsungPay);
payPalNativeCheckoutButton.setOnClickListener(this::launchPayPalNativeCheckout);
sepaDirectDebitButton.setOnClickListener(this::launchSEPADirectDebit);

return view;
Expand Down Expand Up @@ -123,6 +125,11 @@ public void launchSamsungPay(View v) {
Navigation.findNavController(v).navigate(action);
}

public void launchPayPalNativeCheckout(View v) {
NavDirections action = MainFragmentDirections.actionMainFragmentToPayPalNativeCheckoutFragment();
Navigation.findNavController(v).navigate(action);
}

public void launchSEPADirectDebit(View v) {
NavDirections action = MainFragmentDirections.actionMainFragmentToSepaDirectDebitFragment();
Navigation.findNavController(v).navigate(action);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.braintreepayments.demo;

import static com.braintreepayments.demo.PayPalNativeCheckoutRequestFactory.createPayPalCheckoutRequest;
import static com.braintreepayments.demo.PayPalNativeCheckoutRequestFactory.createPayPalVaultRequest;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.navigation.fragment.NavHostFragment;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.braintreepayments.api.BraintreeClient;
import com.braintreepayments.api.DataCollector;
import com.braintreepayments.api.PayPalNativeCheckoutAccountNonce;
import com.braintreepayments.api.PayPalNativeCheckoutListener;
import com.braintreepayments.api.PayPalNativeCheckoutClient;
import com.braintreepayments.api.PaymentMethodNonce;

public class PayPalNativeCheckoutFragment extends BaseFragment implements PayPalNativeCheckoutListener {

private final String TAG = PayPalNativeCheckoutFragment.class.getName();
private String deviceData;
private BraintreeClient braintreeClient;
private PayPalNativeCheckoutClient payPalClient;
private DataCollector dataCollector;

public Button launchPayPalNativeCheckoutButton;

public PayPalNativeCheckoutFragment() {
}

@Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState
) {
View view = inflater.inflate(R.layout.fragment_paypal_native_checkout, container, false);

launchPayPalNativeCheckoutButton = view.findViewById(R.id.paypal_native_checkout_launch);
launchPayPalNativeCheckoutButton.setOnClickListener(v -> launchPayPalNativeCheckout(false));
braintreeClient = getBraintreeClient();
payPalClient = new PayPalNativeCheckoutClient(this, braintreeClient);
payPalClient.setListener(this);
return view;
}

private void launchPayPalNativeCheckout(boolean isBillingAgreement) {
FragmentActivity activity = getActivity();
activity.setProgressBarIndeterminateVisibility(true);

dataCollector = new DataCollector(braintreeClient);

braintreeClient.getConfiguration((configuration, configError) -> {
if (Settings.shouldCollectDeviceData(requireActivity())) {
dataCollector.collectDeviceData(requireActivity(), (deviceDataResult, error) -> {
if (deviceDataResult != null) {
deviceData = deviceDataResult;
}
try {
payPalClient.tokenizePayPalAccount(activity, createPayPalCheckoutRequest(activity, "1.00"));
} catch (Exception e) {
Log.i(TAG, "Unsupported type");
}
});
} else {
try {
payPalClient.tokenizePayPalAccount(activity, createPayPalCheckoutRequest(activity, "1.00"));
} catch (Exception e) {
Log.i(TAG, "Unsupported type");
}

}
});
}

private void handlePayPalResult(PaymentMethodNonce paymentMethodNonce) {
if (paymentMethodNonce != null) {
super.onPaymentMethodNonceCreated(paymentMethodNonce);

PayPalNativeCheckoutFragmentDirections.ActionPayPalNativeCheckoutFragmentToDisplayNonceFragment action =
PayPalNativeCheckoutFragmentDirections.actionPayPalNativeCheckoutFragmentToDisplayNonceFragment(paymentMethodNonce);
action.setDeviceData(deviceData);

NavHostFragment.findNavController(this).navigate(action);
}
}

@Override
public void onPayPalSuccess(@NonNull PayPalNativeCheckoutAccountNonce payPalAccountNonce) {
handlePayPalResult(payPalAccountNonce);
}

@Override
public void onPayPalFailure(@NonNull Exception error) {
handleError(error);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.braintreepayments.demo;

import android.content.Context;

import com.braintreepayments.api.PayPalNativeCheckoutRequest;
import com.braintreepayments.api.PayPalNativeCheckoutPaymentIntent;
import com.braintreepayments.api.PayPalNativeRequest;
import com.braintreepayments.api.PayPalNativeCheckoutVaultRequest;
import com.braintreepayments.api.PostalAddress;

public class PayPalNativeCheckoutRequestFactory {

public static PayPalNativeCheckoutVaultRequest createPayPalVaultRequest(Context context) {
PayPalNativeCheckoutVaultRequest request = new PayPalNativeCheckoutVaultRequest();

request.setDisplayName(Settings.getPayPalDisplayName(context));

if (Settings.isPayPalCreditOffered(context)) {
request.setShouldOfferCredit(true);
}

if (Settings.usePayPalAddressOverride(context)) {
PostalAddress postalAddress = new PostalAddress();
postalAddress.setRecipientName("Brian Tree");
postalAddress.setStreetAddress("123 Fake Street");
postalAddress.setExtendedAddress("Floor A");
postalAddress.setLocality("San Francisco");
postalAddress.setRegion("CA");
postalAddress.setCountryCodeAlpha2("US");

request.setShippingAddressOverride(postalAddress);
}
request.setReturnUrl("com.braintreepayments.demo://paypalpay");
return request;
}

public static PayPalNativeCheckoutRequest createPayPalCheckoutRequest(Context context, String amount) {
PayPalNativeCheckoutRequest request = new PayPalNativeCheckoutRequest(amount);

request.setDisplayName(Settings.getPayPalDisplayName(context));

String intentType = Settings.getPayPalIntentType(context);
if (intentType.equals(context.getString(R.string.paypal_intent_authorize))) {
request.setIntent(PayPalNativeCheckoutPaymentIntent.AUTHORIZE);
} else if (intentType.equals(context.getString(R.string.paypal_intent_order))) {
request.setIntent(PayPalNativeCheckoutPaymentIntent.ORDER);
} else if (intentType.equals(context.getString(R.string.paypal_intent_sale))) {
request.setIntent(PayPalNativeCheckoutPaymentIntent.SALE);
}

if (Settings.isPayPalUseractionCommitEnabled(context)) {
request.setUserAction(PayPalNativeCheckoutRequest.USER_ACTION_COMMIT);
}

if (Settings.usePayPalAddressOverride(context)) {
PostalAddress shippingAddress = new PostalAddress();
shippingAddress.setRecipientName("Brian Tree");
shippingAddress.setStreetAddress("123 Fake Street");
shippingAddress.setExtendedAddress("Floor A");
shippingAddress.setLocality("San Francisco");
shippingAddress.setRegion("CA");
shippingAddress.setCountryCodeAlpha2("US");

request.setShippingAddressOverride(shippingAddress);
}
request.setReturnUrl("com.braintreepayments.demo://paypalpay");
return request;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.braintreepayments.demo;

import com.braintreepayments.api.BinData;
import com.braintreepayments.api.PayPalAccountNonce;
import com.braintreepayments.api.PaymentMethodNonce;
import com.braintreepayments.api.CardNonce;
import com.braintreepayments.api.GooglePayCardNonce;
import com.braintreepayments.api.LocalPaymentNonce;
import com.braintreepayments.api.PayPalAccountNonce;
import com.braintreepayments.api.PayPalNativeCheckoutAccountNonce;
import com.braintreepayments.api.PostalAddress;
import com.braintreepayments.api.VenmoAccountNonce;
import com.braintreepayments.api.VisaCheckoutAddress;
Expand All @@ -21,7 +22,9 @@ public static String convertToString(PaymentMethodNonce nonce) {
return convertCardNonceToString((CardNonce) nonce);
} else if (nonce instanceof PayPalAccountNonce) {
return convertPayPalNonceToString((PayPalAccountNonce) nonce);
} else if (nonce instanceof GooglePayCardNonce) {
} else if (nonce instanceof PayPalNativeCheckoutAccountNonce) {
return convertPayPalNativeCheckoutNonceToString((PayPalNativeCheckoutAccountNonce) nonce);
} else if (nonce instanceof GooglePayCardNonce) {
return convertGooglePayNonceToString((GooglePayCardNonce) nonce);
} else if (nonce instanceof VisaCheckoutNonce) {
return convertVisaCheckoutNonceToString((VisaCheckoutNonce) nonce);
Expand Down Expand Up @@ -53,6 +56,17 @@ private static String convertPayPalNonceToString(PayPalAccountNonce nonce) {
"Shipping Address: " + formatPayPalAddress(nonce.getShippingAddress());
}

private static String convertPayPalNativeCheckoutNonceToString(PayPalNativeCheckoutAccountNonce nonce) {
return "First Name: " + nonce.getFirstName() + "\n" +
"Last Name: " + nonce.getLastName() + "\n" +
"Email: " + nonce.getEmail() + "\n" +
"Phone: " + nonce.getPhone() + "\n" +
"Payer ID: " + nonce.getPayerId() + "\n" +
"Client Metadata ID: " + nonce.getClientMetadataId() + "\n" +
"Billing Address: " + formatPayPalAddress(nonce.getBillingAddress()) + "\n" +
"Shipping Address: " + formatPayPalAddress(nonce.getShippingAddress());
}

private static String convertGooglePayNonceToString(GooglePayCardNonce nonce) {
return "Underlying Card Last Two: " + nonce.getLastTwo() + "\n" +
"Email: " + nonce.getEmail() + "\n" +
Expand Down
13 changes: 5 additions & 8 deletions Demo/src/main/res/layout/fragment_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,25 +105,22 @@
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/sepa_debit"
android:id="@+id/paypal_native_checkout"
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/sepa_direct_debit_button"
android:text="@string/paypal_native_checkout"
android:textSize="12sp" />

<Button
android:id="@+id/future_feature"
android:id="@+id/sepa_debit"
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text=""
android:textSize="12sp"
tools:ignore="SpeakableTextPresentCheck" />
android:text="@string/sepa_direct_debit_button"
android:textSize="12sp" />

</TableRow>
</TableLayout>
Loading

0 comments on commit bf990e0

Please sign in to comment.