Tuesday, 19 March 2019

CCAvenue Payment Gateway Android Integration



CCAvenue payment gateway android integration using PHP RSA and Response Handling.


AndroidManifest.xml
 


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

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

    <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=".activity.InitialScreenActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar"
>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".activity.WebViewActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar"
/>
        <activity android:name=".activity.StatusActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar"
/>
    </application>

</manifest>


String.xml
 
<resources>

    <string name="app_name">CCavenue Demo</string>

    <string name="access_code">Access Code</string>

    <string name="pay_button">Pay</string>

    <string name="merchant_id">Merchant Id</string>

    <string name="currency">Currency</string>

    <string name="amount">Amount</string>

    <string name="redirect_url">Redirect Url</string>

    <string name="cancel_url">Cancel Url</string>

    <string name="rsa_url">RSA Key Url</string>

</resources>

Styles.xml
<resources>

    <!-- Base application theme. -->

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

        <!-- Customize your theme here. -->

        <item name="colorPrimary">@color/colorPrimary</item>

        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>

        <item name="colorAccent">@color/colorAccent</item>

    </style>

    <style name="AppTheme.NoActionBar">

        <item name="windowActionBar">false</item>

        <item name="windowNoTitle">true</item>

    </style>


    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />


    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />


    <style name="Transperent_Toobar" parent="Theme.AppCompat.Light.NoActionBar">

        <item name="android:windowActionBarOverlay">true</item>

    </style>



</resources>

Build.gradle(Module:app)
 
Add dependencies
 
dependencies {

    implementation 'com.jakewharton:butterknife:8.8.1'

    implementation 'com.android.volley:volley:1.1.0'

}


Project Structure 


 
InitialScreenActivity.java

package com.ccavenuedemo.activity;



import android.content.Intent;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.EditText;

import android.widget.Toast;



import com.ccavenuedemo.R;

import com.ccavenuedemo.utility.AvenuesParams;

import com.ccavenuedemo.utility.ServiceUtility;



public class InitialScreenActivity extends AppCompatActivity {

   

   private EditText accessCode, merchantId, currency, amount, orderId, rsaKeyUrl, redirectUrl, cancelUrl;



   private void init(){

      accessCode = (EditText) findViewById(R.id.accessCode);

      merchantId = (EditText) findViewById(R.id.merchantId);

      orderId  = (EditText) findViewById(R.id.orderId);

      currency = (EditText) findViewById(R.id.currency);

      amount = (EditText) findViewById(R.id.amount);

      rsaKeyUrl = (EditText) findViewById(R.id.rsaUrl);

      redirectUrl = (EditText) findViewById(R.id.redirectUrl);

      cancelUrl = (EditText) findViewById(R.id.cancelUrl);



   }



   @Override

   public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_initial_screen);

      init();

   }



   public void onClick(View view) {

      //Mandatory parameters. Other parameters can be added if required.

      String vAccessCode = ServiceUtility.chkNull(accessCode.getText()).toString().trim();

      String vMerchantId = ServiceUtility.chkNull(merchantId.getText()).toString().trim();

      String vCurrency = ServiceUtility.chkNull(currency.getText()).toString().trim();

      String vAmount = ServiceUtility.chkNull(amount.getText()).toString().trim();

      if(!vAccessCode.equals("") && !vMerchantId.equals("") && !vCurrency.equals("") && !vAmount.equals("")){

         Intent intent = new Intent(this,WebViewActivity.class);

         intent.putExtra(AvenuesParams.ACCESS_CODE, ServiceUtility.chkNull(accessCode.getText()).toString().trim());

         intent.putExtra(AvenuesParams.MERCHANT_ID, ServiceUtility.chkNull(merchantId.getText()).toString().trim());

         intent.putExtra(AvenuesParams.ORDER_ID, ServiceUtility.chkNull(orderId.getText()).toString().trim());

         intent.putExtra(AvenuesParams.CURRENCY, ServiceUtility.chkNull(currency.getText()).toString().trim());

         intent.putExtra(AvenuesParams.AMOUNT, ServiceUtility.chkNull(amount.getText()).toString().trim());

         

         intent.putExtra(AvenuesParams.REDIRECT_URL, ServiceUtility.chkNull(redirectUrl.getText()).toString().trim());

         intent.putExtra(AvenuesParams.CANCEL_URL, ServiceUtility.chkNull(cancelUrl.getText()).toString().trim());

         intent.putExtra(AvenuesParams.RSA_KEY_URL, ServiceUtility.chkNull(rsaKeyUrl.getText()).toString().trim());





         startActivity(intent);

      }else{

         showToast("All parameters are mandatory.");

      }

   }

   

   public void showToast(String msg) {

      Toast.makeText(this, "Toast: " + msg, Toast.LENGTH_LONG).show();

   }





   @Override

   protected void onStart() {

      super.onStart();

      //generating new order number for every transaction

      Integer randomNum = ServiceUtility.randInt(0, 9999999);

      orderId.setText(randomNum.toString());

   }



}

activity_initial_screen.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

   android:layout_width="match_parent"

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

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

   android:layout_height="match_parent"

   >





<ScrollView

   android:id="@+id/scrollView1"

   android:layout_width="match_parent"

   android:layout_height="wrap_content">



   <LinearLayout

      android:layout_width="match_parent"

      android:layout_height="match_parent"

      android:gravity="left"

      android:padding="15dp"

      android:orientation="vertical" >



      <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/access_code" />



      <EditText

         android:id="@+id/accessCode"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:text="YOUR ACCESS CODE OUR HERE" >

         <requestFocus />

      </EditText>



      <TextView

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/merchant_id" />



      <EditText

         android:id="@+id/merchantId"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:text="YOUR MERCHANT ID OUR HERE "

         />



      <TextView

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="Order Id" />



      <EditText

         android:id="@+id/orderId"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         />



      <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/currency" />



      <EditText

         android:id="@+id/currency"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:text="INR"

         />



      <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/amount" />



      <EditText

         android:id="@+id/amount"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:text="1.00"

         />



      <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/redirect_url" />



      <EditText

         android:id="@+id/redirectUrl"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:inputType="textUri"

         android:text="YOUR REDIRECT URL OUR HERE (ccavResponseHandler.php)"

         />



      <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/cancel_url" />



      <EditText

         android:id="@+id/cancelUrl"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:inputType="textUri"

         android:text="YOUR CANCEL URL OUR HERE (ccavResponseHandler.php)" />



      <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:layout_marginTop="10dp"

         android:paddingLeft="10dp"

         android:text="@string/rsa_url" />



      <EditText

         android:id="@+id/rsaUrl"

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:ems="10"

         android:inputType="textUri"

         android:text="YOUR GET RSA URL OUR HERE (GetRSA.php)" />



      <Button

         android:id="@+id/nextButton"

         android:layout_gravity="center"

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         android:layout_marginBottom="48dp"

         android:onClick="onClick"

         android:text="@string/pay_button" />

   </LinearLayout>

</ScrollView>



</RelativeLayout>

WebViewActivity.java

package com.ccavenuedemo.activity;



import android.annotation.TargetApi;

import android.app.AlertDialog;

import android.app.Dialog;

import android.content.DialogInterface;

import android.content.Intent;

import android.graphics.Bitmap;

import android.os.AsyncTask;

import android.os.Build;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.webkit.JavascriptInterface;

import android.webkit.WebResourceRequest;

import android.webkit.WebView;

import android.webkit.WebViewClient;



import com.android.volley.DefaultRetryPolicy;

import com.android.volley.Request;

import com.android.volley.RequestQueue;

import com.android.volley.Response;

import com.android.volley.VolleyError;

import com.android.volley.toolbox.StringRequest;

import com.android.volley.toolbox.Volley;

import com.ccavenuedemo.R;

import com.ccavenuedemo.utility.AvenuesParams;

import com.ccavenuedemo.utility.Constants;

import com.ccavenuedemo.utility.LoadingDialog;

import com.ccavenuedemo.utility.RSAUtility;

import com.ccavenuedemo.utility.ServiceUtility;



import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

import java.util.HashMap;

import java.util.Map;



public class WebViewActivity extends AppCompatActivity {

    Intent mainIntent;

    String encVal;

    String vResponse;





    @Override

    public void onCreate(Bundle bundle) {

        super.onCreate(bundle);

        setContentView(R.layout.activity_webview);

        mainIntent = getIntent();



//get rsa key method

        get_RSA_key(mainIntent.getStringExtra(AvenuesParams.ACCESS_CODE), mainIntent.getStringExtra(AvenuesParams.ORDER_ID));

    }







    private class RenderView extends AsyncTask<Void, Void, Void> {

        @Override

        protected void onPreExecute() {

            super.onPreExecute();

            // Showing progress dialog

            LoadingDialog.showLoadingDialog(WebViewActivity.this, "Loading...");



        }



        @Override

        protected Void doInBackground(Void... arg0) {

            if (!ServiceUtility.chkNull(vResponse).equals("")

                    && ServiceUtility.chkNull(vResponse).toString().indexOf("ERROR") == -1) {

                StringBuffer vEncVal = new StringBuffer("");

                vEncVal.append(ServiceUtility.addToPostParams(AvenuesParams.AMOUNT, mainIntent.getStringExtra(AvenuesParams.AMOUNT)));

                vEncVal.append(ServiceUtility.addToPostParams(AvenuesParams.CURRENCY, mainIntent.getStringExtra(AvenuesParams.CURRENCY)));

                encVal = RSAUtility.encrypt(vEncVal.substring(0, vEncVal.length() - 1), vResponse);  //encrypt amount and currency

            }



            return null;

        }



        @Override

        protected void onPostExecute(Void result) {

            super.onPostExecute(result);

            // Dismiss the progress dialog

            LoadingDialog.cancelLoading();



            @SuppressWarnings("unused")

            class MyJavaScriptInterface {

                @JavascriptInterface

                public void processHTML(String html) {

                    // process the html source code to get final status of transaction

                    String status = null;

                    if (html.indexOf("Failure") != -1) {

                        status = "Transaction Declined!";

                    } else if (html.indexOf("Success") != -1) {

                        status = "Transaction Successful!";

                    } else if (html.indexOf("Aborted") != -1) {

                        status = "Transaction Cancelled!";

                    } else {

                        status = "Status Not Known!";

                    }

                    //Toast.makeText(getApplicationContext(), status, Toast.LENGTH_SHORT).show();

                    Intent intent = new Intent(getApplicationContext(), StatusActivity.class);

                    intent.putExtra("transStatus", status);

                    startActivity(intent);

                }

            }



            final WebView webview = (WebView) findViewById(R.id.webview);

            webview.getSettings().setJavaScriptEnabled(true);

            webview.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");

            webview.setWebViewClient(new WebViewClient() {



                @SuppressWarnings("deprecation")

                @Override

                public boolean shouldOverrideUrlLoading(WebView view, String url) {

                    return false;

                }



                @TargetApi(Build.VERSION_CODES.N)

                @Override

                public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

                    view.loadUrl(request.getUrl().toString());

                    return true;

                }



                @Override

                public void onPageFinished(WebView view, String url) {

                    super.onPageFinished(webview, url);

                    LoadingDialog.cancelLoading();

                    if (url.indexOf("/ccavResponseHandler.php") != -1) {

                        webview.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");

                    }

                }



                @Override

                public void onPageStarted(WebView view, String url, Bitmap favicon) {

                    super.onPageStarted(view, url, favicon);

                    LoadingDialog.showLoadingDialog(WebViewActivity.this, "Loading...");

                }

            });





            try {

                String postData = AvenuesParams.ACCESS_CODE + "=" + URLEncoder.encode(mainIntent.getStringExtra(AvenuesParams.ACCESS_CODE), "UTF-8") + "&" + AvenuesParams.MERCHANT_ID + "=" + URLEncoder.encode(mainIntent.getStringExtra(AvenuesParams.MERCHANT_ID), "UTF-8") + "&" + AvenuesParams.ORDER_ID + "=" + URLEncoder.encode(mainIntent.getStringExtra(AvenuesParams.ORDER_ID), "UTF-8") + "&" + AvenuesParams.REDIRECT_URL + "=" + URLEncoder.encode(mainIntent.getStringExtra(AvenuesParams.REDIRECT_URL), "UTF-8") + "&" + AvenuesParams.CANCEL_URL + "=" + URLEncoder.encode(mainIntent.getStringExtra(AvenuesParams.CANCEL_URL), "UTF-8") + "&" + AvenuesParams.ENC_VAL + "=" + URLEncoder.encode(encVal, "UTF-8");

                webview.postUrl(Constants.TRANS_URL, postData.getBytes());

            } catch (UnsupportedEncodingException e) {

                e.printStackTrace();

            }



        }

    }



    public void get_RSA_key(final String ac, final String od) {

        LoadingDialog.showLoadingDialog(WebViewActivity.this, "Loading...");



        StringRequest stringRequest = new StringRequest(Request.Method.POST, mainIntent.getStringExtra(AvenuesParams.RSA_KEY_URL),

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {

                        //Toast.makeText(WebViewActivity.this,response,Toast.LENGTH_LONG).show();

                        LoadingDialog.cancelLoading();



                        if (response != null && !response.equals("")) {

                            vResponse = response;     ///save retrived rsa key

                            if (vResponse.contains("!ERROR!")) {

                                show_alert(vResponse);

                            } else {

                                new RenderView().execute();   // Calling async task to get display content

                            }





                        }

                        else

                        {

                            show_alert("No response");

                        }

                    }

                },

                new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {

                        LoadingDialog.cancelLoading();

                        //Toast.makeText(WebViewActivity.this,error.toString(),Toast.LENGTH_LONG).show();

                    }

                }) {

            @Override

            protected Map<String, String> getParams() {

                Map<String, String> params = new HashMap<String, String>();

                params.put(AvenuesParams.ACCESS_CODE, ac);

                params.put(AvenuesParams.ORDER_ID, od);

                return params;

            }



        };

        stringRequest.setRetryPolicy(new DefaultRetryPolicy(

                30000,

                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,

                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        RequestQueue requestQueue = Volley.newRequestQueue(this);

        requestQueue.add(stringRequest);

    }



    public void show_alert(String msg) {

        AlertDialog alertDialog = new AlertDialog.Builder(

                WebViewActivity.this).create();



        alertDialog.setTitle("Error!!!");

        if (msg.contains("\n"))

            msg = msg.replaceAll("\\\n", "");



        alertDialog.setMessage(msg);







        alertDialog.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {



            @Override

            public void onClick(DialogInterface dialog, int which) {

                finish();

            }

        });





        alertDialog.show();

    }

}

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

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

    android:layout_width="match_parent"

    android:layout_height="match_parent"

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

    android:orientation="vertical">





    <WebView

        android:id="@+id/webview"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:visibility="visible" />



</RelativeLayout>

StatusActivity.java
 
package com.ccavenuedemo.activity;



import android.content.Intent;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.widget.TextView;

import android.widget.Toast;



import com.ccavenuedemo.R;



public class StatusActivity extends AppCompatActivity {



   @Override

   public void onCreate(Bundle bundle) {

      super.onCreate(bundle);

      setContentView(R.layout.activity_status);



      Intent mainIntent = getIntent();

      TextView tv4 = (TextView) findViewById(R.id.textView1);

      tv4.setText(mainIntent.getStringExtra("transStatus"));

   }

   

   public void showToast(String msg) {

      Toast.makeText(this, "Toast: " + msg, Toast.LENGTH_LONG).show();

   }



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

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

    android:layout_width="match_parent"

    android:layout_height="match_parent"

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

    android:orientation="vertical">



    <TextView

        android:id="@+id/textView1"

        android:layout_width="238dp"

        android:layout_height="40dp"

        android:layout_x="55dp"

        android:layout_y="157dp" />



</RelativeLayout>
 
 
AvenuesParams.java
 
package com.ccavenuedemo.utility;



public class AvenuesParams{

   public static final String COMMAND = "command";

   public static final String ACCESS_CODE = "access_code";

   public static final String MERCHANT_ID = "merchant_id";

   public static final String ORDER_ID = "order_id";

   public static final String AMOUNT = "amount";

   public static final String CURRENCY = "currency";

   public static final String ENC_VAL = "enc_val";

   public static final String REDIRECT_URL = "redirect_url";

   public static final String CANCEL_URL = "cancel_url";

   public static final String RSA_KEY_URL = "rsa_key_url";



}
 
Constants.java
 
package com.ccavenuedemo.utility;



public class Constants {

   public static final String PARAMETER_SEP = "&";

   public static final String PARAMETER_EQUALS = "=";

   public static final String TRANS_URL = "https://secure.ccavenue.com/transaction/initTrans";

}
 
LoadingDialog.java
 
package com.ccavenuedemo.utility;



import android.app.ProgressDialog;

import android.content.Context;





public class LoadingDialog {



    static ProgressDialog progressDialog;





    public static void showLoadingDialog(Context context, String message) {



        if (!(progressDialog != null && progressDialog.isShowing())) {

            progressDialog = new ProgressDialog(context);

            progressDialog.setMessage(message);



            progressDialog.setCancelable(false);

            progressDialog.setCanceledOnTouchOutside(false);



            progressDialog.show();

        }

    }



    public static void cancelLoading() {

        if (progressDialog != null && progressDialog.isShowing())

            progressDialog.cancel();



    }

}
 
RSAUtility.java
 
package com.ccavenuedemo.utility;



import android.util.Base64;



import java.security.KeyFactory;

import java.security.PublicKey;

import java.security.spec.X509EncodedKeySpec;



import javax.crypto.Cipher;





public class RSAUtility {

   public static String encrypt(String plainText, String key){

      try{

         PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode(key, Base64.DEFAULT)));

          Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

          cipher.init(Cipher.ENCRYPT_MODE, publicKey);

          return Base64.encodeToString(cipher.doFinal(plainText.getBytes("UTF-8")), Base64.DEFAULT);

      }catch (Exception e) {

         e.printStackTrace();

      }

      return null;

   }

}
 
 
ServiceUtility.java
 
package com.ccavenuedemo.utility;



import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Properties;

import java.util.Random;

import java.util.Set;

import java.util.StringTokenizer;



public class ServiceUtility{

   

   public java.util.Map readProperties(String pFilePath)throws IOException {

      java.util.Map vPropertyMap=new LinkedHashMap();

        Set vTckey;

      Iterator<String> vTcPropItr;

      Properties vTCProperties=null;

      try {

         vTCProperties = new Properties();

         vTCProperties.load(ServiceUtility.class.getResourceAsStream(pFilePath));

         vTckey = vTCProperties.keySet();

         vTcPropItr = vTckey.iterator();

         vPropertyMap=new LinkedHashMap();

         while(vTcPropItr.hasNext()){

            String vKey=vTcPropItr.next();

            vPropertyMap.put(vKey, vTCProperties.get(vKey));

         }

      }finally{

         vTcPropItr=null;

         vTckey=null;

         vTCProperties=null;

      }

        return vPropertyMap;

    }

   

   public static Object chkNull(Object pData){

      return (pData==null?"":pData);

   }

   

   public static java.util.Map tokenizeToHashMap(String msg, String delimPairValue, String delimKeyPair) throws Exception {

      java.util.Map keyPair = new HashMap();

      ArrayList respList = new ArrayList();

      String part = "";

      StringTokenizer strTkn = new StringTokenizer(msg, delimPairValue, true);

      while (strTkn.hasMoreTokens())

      {

         part = (String)strTkn.nextElement();

         if(part.equals(delimPairValue)) {

            part=null; 

         }

         else {

            respList = tokenizeToArrayList(part,delimKeyPair);

            if(respList.size() == 2)keyPair.put(respList.get(0), respList.get(1));

            else if (respList.size() == 1) keyPair.put(respList.get(0), null);

         }

         if(part == null) continue;

         if(strTkn.hasMoreTokens()) strTkn.nextElement();

      }     

      return keyPair.size() > 0 ? keyPair : null;

   }

   

   public static ArrayList tokenizeToArrayList(String msg, String delim) throws Exception {

      ArrayList respList = new ArrayList();

      String varName = null;

      String varVal = null;

      int index = msg.indexOf(delim);

      varName = msg.substring(0,index);

      if((index+1)!=msg.length())

         varVal = msg.substring(index+1,msg.length());

      respList.add(varName);

      respList.add(varVal);

      return respList.size() > 0 ? respList : null;

   }

   

   public static String addToPostParams(String paramKey, String paramValue){

      if(paramValue!=null)

         return paramKey.concat(Constants.PARAMETER_EQUALS).concat(paramValue)

               .concat(Constants.PARAMETER_SEP);

      return "";

   }

   

   public static int randInt(int min, int max) {

       // Usually this should be a field rather than a method variable so

       // that it is not re-seeded every call.

       Random rand = new Random();



       // nextInt is normally exclusive of the top value,

       // so add 1 to make it inclusive

       int randomNum = rand.nextInt((max - min) + 1) + min;



       return randomNum;

   }

}
 
 
RSA and Response Handling PHP files

ccavResponseHandler.php

<?php include('Crypto.php')?>
<?php

            error_reporting(0);
           
            $workingKey='';                       //Working Key should be provided here.
            $encResponse=$_POST["encResp"];                           //This is the response sent by the CCAvenue Server
            $rcvdString=decrypt($encResponse,$workingKey);               //Crypto Decryption used as per the specified working key.
            $order_status="";
            $decryptValues=explode('&', $rcvdString);
            $dataSize=sizeof($decryptValues);
            echo "<center>";

            for($i = 0; $i < $dataSize; $i++)
            {
                        $information=explode('=',$decryptValues[$i]);
                        if($i==3)          $order_status=$information[1];
            }

            if($order_status==="Success")
            {
                        echo "<br>Thank you for shopping with us. Your credit card has been charged and your transaction is successful. We will be shipping your order to you soon.";
                       
            }
            else if($order_status==="Aborted")
            {
                        echo "<br>Thank you for shopping with us.We will keep you posted regarding the status of your order through e-mail";
           
            }
            else if($order_status==="Failure")
            {
                        echo "<br>Thank you for shopping with us.However,the transaction has been declined.";
            }
            else
            {
                        echo "<br>Security Error. Illegal access detected";
           
            }

            echo "<br><br>";

            echo "<table cellspacing=4 cellpadding=4>";
            for($i = 0; $i < $dataSize; $i++)
            {
                        $information=explode('=',$decryptValues[$i]);
                         echo '<tr><td>'.$information[0].'</td><td>'.$information[1].'</td></tr>';
            }

            echo "</table><br>";
            echo "</center>";
?>

GetRSA.php

<?php
$url = "https://secure.ccavenue.com/transaction/getRSAKey";
$fields = array(
        'access_code'=>"",
        'order_id'=>$_POST['order_id']
);

$postvars='';
$sep='';
foreach($fields as $key=>$value)
{
        $postvars.= $sep.urlencode($key).'='.urlencode($value);
        $sep='&';
}

$ch = curl_init();

curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch, CURLOPT_CAINFO, 'replace this with your cacert.pem file path here');
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);

echo $result;
?>

Crypto.php

<?php

            error_reporting(0);

            function encrypt($plainText,$key)
            {
                        $secretKey = hextobin(md5($key));
                        $initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
                        $openMode = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '','cbc', '');
                        $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'cbc');
                        $plainPad = pkcs5_pad($plainText, $blockSize);
                        if (mcrypt_generic_init($openMode, $secretKey, $initVector) != -1)
                        {
                              $encryptedText = mcrypt_generic($openMode, $plainPad);
                               mcrypt_generic_deinit($openMode);
                                                            
                        }
                        return bin2hex($encryptedText);
            }

            function decrypt($encryptedText,$key)
            {
                        $secretKey = hextobin(md5($key));
                        $initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
                        $encryptedText=hextobin($encryptedText);
                        $openMode = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '','cbc', '');
                        mcrypt_generic_init($openMode, $secretKey, $initVector);
                        $decryptedText = mdecrypt_generic($openMode, $encryptedText);
                        $decryptedText = rtrim($decryptedText, "\0");
                        mcrypt_generic_deinit($openMode);
                        return $decryptedText;
                       
            }
            //*********** Padding Function *********************

             function pkcs5_pad ($plainText, $blockSize)
            {
                $pad = $blockSize - (strlen($plainText) % $blockSize);
                return $plainText . str_repeat(chr($pad), $pad);
            }

            //********** Hexadecimal to Binary function for php 4.0 version ********

            function hextobin($hexString)
             {
             $length = strlen($hexString);
             $binString="";  
             $count=0;
             while($count<$length)
             {      
                 $subString =substr($hexString,$count,2);          
                 $packedString = pack("H*",$subString);
                 if ($count==0)
                            {
                                                $binString=$packedString;
                            }
                 
                            else
                            {
                                                $binString.=$packedString;
                            }
                 
                            $count+=2;
             }
                    return $binString;
               }
?>


NOTE: cacert.pem file you will get from CCAvenue dashboard.