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>
<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.