Using Braintree Payment in Android to accept Payment

In this android tutorial, we are going to learn how to use Braintree Payment in android to accept payment.

Accepting payment comes with integrating payment processing SDK in your android client application which will communicate with backend server provided by your provider for transaction processing.

Braintree Payment is part of PayPal business to focuses in helping businesses of all sizes, from small to large enterprise, accept and process payments to help maximise business opportunities and revenue growth.

Using Braintree Android SDK, you can accept payment with the following Payment Processors.

Android Pay

Apple Pay

PayPal

UnionPay

Venmo

Credit Cards

To use Braintree Payment in android, we will need to import or add the SDK library in our project gradle dependencies section.

Secondly, we will need to setup our own server which will help us to generate client token, payment nonce to create transaction and communicate with Braintree server for payment processing.

Also, we are going to create a new account with Braintree if you have not done that already. Since we are still working on development environment, we are going to create a Sandbox account for testing our android application.

The process of creating a sandbox account is simple and straight forward so we are not going to dive into it.

Once you have created your Braintree sandbox account, login into your account as shown

In your Dashboard, click on the Account tab. Then select My User, go to View Authorizations button and click on it to see the following information.

Environment – Sandbox

MerchantId – xxxxxxxxxxxxxxx

PublicKey – xxxxxxxxxxxxxxxx

PrivateKey – xxxxxxxxxxxxxxx

Copy and paste this information somewhere because we are going to use it in our server setup.

Most people usually get confused when they go directly to Braintree documentation. The reason is because it takes some time before you figure out there is different ways you can use to create android client with Braintree SDK.

In this tutorial, we are going to use Drop-in UI. Braintree Drop-in UI is an ready made UI that has the fields pre-built in it.

If you want to create you own UI interface for accepting payment, then you can use the Android Client SDK

Before we move further, I want to inform you that I have written some other android payment tutorials with different SDKs and APIs which might interest you. You can find some of them below.

1. Android Ecommerce Shopping App with PayPal 

2. Accepting payment in android using Stripe 

3. Android In-App Billing for digital products 

4. Android Pay Integration Tutorial

Now that we have done with creating Braintree Payment account, we will move on to create the android client application.

But before then, I have added some of the screen-shot for this tutorial to give you an idea of what we plan to achieve.

braintree android tutorial

1. Create a new android project

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidBraintree

Package: com.inducesmile.androidbraintree

Select Empty Activity

Name your activity: MainActivity

Keep other default selections

Continue to click on next button until Finish button is active, then click on Finish Button.

2. Update strings.xml resource file

Open the strings.xml file and add the code below.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Android BrainTree Payment</string>
    <string name="failed_token">Client Failed to retrieve token from server</string>
    <string name="BraintreeFragment_initialized">BraintreeFragment is ready to use</string>
    <string name="issues_with_authorization">There was an issue with your authorization string</string>
    <string name="token_failed">Fail to retrieve client token </string>
    <string name="buy_brand_new_laptop">BUY BRAND NEW LAPTOP</string>
    <string name="buy_now">BUY NOW</string>
</resources>

3. Update colors.xml resource file

Open the colors.xml resource file and add the code below.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorBackground">#DFD1D0</color>
    <color name="colorBlack">#000000</color>
</resources>

4. Update AndroidManifest.xml file

Since we are going to make network calls from our android client application to remote server application, add the Internet user permission in AndroidManifest.xml.

Also, we are going to add an Intent Infilter for PayPal Browser Switch Setup. If you decide not to accept payment with PayPal, you can leave it out.

The updated code is as shown.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.inducesmile.androidbraintree">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="com.braintreepayments.api.BraintreeBrowserSwitchActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="${applicationId}.braintree" />
            </intent-filter>
        </activity>

    </application>

</manifest>

5. Update build.gradle file

We are going to add the Braintree payment SDK and AsyncHttpClient library as dependencies in gradle. Open the build.gradle file and update the code as shown below.

We are going to add the Braintree payment SDK library as dependency in gradle. Open the build.gradle file and update the code as shown below.

apply plugin: 'com.android.application'

android {

    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.inducesmile.androidbraintree"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.1'
    compile 'com.braintreepayments.api:braintree:2.+'
    compile 'com.braintreepayments.api:drop-in:3.+'
    compile 'com.intuit.sdp:sdp-android:1.0.3'
    compile 'com.loopj.android:android-async-http:1.4.9'
    compile 'com.android.support:design:25.1.1'
    compile 'com.google.code.gson:gson:2.6.1'
    testCompile 'junit:junit:4.12'
}

 6. Update activity_main.xml

Now, lets design our project layout file. We are going to add an ImageView, TextView and Button widgets. When the button is clicked it will initialized Braintree payment.

Open the activity_main.xml and add the code below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="@color/colorBackground"
    tools:context="com.inducesmile.androidbraintree.MainActivity">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        android:adjustViewBounds="true"
        android:src="@drawable/laptop"
        android:contentDescription="@string/app_name"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_12sdp"
        android:textColor="@color/colorBlack"
        android:text="@string/buy_brand_new_laptop"/>

    <Button
        android:id="@+id/buy_now"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:text="@string/buy_now"
        android:textColor="@color/colorBlack"
        android:layout_marginTop="@dimen/_24sdp"/>

</LinearLayout>

7. Update MainActivity.java class

In the MainActivity class, we are going to get the instance of the button widget and attach an event click listener to it.

i. Generate a client token for the transaction

Every payment transaction that a user initiate, there is a client token associated with the transaction. In other to talk to our server to generate a client token for us, we will use the AsyncHttpClient Android Library.

Pass the path to your server in the GET method parameter and the callback methods will signified if the client token is successfully generator or not.

I have create a method be that does this.

private void getClientTokenFromServer(){
    AsyncHttpClient androidClient = new AsyncHttpClient();
    androidClient.get(PATH_TO_SERVER, new TextHttpResponseHandler() {
        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
            Log.d(TAG, getString(R.string.token_failed) + responseString);
        }
        @Override
        public void onSuccess(int statusCode, Header[] headers, String responseToken) {
            Log.d(TAG, "Client token: " + responseToken);
            clientToken = responseToken;
        }
    });
}

ii. Pass the client token DropInRequest object

Once the client token is obtained, pass it as a parameter to DropInRequest clientToken() method and then call startActivityForResult() method.

public void onBraintreeSubmit(View view){
    DropInRequest dropInRequest = new DropInRequest().clientToken(clientToken);
    startActivityForResult(dropInRequest.getIntent(this), BRAINTREE_REQUEST_CODE);
}

 iii. Obtain Payment Nonce from onActivityResult()

If everything works well, the android client application will obtain a payment nonce which it will send to the server. In the server, the payment nonce will be used to create a transaction for the user.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == BRAINTREE_REQUEST_CODE){
        if (RESULT_OK == resultCode){
            DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
            String paymentNonce = result.getPaymentMethodNonce().getNonce();
            //send to your server
            Log.d(TAG, "Testing the app here");
            sendPaymentNonceToServer(paymentNonce);
        }else if(resultCode == Activity.RESULT_CANCELED){
            Log.d(TAG, "User cancelled payment");
        }else {
            Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
            Log.d(TAG, " error exception");
        }
    }
}

The complete code for MainActivity class is as shown below.

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.braintreepayments.api.dropin.DropInActivity;
import com.braintreepayments.api.dropin.DropInRequest;
import com.braintreepayments.api.dropin.DropInResult;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.TextHttpResponseHandler;
import cz.msebera.android.httpclient.Header;
public class MainActivity extends AppCompatActivity{

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final String PATH_TO_SERVER = "PATH_TO_SERVER";
    private String clientToken;
    private static final int BRAINTREE_REQUEST_CODE = 4949;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        getClientTokenFromServer();
        Button buyNowButton = (Button)findViewById(R.id.buy_now);
        buyNowButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBraintreeSubmit(view);
            }
        });
    }

    public void onBraintreeSubmit(View view){
        DropInRequest dropInRequest = new DropInRequest().clientToken(clientToken);
        startActivityForResult(dropInRequest.getIntent(this), BRAINTREE_REQUEST_CODE);
    }

    private void getClientTokenFromServer(){
        AsyncHttpClient androidClient = new AsyncHttpClient();
        androidClient.get(PATH_TO_SERVER, new TextHttpResponseHandler() {
            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                Log.d(TAG, getString(R.string.token_failed) + responseString);
            }
            @Override
            public void onSuccess(int statusCode, Header[] headers, String responseToken) {
                Log.d(TAG, "Client token: " + responseToken);
                clientToken = responseToken;
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == BRAINTREE_REQUEST_CODE){
            if (RESULT_OK == resultCode){
                DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
                String paymentNonce = result.getPaymentMethodNonce().getNonce();
                //send to your server
                Log.d(TAG, "Testing the app here");
                sendPaymentNonceToServer(paymentNonce);
            }else if(resultCode == Activity.RESULT_CANCELED){
                Log.d(TAG, "User cancelled payment");
            }else {
                Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
                Log.d(TAG, " error exception");
            }
        }
    }

    private void sendPaymentNonceToServer(String paymentNonce){
        RequestParams params = new RequestParams("NONCE", paymentNonce);
        AsyncHttpClient androidClient = new AsyncHttpClient();
        androidClient.post(PATH_TO_SERVER, params, new TextHttpResponseHandler() {
            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                Log.d(TAG, "Error: Failed to create a transaction");
            }
            @Override
            public void onSuccess(int statusCode, Header[] headers, String responseString) {
                Log.d(TAG, "Output " + responseString);
            }
        });
    }
}

That is all for our android client application. We will move over to create the server side application.

8. Create Server Side Application using Braintree Payment Php SDK

First, we are going to download the Braintree Payment Php SDK. Move over to the following link and download a copy.

I am using WAMP local server. Create a new folder for your application and name it braintree or any name of your choice.

Copy and pass the Braintree Php SDK inside the application folder.

Create a new php file and name it index.php.

Open the index.php and include this class in it.

<?php
include_once 'braintree-php-3.21.1/lib/Braintree.php';

Get the private and public keys we obtained when we created a Braintree account and fill the information below.

Braintree_Configuration::environment('sandbox');
Braintree_Configuration::merchantId(' ');
Braintree_Configuration::publicKey(' ');
Braintree_Configuration::privateKey(' ');

Check for Payment Nonce or Generate Token

Finally, we will check if the incoming request is a POST method and if it contains a Key parameter value NONCE.

If it contains key value, then we create a payment transaction with the code below.

if(isset($_POST["NONCE"])){
  $nonceFromTheClient = $_POST["NONCE"];
  $result = Braintree_Transaction::sale([
    'amount' => '1000.00',
    'paymentMethodNonce' => $nonceFromTheClient,
    'options' => ['submitForSettlement' => true ]
  ]);

If not we will generate a new client token using the line of code below.

echo($clientToken = Braintree_ClientToken::generate());

Open the index.php and add the complete code as shown below.

<?php
include_once 'braintree-php-3.21.1/lib/Braintree.php';

Braintree_Configuration::environment('sandbox');
Braintree_Configuration::merchantId(' ');
Braintree_Configuration::publicKey(' ');
Braintree_Configuration::privateKey(' ');


if(isset($_POST["NONCE"])){
  $nonceFromTheClient = $_POST["NONCE"];
  $result = Braintree_Transaction::sale([
    'amount' => '1000.00',
    'paymentMethodNonce' => $nonceFromTheClient,
    'options' => ['submitForSettlement' => true ]
  ]);


  if ($result->success) {
      echo("success!: " . $result->transaction->id);
  } else if ($result->transaction) {
      echo "Error processing transaction: \n" . " code: " . $result->transaction->processorResponseCode . " \n " . " text: " . $result->transaction->processorResponseText;
  } else {
      echo "Validation errors: \n"; //+ $result->errors->deepAll();
  }

}else{
  echo($clientToken = Braintree_ClientToken::generate());
}

?>

9. Test the application

There is no better time to test the application than now. Run the android application and click on Buy Now button, a new dialog will appear in the bottom center of your device with the option to pay with PayPal or Credit Card.

If you want to use Credit card payment, you can look up the credit card numbers that have been made available for testing by Braintree Payment.

This is an example of successful transaction as shown in my Sandbox Dashboard.

braintree android sdk

Please note that this is a simple tutorial on how to use Braintree to accept payment in android. There are many things I did not cover in the SDK.

Feel free to dig more in their SDK and you can also learn how you can build your own payment interface.

You can download the code for this tutorial above. If you are having hard time downloading the tutorial, kindly contact me.

Remember to subscribe with your email address to be among the first to receive my new android blog post once it is published.

One Response

Add a Comment