Skip to content

Commit

Permalink
Update Venmo with FPTI Analytics Events (#846)
Browse files Browse the repository at this point in the history
* Replace Venmo analytics with FPTI events

* Update unit tests

* Add new unit tests

* Fix unit tests

* Convert VenmoAnalytics to class

* Remove companion object

* Add helper analtyics methods

* Update app switch failure analytics

* Remove extra analytics event
  • Loading branch information
sarahkoop authored Dec 11, 2023
1 parent 2970a41 commit 69b62cb
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 110 deletions.
14 changes: 7 additions & 7 deletions Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.braintreepayments.api

internal enum class VenmoAnalytics(@JvmField val event: String) {
internal object VenmoAnalytics {

// Conversion Events
TOKENIZE_STARTED("venmo:tokenize:started"),
TOKENIZE_FAILED("venmo:tokenize:failed"),
TOKENIZE_SUCCEEDED("venmo:tokenize:succeeded"),
APP_SWITCH_CANCELED("venmo:tokenize:app-switch:canceled"),
const val TOKENIZE_STARTED = "venmo:tokenize:started"
const val TOKENIZE_FAILED = "venmo:tokenize:failed"
const val TOKENIZE_SUCCEEDED = "venmo:tokenize:succeeded"
const val APP_SWITCH_CANCELED = "venmo:tokenize:app-switch:canceled"

// Additional Detail Events
APP_SWITCH_SUCCEEDED("venmo:tokenize:app-switch:succeeded"),
APP_SWITCH_FAILED("venmo:tokenize:app-switch:failed")
const val APP_SWITCH_SUCCEEDED = "venmo:tokenize:app-switch:succeeded"
const val APP_SWITCH_FAILED = "venmo:tokenize:app-switch:failed"
}
83 changes: 43 additions & 40 deletions Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public VenmoClient(@NonNull Context context, @NonNull String authorization) {
* @param activity used to open the Venmo's Google Play Store
*/
public void showVenmoInGooglePlayStore(@NonNull FragmentActivity activity) {
braintreeClient.sendAnalyticsEvent("android.pay-with-venmo.app-store.invoked");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(
"https://play.google.com/store/apps/details?id=" + VENMO_PACKAGE_NAME));
Expand All @@ -80,25 +79,22 @@ public void showVenmoInGooglePlayStore(@NonNull FragmentActivity activity) {
public void createPaymentAuthRequest(@NonNull final FragmentActivity activity,
@NonNull final VenmoRequest request,
@NonNull VenmoPaymentAuthRequestCallback callback) {
braintreeClient.sendAnalyticsEvent("pay-with-venmo.selected");
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED);
braintreeClient.getConfiguration((configuration, error) -> {
if (configuration == null && error != null) {
callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(error));
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed");
callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(error));
return;
}

String exceptionMessage = null;
if (!configuration.isVenmoEnabled()) {
exceptionMessage = "Venmo is not enabled";
} else if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) {
exceptionMessage = "Venmo is not installed";
callbackPaymentAuthFailure(callback,
new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException("Venmo is not enabled")));
return;
}

if (exceptionMessage != null) {
callback.onVenmoPaymentAuthRequest(
new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException(exceptionMessage)));
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed");
if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) {
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED);
callbackPaymentAuthFailure(callback,
new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException("Venmo is not installed")));
return;
}

Expand All @@ -107,10 +103,9 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity,
if ((request.getCollectCustomerShippingAddress() ||
request.getCollectCustomerBillingAddress()) &&
!configuration.getVenmoEnrichedCustomerDataEnabled()) {
callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(new BraintreeException(
callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(new BraintreeException(
"Cannot collect customer data when ECD is disabled. Enable this feature " +
"in the Control Panel to collect this data.")));
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed");
return;
}

Expand All @@ -127,8 +122,7 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity,
braintreeClient.getAuthorization(), finalVenmoProfileId,
paymentContextId, callback);
} else {
callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(exception));
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed");
callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(exception));
}
});
});
Expand All @@ -150,7 +144,6 @@ private void createPaymentAuthRequest(
new VenmoPaymentAuthRequestParams(configuration, venmoProfileId, paymentContextId,
braintreeClient.getSessionId(), braintreeClient.getIntegrationType());
callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.ReadyToLaunch(params));
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.started");
}

/**
Expand All @@ -166,7 +159,7 @@ private void createPaymentAuthRequest(
public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResult,
@NonNull VenmoTokenizeCallback callback) {
if (venmoPaymentAuthResult.getError() == null) {
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.success");
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED);

final boolean isClientTokenAuth = (braintreeClient.getAuthorization() instanceof ClientToken);

Expand All @@ -181,20 +174,16 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul
vaultVenmoAccountNonce(nonce.getString(),
(venmoAccountNonce, vaultError) -> {
if (venmoAccountNonce != null) {
callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce));
callbackSuccess(callback, new VenmoResult.Success(venmoAccountNonce));
} else if (vaultError != null) {
callback.onVenmoResult(new VenmoResult.Failure(vaultError));
callbackTokenizeFailure(callback, new VenmoResult.Failure(vaultError));
}
});
} else {
braintreeClient.sendAnalyticsEvent(
"pay-with-venmo.app-switch.failure");
callback.onVenmoResult(new VenmoResult.Success(nonce));
callbackSuccess(callback, new VenmoResult.Success(nonce));
}
} else if (error != null) {
braintreeClient.sendAnalyticsEvent(
"pay-with-venmo.app-switch.failure");
callback.onVenmoResult(new VenmoResult.Failure(error));
callbackTokenizeFailure(callback, new VenmoResult.Failure(error));
}
});
} else {
Expand All @@ -205,36 +194,30 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul
if (shouldVault && isClientTokenAuth) {
vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> {
if (venmoAccountNonce != null) {
callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce));
callbackSuccess(callback, new VenmoResult.Success(venmoAccountNonce));
} else if (error != null) {
callback.onVenmoResult(new VenmoResult.Failure(error));
callbackTokenizeFailure(callback, new VenmoResult.Failure(error));
}
});
} else {
String venmoUsername = venmoPaymentAuthResult.getVenmoUsername();
VenmoAccountNonce venmoAccountNonce =
new VenmoAccountNonce(nonce, venmoUsername, false);
callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce));
callbackSuccess(callback, new VenmoResult.Success(venmoAccountNonce));
}

}
} else if (venmoPaymentAuthResult.getError() != null) {
if (venmoPaymentAuthResult.getError() instanceof UserCanceledException) {
braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.canceled");
callbackTokenizeCancel(callback);
} else {
callbackTokenizeFailure(callback, new VenmoResult.Failure(venmoPaymentAuthResult.getError()));
}
callback.onVenmoResult(VenmoResult.Cancel.INSTANCE);
}
}

private void vaultVenmoAccountNonce(String nonce, final VenmoInternalCallback callback) {
venmoApi.vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> {
if (venmoAccountNonce != null) {
braintreeClient.sendAnalyticsEvent("pay-with-venmo.vault.success");
} else {
braintreeClient.sendAnalyticsEvent("pay-with-venmo.vault.failed");
}
callback.onResult(venmoAccountNonce, error);
});
venmoApi.vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> callback.onResult(venmoAccountNonce, error));
}

/**
Expand Down Expand Up @@ -270,4 +253,24 @@ public void isReadyToPay(final Context context, final VenmoIsReadyToPayCallback
}
});
}

private void callbackPaymentAuthFailure(VenmoPaymentAuthRequestCallback callback, VenmoPaymentAuthRequest request) {
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED);
callback.onVenmoPaymentAuthRequest(request);
}

private void callbackSuccess(VenmoTokenizeCallback callback, VenmoResult venmoResult) {
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED);
callback.onVenmoResult(venmoResult);
}

private void callbackTokenizeCancel(VenmoTokenizeCallback callback) {
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED);
callback.onVenmoResult(VenmoResult.Cancel.INSTANCE);
}

private void callbackTokenizeFailure(VenmoTokenizeCallback callback, VenmoResult venmoResult) {
braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED);
callback.onVenmoResult(venmoResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ class VenmoAnalyticsUnitTest {
fun testAnalyticsEvents_sendsExpectedEventNames() {
assertEquals(
"venmo:tokenize:app-switch:canceled",
VenmoAnalytics.APP_SWITCH_CANCELED.event
VenmoAnalytics.APP_SWITCH_CANCELED
)
assertEquals(
"venmo:tokenize:app-switch:failed",
VenmoAnalytics.APP_SWITCH_FAILED.event
VenmoAnalytics.APP_SWITCH_FAILED
)
assertEquals(
"venmo:tokenize:app-switch:succeeded",
VenmoAnalytics.APP_SWITCH_SUCCEEDED.event
VenmoAnalytics.APP_SWITCH_SUCCEEDED
)
assertEquals("venmo:tokenize:failed", VenmoAnalytics.TOKENIZE_FAILED.event)
assertEquals("venmo:tokenize:started", VenmoAnalytics.TOKENIZE_STARTED.event)
assertEquals("venmo:tokenize:succeeded", VenmoAnalytics.TOKENIZE_SUCCEEDED.event)
assertEquals("venmo:tokenize:failed", VenmoAnalytics.TOKENIZE_FAILED)
assertEquals("venmo:tokenize:started", VenmoAnalytics.TOKENIZE_STARTED)
assertEquals("venmo:tokenize:succeeded", VenmoAnalytics.TOKENIZE_SUCCEEDED)
}
}
Loading

0 comments on commit 69b62cb

Please sign in to comment.