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>