Skip to content

Commit

Permalink
Venmo Universal/App Links (#911)
Browse files Browse the repository at this point in the history
* Add setFallbackToWeb() to VenmoRequest
    * If set to true customers will fallback to a web based Venmo flow if the Venmo app is not installed
    * This method uses App Links instead of Deep Links
* Add VenmoClient#parseBrowserSwitchResult(Context, Intent) method
* Add VenmoClient#clearActiveBrowserSwitchRequests(Context) method
* Add VenmoClient#onBrowserSwitchResult(BrowserSwitchResult, VenmoOnActivityResultCallback) method
* This feature has been added to the Demo app, select "Venmo Fallback to Web" in the Settings menu to test this flow
* Add unit tests

Co-authored-by: Tim Chow <tichow@paypal.com>
Co-authored-by: Justin Warmkessel <jwarmkessel@gmail.com>
Co-authored-by: Sarah Koop <skoop@paypal.com>
  • Loading branch information
4 people authored Mar 1, 2024
1 parent 332442e commit ab5f704
Show file tree
Hide file tree
Showing 12 changed files with 747 additions and 22 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

* Venmo
* Add `setIsFinalAmount()` to `VenmoRequest`
* Add `setFallbackToWeb()` to `VenmoRequest`
* If set to `true` customers will fallback to a web based Venmo flow if the Venmo app is not installed
* This method uses App Links instead of Deep Links
* Add `VenmoClient#parseBrowserSwitchResult(Context, Intent)` method
* Add `VenmoClient#clearActiveBrowserSwitchRequests(Context)` method
* Add `VenmoClient#onBrowserSwitchResult(BrowserSwitchResult, VenmoOnActivityResultCallback)` method
* ThreeDSecure
* Call cleanup method to resolve `Cardinal.getInstance` memory leak

Expand Down
4 changes: 4 additions & 0 deletions Demo/src/main/java/com/braintreepayments/demo/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ public static boolean vaultVenmo(Context context) {
return getPreferences(context).getBoolean("vault_venmo", true);
}

public static boolean venmoFallbackToWeb(Context context) {
return getPreferences(context).getBoolean("venmo_fallback_to_web", false);
}

public static boolean isAmexRewardsBalanceEnabled(Context context) {
return getPreferences(context).getBoolean("amex_rewards_balance", false);
}
Expand Down
72 changes: 53 additions & 19 deletions Demo/src/main/java/com/braintreepayments/demo/VenmoFragment.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.braintreepayments.demo;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
Expand All @@ -14,6 +15,7 @@
import androidx.navigation.fragment.NavHostFragment;

import com.braintreepayments.api.BraintreeClient;
import com.braintreepayments.api.BrowserSwitchResult;
import com.braintreepayments.api.VenmoAccountNonce;
import com.braintreepayments.api.VenmoClient;
import com.braintreepayments.api.VenmoLineItem;
Expand All @@ -28,13 +30,16 @@ public class VenmoFragment extends BaseFragment implements VenmoListener {
private VenmoClient venmoClient;
private BraintreeClient braintreeClient;

private boolean useManualBrowserSwitch;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_venmo, container, false);
venmoButton = view.findViewById(R.id.venmo_button);
venmoButton.setOnClickListener(this::launchVenmo);

useManualBrowserSwitch = Settings.isManualBrowserSwitchingEnabled(requireActivity());
braintreeClient = getBraintreeClient();
venmoClient = new VenmoClient(this, braintreeClient);
venmoClient.setListener(this);
Expand All @@ -46,7 +51,7 @@ private void handleVenmoResult(VenmoAccountNonce venmoAccountNonce) {
super.onPaymentMethodNonceCreated(venmoAccountNonce);

NavDirections action =
VenmoFragmentDirections.actionVenmoFragmentToDisplayNonceFragment(venmoAccountNonce);
VenmoFragmentDirections.actionVenmoFragmentToDisplayNonceFragment(venmoAccountNonce);
NavHostFragment.findNavController(this).navigate(action);
}

Expand All @@ -57,35 +62,64 @@ public void launchVenmo(View v) {

boolean shouldVault =
Settings.vaultVenmo(activity) && !TextUtils.isEmpty(Settings.getCustomerId(activity));
boolean fallbackToWeb = Settings.venmoFallbackToWeb(activity);

int venmoPaymentMethodUsage = shouldVault ?
VenmoPaymentMethodUsage.MULTI_USE : VenmoPaymentMethodUsage.SINGLE_USE;
VenmoRequest venmoRequest = new VenmoRequest(venmoPaymentMethodUsage);
venmoRequest.setProfileId(null);
venmoRequest.setShouldVault(shouldVault);
venmoRequest.setCollectCustomerBillingAddress(true);
venmoRequest.setCollectCustomerShippingAddress(true);
venmoRequest.setTotalAmount("20");
venmoRequest.setSubTotalAmount("18");
venmoRequest.setTaxAmount("1");
venmoRequest.setShippingAmount("1");
ArrayList<VenmoLineItem> lineItems = new ArrayList<>();
lineItems.add(new VenmoLineItem(VenmoLineItem.KIND_CREDIT, "Some Item", 1, "2"));
lineItems.add(new VenmoLineItem(VenmoLineItem.KIND_DEBIT, "Two Items", 2, "10"));
venmoRequest.setLineItems(lineItems);

braintreeClient.getConfiguration((configuration, error) -> {
if (venmoClient.isVenmoAppSwitchAvailable(activity)) {
VenmoRequest venmoRequest = new VenmoRequest(venmoPaymentMethodUsage);
venmoRequest.setProfileId(null);
venmoRequest.setShouldVault(shouldVault);
venmoRequest.setCollectCustomerBillingAddress(true);
venmoRequest.setCollectCustomerShippingAddress(true);
venmoRequest.setTotalAmount("20");
venmoRequest.setSubTotalAmount("18");
venmoRequest.setTaxAmount("1");
venmoRequest.setShippingAmount("1");
ArrayList<VenmoLineItem> lineItems = new ArrayList<>();
lineItems.add(new VenmoLineItem(VenmoLineItem.KIND_CREDIT, "Some Item", 1, "2"));
lineItems.add(new VenmoLineItem(VenmoLineItem.KIND_DEBIT, "Two Items", 2, "10"));
venmoRequest.setLineItems(lineItems);

if (fallbackToWeb) {
venmoRequest.setFallbackToWeb(true);
venmoClient.tokenizeVenmoAccount(activity, venmoRequest);
} else if (configuration.isVenmoEnabled()) {
showDialog("Please install the Venmo app first.");
} else {
showDialog("Venmo is not enabled for the current merchant.");
if (venmoClient.isVenmoAppSwitchAvailable(activity)) {
venmoClient.tokenizeVenmoAccount(activity, venmoRequest);
} else if (configuration.isVenmoEnabled()) {
showDialog("Please install the Venmo app first.");
} else {
showDialog("Venmo is not enabled for the current merchant.");
}
}
});
}

@Override
public void onResume() {
super.onResume();
if (useManualBrowserSwitch) {
Activity activity = requireActivity();
BrowserSwitchResult browserSwitchResult =
venmoClient.parseBrowserSwitchResult(activity, activity.getIntent());
if (browserSwitchResult != null) {
handleBrowserSwitchResult(browserSwitchResult);
}
}
}

private void handleBrowserSwitchResult(BrowserSwitchResult browserSwitchResult) {
venmoClient.onBrowserSwitchResult(browserSwitchResult, ((venmoAccountNonce, error) -> {
if (venmoAccountNonce != null) {
handleVenmoResult(venmoAccountNonce);
} else if (error != null) {
handleError(error);
}
}));
venmoClient.clearActiveBrowserSwitchRequests(requireContext());
}

@Override
public void onVenmoSuccess(@NonNull VenmoAccountNonce venmoAccountNonce) {
handleVenmoResult(venmoAccountNonce);
Expand Down
2 changes: 2 additions & 0 deletions Demo/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@
<string name="paypal_native_checkout_launch">Launch PayPal Native Checkout</string>
<string name="paypal_native_checkout_vault_launch">Launch PayPal Native Vault Checkout</string>
<string name="venmo">Venmo</string>
<string name="venmo_fallback_to_web">Venmo Fallback to Web</string>
<string name="venmo_fallback_to_web_summary">Fallback to web if the Venmo app is not installed.</string>
<string name="vault_venmo">Vault Venmo</string>
<string name="vault_venmo_summary">Vault Venmo payment methods on creation. Requires a customer id to be set.</string>
<string name="amex">Amex</string>
Expand Down
5 changes: 5 additions & 0 deletions Demo/src/main/res/xml/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@
android:title="@string/vault_venmo"
android:summary="@string/vault_venmo_summary"
android:defaultValue="true" />
<CheckBoxPreference
android:key="venmo_fallback_to_web"
android:title="@string/venmo_fallback_to_web"
android:summary="@string/venmo_fallback_to_web_summary"
android:defaultValue="false" />

</PreferenceCategory>

Expand Down
Loading

0 comments on commit ab5f704

Please sign in to comment.