Client-Side Implementation

Choose an integration methodAnchorIcon

You can set up your client-side either with our Drop-in UI or with a custom integration.

Drop-in integrationAnchorIcon

Our Drop-in UI is the fastest way to set up your client-side integration.

For full details, see Drop-in Setup and Integration.

Custom integrationAnchorIcon

Alternatively, you can add Venmo to your current custom integration. Keep in mind, for compliance purposes, we require you to present the customer with an order summary before and after purchase.

The pre-purchase summary should include:

  • The items ordered
  • The total order price
  • An indication of Venmo as the payment method

The post-purchase summary can either be shown in the UI or sent via email. It should include:

  • The items purchased
  • The total purchase price
  • The customer's name
  • The customer's Venmo username

Failing to comply with these guidelines can lead to an interruption of your Venmo service.

Get the SDKAnchorIcon

Add the following in your app-level build.gradle:

  1. Kotlin
  2. Groovy
dependencies {
    implementation("com.braintreepayments.api:venmo:5.8.0")
}

Invoking the Venmo flowAnchorIcon

Create an instance of VenmoClient and VenmoLauncher. When ready to launch the Venmo flow, make a call to venmoClient.createPaymentAuthRequest() - see startVenmoFlow() for an example in the code sample below. Store the VenmoPendingRequest obtained from a call to venmoLauncher.launch() to use later. In your onResume() method, call venmoLauncher.handleReturnToApp(). Once you have a successful result, complete the Venmo flow by calling venmoClient.tokenize(). See individual methods for detailed docs.

  1. Kotlin
class VenmoActivity : AppCompatActivity() {
    private lateinit var venmoClient: VenmoClient
    private lateinit var venmoLauncher: VenmoLauncher

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // must be initialized on onCreate()
        venmoLauncher = VenmoLauncher()

        // can be initialized outside onCreate() if desired
        venmoClient = VenmoClient(
            context = requireContext(),
            authorization = "TOKENIZATION_KEY or CLIENT_TOKEN",
            appLinkReturnUrl = Uri.parse("https://merchant-app.com") // Merchant App Link
        )
    }

    // ONLY REQUIRED IF YOUR ACTIVITY LAUNCH MODE IS SINGLE_TOP
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleReturnToApp(intent)
    }

    // ALL OTHER ACTIVITY LAUNCH MODES
    override fun onResume() {
        super.onResume()
        handleReturnToApp(intent)
    }

    private fun handleReturnToApp(intent: Intent) {
        super.onResume()
        val pendingRequest: VenmoPendingRequest.Started = pendingRequest
        pendingRequest?.let {
            val paymentAuthResult: VenmoPaymentAuthResult =
                venmoLauncher.handleReturnToApp(
                    pendingRequest = it,
                    intent = intent
                )
            if (paymentAuthResult is VenmoPaymentAuthResult.Success) {
                // complete the venmo flow with the successful paymentAuthResult
                completeVenmoFlow(paymentAuthResult)
            } else {
                // handle error - user did not complete Venmo flow
            }
            // clear pendingRequest
        }
    }

    private fun startVenmoFlow(venmoRequest: VenmoRequest) {
        venmoClient.createPaymentAuthRequest(
            context = requireActivity(),
            request = venmoRequest
        ) { paymentAuthRequest ->
            if (paymentAuthRequest is VenmoPaymentAuthRequest.Failure) {
                // handle paymentAuthRequest.error
            } else if (paymentAuthRequest is VenmoPaymentAuthRequest.ReadyToLaunch) {
                val pendingRequest: VenmoPendingRequest = venmoLauncher.launch(
                    activity = requireActivity(),
                    paymentAuthRequest = paymentAuthRequest
                )
                if (pendingRequest is VenmoPendingRequest.Started) {
                    // store pendingRequest for future use
                } else if (pendingRequest is VenmoPendingRequest.Failure) {
                    // handle pendingRequest.error
                }
            }
        }
    }

    private fun completeVenmoFlow(paymentAuthResult: VenmoPaymentAuthResult.Success) {
        venmoClient.tokenize(paymentAuthResult) { result: VenmoResult ->
            this.handleVenmoResult(result)
        }
    }

    private fun handleVenmoResult(result: VenmoResult) {
        when (result) {
            is VenmoResult.Success -> { /* handle result.nonce) */ }
            is VenmoResult.Failure -> { /* handle result.error */ }
            is VenmoResult.Cancel -> { /* handle user canceled */ }
        }
    }

    private fun storePendingRequest(request: VenmoPendingRequest.Started) {
        // store pending request
    }

    private val pendingRequest: VenmoPendingRequest.Started
        get() = { /* fetch stored pending request */ }

    private fun clearPendingRequest() {
        // clear/reset pending request
    }
}

Payment method usageAnchorIcon

You must specify how you will use the customer's Venmo account by passing the VenmoPaymentMethodUsage into your VenmoRequest:

  • MULTI_USE: Request authorization for future payments (vaulting allowed)
  • SINGLE_USE: Request authorization for a one-time payment (vaulting not allowed)

The payment method usage will affect the customer flow by:

  • Displaying different phrases to the customer on the transaction consent page (e.g. "Authorize Business Name to pay with Venmo" vs. "Authorize Business Name to pay with Venmo for future purchases" where Business Name is the business name submitted in the Venmo application form).
  • Not displaying a merchant connection on the Connected Businesses page in the Venmo app when the paymentMethodUsage property is SINGLE_USE.
  • Allowing customers to update their funding instrument on the Connected Businesses page in the Venmo app when the paymentMethodUsage property is MULTI_USE.
  1. Kotlin
  2. Java
val request = VenmoRequest(VenmoPaymentMethodUsage.MULTI_USE)

    venmoClient.tokenizeVenmoAccount(this, request)

Multiple profilesAnchorIcon

If you have a custom integration and have onboarded multiple apps for Venmo processing with a single Braintree gateway, you'll need to pass the profile_id to specify which Venmo profile to present during the payment flow.

You'll also need to pass the profile_id when creating the transaction on the server side.

Collect device dataAnchorIcon

You must collect information about the customer's device before creating each transaction.

  1. Kotlin
  2. Java
dataCollector.collectDeviceData(this@MyActivity) { deviceData, dataCollectorError ->
  // send venmoAccountNonce.string and deviceData to server
}

You'll need to pass this deviceData when creating the Venmo transaction from your server.

Shipping and Billing Address collectionAnchorIcon

You can specify if you wish to receive a customer's Venmo shipping and billing address by passing the collectCustomerBillingAddress and collectCustomerShippingAddress flags into your VenmoRequest. When these flags are enabled, Venmo will collect the required addresses from the consumer and send them back in the reponse object.
  1. Java
  2. Kotlin
VenmoRequest request = new VenmoRequest(VenmoPaymentMethodUsage.MULTI_USE);
request.setProfileId("your-profile-id");
request.setCollectCustomerBillingAddress(true);
request.setCollectCustomerShippingAddress(true);

venmoClient.tokenizeVenmoAccount(this, request)
Once the tokenization call is successful, you will receive the shipping and billing address in the venmo account nonce.
  1. Java
  2. Kotlin
@Override
public void onVenmoSuccess(@NonNull VenmoAccountNonce venmoAccountNonce) {
  PostalAddress billingAddress = venmoAccountNonce.getBillingAddress();
  String streetAddress = billingAddress.getStreetAddress();
  String extendedAddress = billingAddress.getExtendedAddress();
  String locality = billingAddress.getLocality();
  String region = billingAddress.getRegion();
  String postalCode = billingAddress.getPostalCode();

  PostalAddress shippingAddress = venmoAccountNonce.getShippingAddress();
  // ...
}

Amounts and Line ItemsAnchorIcon

If you are making the tokenization call in the context of a purchase, you will need to pass the total amount of the transaction which will be displayed to the user on the Venmo paysheet. Additionally, you can also pass other transaction details that you would like to render to the user such as subtotal, discount, taxes, shipping amount and line items.
  1. Java
  2. Kotlin
VenmoRequest request = new VenmoRequest(VenmoPaymentMethodUsage.MULTI_USE);
  request.setProfileId("your-profile-id");
  request.setTotalAmount('10.00');
  // Set optional amounts & line items
  request.setSubTotalAmount('8.00');
  request.setTaxAmount('1.00');
  request.setDiscountAmount('1.00');
  request.setShippingAmount('2.00');

  ArrayList<VenmoLineItem> lineItems = new ArrayList<>();
  lineItems.add(new VenmoLineItem(VenmoLineItem.KIND_DEBIT, "item-name", 2, "5.00"));
  lineItems.add(new VenmoLineItem(VenmoLineItem.KIND_CREDIT, "credited-item-name", 1, "2.00"));
  request.setLineItems(lineItems);

  venmoClient.tokenizeVenmoAccount(this, request)