Sunday 18 February 2018

Paytm Integration Android Example


Integrating Paytm Payment in Android Project
OUTPUT




Configuring the Paytm Checksum Kit

Now let’s start the real process. We will start with the server-side implementation.
  • Open XAMPP Server and Start the Server. (Skip this step if you are using a live server).
  • Then download the Paytm App Checksum Kit. And paste it to your server’s root directory. (For XAMPP it is c:/xampp/htdocs by default)
  • I have renamed the folder to only paytm to make it short and simple.
  • Inside the folder we have a file named generateChecksum.php and we need to use it for generating checksum.
  • But first we need to put our Paytm Merchant Key in the configuration.
  • Go to config_paytm.php (it is inside the lib folder paytm/lib/config_paytm.php), and put your Paytm Merchant Key.
  • That’s it for the server side implementation, we just need to route to generateChecksum.php file. So it is localhost/paytm/generateChecksum.php.
generateChecksumPost.php
<?php
 
$orderid =$_POST['orderid'];
$email =$_POST['email'];
$mobile =$_POST['mobile'];
$amount =$_POST['amount'];
 
//require_once('db_Connect.php');
 
header("Pragma: no-cache");
header("Cache-Control: no-cache");
header("Expires: 0");
// following files need to be included
require_once("./lib/config_paytm.php");
require_once("./lib/encdec_paytm.php");
//$checkSum = "qwertyasdfg12345";
 
// below code snippet is mandatory, so that no one can use your checksumgeneration url for other purpose .
$paramList = array();
$paramList["MID"] = 'YOUR MERCHANT ID'; //Provided by Paytm
$paramList["ORDER_ID"] = $orderid; //unique OrderId for every request
$paramList["CUST_ID"] = 'CUST563210'; // unique customer identifier 
$paramList["INDUSTRY_TYPE_ID"] = 'Retail'; //Provided by Paytm
$paramList["TXN_AMOUNT"] = $amount; // transaction amount
$paramList["CHANNEL_ID"] = 'WAP'; // transaction amount
$paramList["WEBSITE"] = 'APP_STAGING'; // transaction amount
$paramList["EMAIL"] = $email; // customer email id
$paramList["MOBILE_NO"] = $mobile; // customer 10 digit mobile no.
//$paramList["CALLBACK_URL"] = 'https://pguat.paytm.com/paytmchecksum/paytmCallback.jsp'; //Provided by Paytm
$paramList["CALLBACK_URL"] = 'http://YOUR_DOMAIN/paytm_integration/verifyCheckSum.php'; //Provided by Paytm
 
$checkSum = getChecksumFromArray($paramList,PAYTM_MERCHANT_KEY);
$paramList["CHECKSUMHASH"] = $checkSum;
 
echo json_encode($paramList);
//echo json_encode(array("category_sub_list"=>$paramList));
//print_r($paramList);
 
?>


verifyCheckSum.php
<?php
header("Pragma: no-cache");
header("Cache-Control: no-cache");
header("Expires: 0");
// following files need to be included
require_once("./lib/config_paytm.php");
require_once("./lib/encdec_paytm.php");
$paytmChecksum = "";
$paramList = array();
$isValidChecksum = FALSE;
$paramList = $_POST;
$return_array = $_POST;
$paytmChecksum = isset($_POST["CHECKSUMHASH"]) ? $_POST["CHECKSUMHASH"] : ""; //Sent by Paytm pg
//Verify all parameters received from Paytm pg to your application. Like MID received from paytm pg is same as your application’s MID, TXN_AMOUNT and ORDER_ID are same as what was sent by you to Paytm PG for initiating transaction etc.
$isValidChecksum = verifychecksum_e($paramList, PAYTM_MERCHANT_KEY, $paytmChecksum); //will return TRUE or FALSE string.
// if ($isValidChecksum===TRUE)
//   $return_array["IS_CHECKSUM_VALID"] = "Y";
// else
//   $return_array["IS_CHECKSUM_VALID"] = "N";
$return_array["IS_CHECKSUM_VALID"] = $isValidChecksum ? "Y" : "N";
//$return_array["TXNTYPE"] = "";
//$return_array["REFUNDAMT"] = "";
unset($return_array["CHECKSUMHASH"]);
 
$mid = $_POST['MID'];
$orderid = $_POST['ORDERID'];
 
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_URL => 'https://pguat.paytm.com/oltp/HANDLER_INTERNAL/TXNSTATUS?JsonData={"MID":"'.$mid.'","ORDERID":"'.$orderid.'","CHECKSUMHASH":"'.$paytmChecksum.'"}',
    CURLOPT_USERAGENT => 'Codular Sample cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
$status= json_decode($resp)->STATUS;
 
echo $resp; 
//exit();
 
// Close request to clear up some resources
curl_close($curl);
 
$encoded_json = htmlentities(json_encode($return_array));
?>
 
<html>
<head>
     <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-I">
     <title>Paytm</title>
     <script type="text/javascript">
            function response(){
                    return document.getElementById('response').value;
            }
     </script>
</head>
<body>
  Redirect back to the app<br>
  <form name="frm" method="post">
    <input type="hidden" id="response" name="responseField" value='<?php echo $encoded_json?>'>
  </form>
</body>
</html>

But remember using localhost will not work you need to find the IP. You can see it using the ipconfig command, and if you are using a live server, then you can use the URL with your domain.

Now, let’s move ahead by creating an Android Studio Project.

Creating a New Project
  • First, we will create a new Android Studio Project. I have create a project named PaytmIntegration with an Empty Activity.
Adding Paytm SDK
  • Now download the Paytm SDK. Inside the SDK you will find a file named PGSDK_V2.1.jar. We need to add this file in our project dependencies.
  • So first on the project explorer select Project.

  • Then inside app/lib paste the PGSDK_V2.1.jar that we downloaded.
  • Then add dependency in your build.gradle.


compile files('libs/PGSDK_V2.1.jar')

MainActivityPost.class

package com.paytmintegration;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.paytm.pgsdk.PaytmOrder;
import com.paytm.pgsdk.PaytmPGService;
import com.paytm.pgsdk.PaytmPaymentTransactionCallback;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;

/**
 * This is the sample app which will make use of the PG SDK. This activity will
 * show the usage of Paytm PG SDK API’s.
 **/

public class MainActivityPost extends Activity {

    String
orderId;
       
//Test
   
TextView order_id_txt;
    EditText
order_res;
    EditText
edt_email,edt_mobile,edt_amount;

    String
url = "http://YOUR_DOMAIN/paytm_integration/generateChecksumPost.php";
    Map
paramMap = new HashMap();
    String
mid="MID",order_id="ORDER_ID",cust_id="CUST_ID",callback="CALLBACK",industry_type="INDUS_TYPE",txn_amount="TXN_AMOUNT",checksum="CHECKSUM",mobile="MOBILE_NO",email="EMAIL",channel_id="CHANNEL_ID";
    String
website="WEBSITE";

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
        initOrderId();
        getWindow().setSoftInputMode(WindowManager.LayoutParams.
SOFT_INPUT_STATE_HIDDEN);

       
edt_email = (EditText)findViewById(R.id.edt_email);
       
edt_mobile = (EditText)findViewById(R.id.edt_mobile);
       
edt_amount = (EditText)findViewById(R.id.edt_amount);
    }

   
// This is to refresh the order id: Only for the Sample App’s purpose.
   
@Override
   
protected void onStart() {
       
super.onStart();
        initOrderId();
        getWindow().setSoftInputMode(WindowManager.LayoutParams.
SOFT_INPUT_STATE_HIDDEN);
    }

   
private void initOrderId() {
        Random r =
new Random(System.currentTimeMillis());
       
orderId = "ORDER" + (1 + r.nextInt(2)) * 10000
               
+ r.nextInt(10000);
       
order_id_txt = (TextView)findViewById(R.id.order_id);
       
order_id_txt.setText(orderId);

    }

   
public void onStartTransaction(View view) throws InterruptedException, ExecutionException {

       
if(edt_email.getText().toString().equalsIgnoreCase("")){
            Toast.makeText(getApplicationContext(),
"Please Enter Email-id",Toast.LENGTH_LONG).show();
        }
else if(edt_mobile.getText().toString().equalsIgnoreCase("")){
            Toast.makeText(getApplicationContext(),
"Please Enter Mobile Number",Toast.LENGTH_LONG).show();
        }
else if(edt_amount.getText().toString().equalsIgnoreCase("")){
            Toast.makeText(getApplicationContext(),
"Please Enter Amount",Toast.LENGTH_LONG).show();
        }
else {

            PaytmPGService Service = PaytmPGService.getStagingService();
            
//PaytmPGService Service = PaytmPGService.getProductionService();

           
Log.d("before request", "some");
            String edtemail =
edt_email.getText().toString().trim();
            String edtmobile =
edt_mobile.getText().toString().trim();
            String edtamount =
edt_amount.getText().toString().trim();
            JSONObject postData =
new JSONObject();

            HashMap<String, String> stringHashMap =
new HashMap<>();
            stringHashMap.put(
"orderid", orderId);
            stringHashMap.put(
"email", edtemail);
            stringHashMap.put(
"mobile", edtmobile);
            stringHashMap.put(
"amount", edtamount);

            SendDeviceDetails sendDeviceDetails =
null;
           
try {
                sendDeviceDetails =
new SendDeviceDetails(url, getPostDataString(stringHashMap), Service);
                sendDeviceDetails.execute();
            }
catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }


   
private class SendDeviceDetails extends AsyncTask<String, Void, String> {

        String
url,data;
        PaytmPGService
Service;

       
public SendDeviceDetails(String url, String data, PaytmPGService Service) {
           
this.url = url;
           
this.data = data;
           
this.Service = Service;
        }

       
@Override
       
protected String doInBackground(String... params) {

            String data1 =
"";

            HttpURLConnection httpURLConnection =
null;
           
try {

                httpURLConnection = (HttpURLConnection)
new URL(url).openConnection();
                httpURLConnection.setRequestMethod(
"POST");

                httpURLConnection.setDoOutput(
true);

                DataOutputStream wr =
new DataOutputStream(httpURLConnection.getOutputStream());
//                wr.writeBytes("PostData=" + params[1]);
               
wr.writeBytes(data);
                wr.flush();
                wr.close();

                InputStream in = httpURLConnection.getInputStream();
                InputStreamReader inputStreamReader =
new InputStreamReader(in);

               
int inputStreamData = inputStreamReader.read();
               
while (inputStreamData != -1) {
                   
char current = (char) inputStreamData;
                    inputStreamData = inputStreamReader.read();
                    data1 += current;
                }
            }
catch (Exception e) {
                e.printStackTrace();
            }
finally {
               
if (httpURLConnection != null) {
                    httpURLConnection.disconnect();
                }
            }

           
return data1;
        }

       
@Override
       
protected void onPostExecute(String result) {
           
super.onPostExecute(result);
            Toast.makeText(getApplicationContext(),result,Toast.
LENGTH_LONG).show();
            Log.e(
"TAG", result); // this is expecting a response code to be sent from your server upon receiving the POST data
            //String json = (String) myAsyncTask.execute(url).get();
           
JSONObject mJsonObject = null;
           
try {
                mJsonObject=
new JSONObject(result);
               
mid = mJsonObject.getString("MID");
               
order_id=mJsonObject.getString("ORDER_ID");
               
cust_id = mJsonObject.getString("CUST_ID");
               
callback = mJsonObject.getString("CALLBACK_URL");
               
industry_type = mJsonObject.getString("INDUSTRY_TYPE_ID");
               
channel_id = mJsonObject.getString("CHANNEL_ID");
               
txn_amount = mJsonObject.getString("TXN_AMOUNT");
               
checksum = mJsonObject.getString("CHECKSUMHASH");
               
mobile = mJsonObject.getString("MOBILE_NO");
               
email = mJsonObject.getString("EMAIL");
                
website = mJsonObject.getString("WEBSITE");

            }
catch (JSONException e) {
               
// TODO Auto-generated catch block
               
e.printStackTrace();
            }

            Log.d(
"after request", "some");

           
paramMap.put("MID", mid);
           
paramMap.put("ORDER_ID", order_id);
           
paramMap.put("CUST_ID", cust_id);
           
paramMap.put("INDUSTRY_TYPE_ID",industry_type);
           
paramMap.put("CHANNEL_ID",channel_id);
           
paramMap.put("TXN_AMOUNT",txn_amount);
           
paramMap.put("WEBSITE", website);
           
paramMap.put("EMAIL",email);
           
paramMap.put("MOBILE_NO",mobile);
           
paramMap.put("CALLBACK_URL",callback);
           
paramMap.put("CHECKSUMHASH",checksum);

            PaytmOrder Order =
new PaytmOrder(paramMap);

           
Service.initialize(Order, null);

           
Service.startPaymentTransaction(MainActivityPost.this, true, true,
                   
new PaytmPaymentTransactionCallback() {

                       
@Override
                       
public void someUIErrorOccurred(String inErrorMessage) {
// Some UI Error Occurred in Payment Gateway Activity.
// // This may be due to initialization of views in
// Payment Gateway Activity or may be due to //
// initialization of webview. // Error Message details
// the error occurred.
                           
Toast.makeText(getApplicationContext(), "Payment Transaction response " + inErrorMessage.toString(), Toast.LENGTH_LONG).show();

                        }

                       
@Override
                       
public void onTransactionResponse(Bundle inResponse) {
                            Log.d(
"LOG", "Payment Transaction :" + inResponse);
                            Toast.makeText(getApplicationContext(),
"Payment Transaction response " + inResponse.toString(), Toast.LENGTH_LONG).show();
                           
order_res = (EditText)findViewById(R.id.order_res);
                           
order_res.setText(inResponse.toString());

                            String response=inResponse.getString(
"RESPMSG");
                           
if (response.equals("Txn Successful."))
                            {
                                Toast.makeText(getApplicationContext(),response,Toast.
LENGTH_SHORT).show();
                            }
else
                           
{
                                Toast.makeText(getApplicationContext(),response,Toast.
LENGTH_SHORT).show();
                            }

                        }

                       
@Override
                       
public void networkNotAvailable() {
// If network is not
// available, then this
// method gets called.
                           
Toast.makeText(getApplicationContext(), "Network" , Toast.LENGTH_LONG).show();

                        }

                       
@Override
                       
public void clientAuthenticationFailed(String inErrorMessage) {
// This method gets called if client authentication
// failed. // Failure may be due to following reasons //
// 1. Server error or downtime. // 2. Server unable to
// generate checksum or checksum response is not in
// proper format. // 3. Server failed to authenticate
// that client. That is value of payt_STATUS is 2. //
// Error Message describes the reason for failure.
                           
Toast.makeText(getApplicationContext(), "clientAuthenticationFailed"+inErrorMessage.toString() , Toast.LENGTH_LONG).show();

                        }

                       
@Override
                       
public void onErrorLoadingWebPage(int iniErrorCode,
                                                          String inErrorMessage, String inFailingUrl) {

                            Toast.makeText(getApplicationContext(),
"onErrorLoadingWebPage"+inErrorMessage.toString() , Toast.LENGTH_LONG).show();

                        }

                       
// had to be added: NOTE
                       
@Override
                       
public void onBackPressedCancelTransaction() {
                            Toast.makeText(getApplicationContext(),
"onBackPressedCancelTransaction", Toast.LENGTH_LONG).show();

// TODO Auto-generated method stub
                       
}

                       
@Override
                       
public void onTransactionCancel(String inErrorMessage,
                                                        Bundle inResponse) {
                            Log.d(
"LOG", "Payment Transaction Failed "
                                    
+ inErrorMessage);
                            Toast.makeText(getBaseContext(),
                                   
"Payment Transaction Failed ",
                                    Toast.
LENGTH_LONG).show();
                        }

                    });
        }
    }


   
private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result =
new StringBuilder();
       
boolean first = true;
       
for(Map.Entry<String, String> entry : params.entrySet()){
           
if (first)
                first =
false;
           
else
               
result.append("&");
            result.append(URLEncoder.encode(entry.getKey(),
"UTF-8"));
            result.append(
"=");
            result.append(URLEncoder.encode(entry.getValue(),
"UTF-8"));
        }
       
return result.toString();
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<ScrollView

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">



    <LinearLayout

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:orientation="vertical"

        android:weightSum="1">



        <LinearLayout

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:orientation="vertical">



            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:text="Paytm Integration"

                android:textStyle="bold"

                android:textSize="18dip"

                android:layout_gravity="center_horizontal"

                android:layout_marginBottom="10dip"/>





        </LinearLayout>





        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal">

            <TextView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="Order Id : "

                android:textSize="20sp"/>

            <TextView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:id="@+id/order_id"

                android:layout_weight="1"

                android:textSize="20sp"/>

        </LinearLayout>



        <EditText

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:id="@+id/edt_email"

            android:hint="Enter Email"/>

        <EditText

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:id="@+id/edt_mobile"

            android:hint="Enter Mobile No"/>

        <EditText

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:id="@+id/edt_amount"

            android:hint="Enter Amount"/>



        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="vertical">

            <TextView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="Order Response : "

                android:textSize="20sp"/>

            <EditText

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:id="@+id/order_res"

                android:editable="false"/>

        </LinearLayout>



        <Button

            android:layout_width="217dp"

            android:layout_height="wrap_content"

            android:id="@+id/start_transaction"

            android:text="Pay"

            android:onClick="onStartTransaction"

            android:layout_gravity="center"

            android:textStyle="bold"

            android:textSize="16dip"

            android:layout_marginTop="10dip"

            android:layout_weight="2.05" />



    </LinearLayout>



</ScrollView>

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.paytmintegration">



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

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

    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:roundIcon="@mipmap/ic_launcher_round"

        android:supportsRtl="true"

        android:theme="@style/AppTheme">

        <activity android:name=".MainActivityPost">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />



                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>



        <activity

            android:name="com.paytm.pgsdk.PaytmPGActivity"

            android:screenOrientation="portrait"

            android:configChanges="keyboardHidden|orientation|keyboard"/>

    </application>



</manifest>