ICICI Eazypay PHP

Internet banking has grown a lot in the past decade and will continue to grow even more considering how much our life’s are getting digitalized. Also, commercial websites require a payment gateway integrated so that the payment can be done instantly without any hassle and ICICI Eazypay provides a solution.

In this post, I’ll be showing you how to integrate ICICI Eazypay with any website using PHP. Also, we will be creating a simple form that will get the user details and amount as inputs and send an email to the payer and the owner via PHPMailer.

Sidenote: Feels good to be back on the writing side of my life which got disrupted for the past few months due to work and the COVID-19 pandemic. But I did get an opportunity to work on a side project and it took me while to get this done which actually motivated me to write this post. 

ICICI Eazypay Integration

ICICI provides a payment gateway called as Eazypay which can be easily integrated with any website and has various options for money transfer. They can be integrated using programming languages like Java, VB.Net and PHP.

Step 1: Contact nearest ICICI branch

If you are planning to use the ICICI Eazypay in your website, then contact the nearest ICICI bank and get necessary things done before going to the next step.

Step 2: Get user inputs

First let’s create a simple form that takes the payer’s name, email address, phone number and the amount he needs to pay.

<div class="payment-section">
  <div class="eazypay-payment">
    <form onsubmit="return validateForm()" method="post" name="paymentform">
      <label for="payername"> Name: (Required)</label><br>
      <input type="text" id="payername" name="payername" required><br>
      <label for="payerphone"> Phone Number: (Optional)</label><br>
      <input type="text" id="payerphone" name="payerphone"/><br>
      <label for="payeremail"> Email ID: (Required)</label><br>
      <input type="email" id="payeremail" name="payeremail"/><br>
      <label for="payeramount"> Amount:</label><br>
      <input type="number" min="0" id="amount" name="payeramount" required/><br><br>
      <input id="paybutton" name="payeramount" type="submit" value="Pay Amount">
    </form> 
  </div>        
</div>

I haven’t done any validations except for the required field validation. You can add more if you want to. Just create a function validateForm() and you can get the form values similarly like this one below:

<head>
  <script>
      function validateForm() {
        var amount = document.forms["paymentform"]["payeramount"].value;
        if (amount < 0) {
          alert("Amount should be a greater than Rs.0");
          return false;
        }
      }
  </script>
</head>

Step 3 – Creating the payment gateway URL

If your registration for the Eazypay is successful, then the bank will send you an email with some confidential information. The email will have the merchant id, encryption key, sub merchant id, payment mode and the return url.  Make a note of it as you need them in this step.

Use the following code which will be used to create the URL for the Eazypay payment gateway.

<?php

class Eazypay
{
    public $merchant_id;
    public $encryption_key;
    public $sub_merchant_id;
    public $reference_no;
    public $paymode;
    public $return_url;

    const DEFAULT_BASE_URL = 'https://eazypay.icicibank.com/EazyPG?';

    public function __construct()
    {
        $this->merchant_id              =    XXXXXX;
        $this->encryption_key           =    XXXXXXXXXXXXXXX;
        $this->sub_merchant_id          =    XX;
        $this->paymode                  =    X;
        $this->return_url               =    'https://example.com/some_file_name.php';
    }

    public function getPaymentUrl($amount, $reference_no, $optionalField=null)
    {
        $mandatoryField   =    $this->getMandatoryField($amount, $reference_no);
        $optionalField    =    $this->getOptionalField($optionalField);
        $amount           =    $this->getAmount($amount);
        $reference_no     =    $this->getReferenceNo($reference_no);

        $paymentUrl = $this->generatePaymentUrl($mandatoryField, $optionalField, $amount, $reference_no);
        return $paymentUrl;
    }

    protected function generatePaymentUrl($mandatoryField, $optionalField, $amount, $reference_no)
    {
        $encryptedUrl = self::DEFAULT_BASE_URL."merchantid=".$this->merchant_id.
            "&mandatory fields=".$mandatoryField."&optional fields=".$optionalField.
            "&returnurl=".$this->getReturnUrl()."&Reference No=".$reference_no.
            "&submerchantid=".$this->getSubMerchantId()."&transaction amount=".
            $amount."&paymode=".$this->getPaymode();

        return $encryptedUrl;
    }

    protected function getMandatoryField($amount, $reference_no)
    {
        return $this->getEncryptValue($reference_no.'|'.$this->sub_merchant_id.'|'.$amount);
    }

    // optional field must be seperated with | eg. (20|20|20|20)
    protected function getOptionalField($optionalField=null)
    {
        if (!is_null($optionalField)) {
            return $this->getEncryptValue($optionalField);
        }
        return null;
    }

    protected function getAmount($amount)
    {
        return $this->getEncryptValue($amount);
    }

    protected function getReturnUrl()
    {
        return $this->getEncryptValue($this->return_url);
    }

    protected function getReferenceNo($reference_no)
    {
        return $this->getEncryptValue($reference_no);
    }

    protected function getSubMerchantId()
    {
        return $this->getEncryptValue($this->sub_merchant_id);
    }

    protected function getPaymode()
    {
        return $this->getEncryptValue($this->paymode);
    }

    // use @ to avoid php warning php 

    protected function getEncryptValue($data)
    {
        // Generate an initialization vector
        // $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
        // Encrypt the data using AES 128 encryption in ecb mode using our encryption key and initialization vector.
      $encrypted = openssl_encrypt($data, 'aes-128-ecb', $this->encryption_key, OPENSSL_RAW_DATA);
      // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
      return base64_encode($encrypted);
    }
}

Just replace the merchant_id, encryption_key, sub_merchant_id, paymode and return url values with the ones provided to you. The URL should be encrypted using the encrypted key provided to you for a safer transaction.

Note: During the registration process, the bank will ask you for your domain name. Since the return URL is the url to which the payer will be redirected to once the payment is a success or a failure, make sure that you activate HTTPS for your domain before registering for Eazypay.  If you domain name is https://www.example.com, then the return URL will be https://www.example.com/some_file_name.php

Step 4: Redirecting to the payment URL

Now that we have the code to generate the URL, let’s generate one. And for that, you can use the code below:

<?php
  session_start();
    if(isset($_POST['donation_payment'])) {
    $_SESSION['payer_name'] = $_REQUEST['payername'];
    $_SESSION['payer_phone'] = $_REQUEST['payerphone'];
    $_SESSION['payer-email'] = $_REQUEST['payeremail'];
    $amount = $_REQUEST['payeramount'];
    include 'payment.php';
    $reference_no = rand();
    // call The method
    $eazypay_integration=new Eazypay();
    $payment_url=$eazypay_integration->getPaymentUrl($amount, $reference_no , $optionalField=null);
    header('Location: '.$payment_url);
    exit;
    }
?>

Let me quickly walk you through what the code does.

  • Creating a PHP session and store the name, email, phone and amount in separate session variables which we can be consumed in other PHP files later on.
  • Including the payment.php file which contains the code used to generate the URL.
  • Creating a reference_no randomly using the PHP rand() function which needs to be unique for every transaction and then we create an instance of the class EazyPay which will be present inside the final-payment.php
  • Finally we pass the amount and the reference_no to the getPaymentUrl() function and once it returns the URL, we redirect to the URL using the header function in Javascript

If you are done with all the above steps, then you can run the code on the server and test it out. Click on the “Pay Amount” button and if everything goes well, then you should be getting a screen like this:

eazypay_icici_php

Step 5.1 :  Show the response page

When the payer is done with the payment, he will be redirected to the return URL which will contain a file_name.php at the end. If your return url is https://example.com/ResponseHandler.php, then create a file ResponseHandler.php in the root folder in your server. 

Inside that file, you can access the response that was sent from Eazypay using the PHP $_POST variables. You can use the following code to check whether the payment is a success or a failure.

<?php 
session_start();
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
function payment_success_exec() {
	if(isset($_POST) && isset($_POST['Total_Amount']) && $_POST['Response_Code'] == 'E000') {
		$res = $_POST;
		
		// Same encryption key that we gave for generating the URL
		$aes_key_for_payment_success = XXXXXXXXXXXXXXXX;

		$data = array(
			'Response_Code'=> $res['Response_Code'],
			'Unique_Ref_Number'=> $res['Unique_Ref_Number'],
			'Service_Tax_Amount'=> $res['Service_Tax_Amount'],
			'Processing_Fee_Amount'=> $res['Processing_Fee_Amount'],
			'Total_Amount'=> $res['Total_Amount'],
			'Transaction_Amount'=> $res['Transaction_Amount'],
			'Transaction_Date'=> $res['Transaction_Date'],
			'Interchange_Value'=> $res['Interchange_Value'],
			'TDR'=> $res['TDR'],
			'Payment_Mode'=> $res['Payment_Mode'],
			'SubMerchantId'=> $res['SubMerchantId'],
			'ReferenceNo'=> $res['ReferenceNo'],
			'ID'=> $res['ID'],
			'RS'=> $res['RS'],
			'TPS'=> $res['TPS'],
		);

		$verification_key = $data['ID'].'|'.$data['Response_Code'].'|'.$data['Unique_Ref_Number'].'|'.
				$data['Service_Tax_Amount'].'|'.$data['Processing_Fee_Amount'].'|'.$data['Total_Amount'].'|'.
				$data['Transaction_Amount'].'|'.$data['Transaction_Date'].'|'.$data['Interchange_Value'].'|'.
				$data['TDR'].'|'.$data['Payment_Mode'].'|'.$data['SubMerchantId'].'|'.$data['ReferenceNo'].'|'.
				$data['TPS'].'|'.$aes_key_for_payment_success;

		$encrypted_message = hash('sha512', $verification_key);
		if($encrypted_message == $data['RS']) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}
?>

Additionally, you can also show a Thank you message when the payment is a success or the reason for failure when the payment fails.

<?php 
function response_code($code) {
     $rc=array('E000' =>'"Payment Successful.', 
     'E001' =>'Unauthorized Payment Mode', 
     'E002' =>'Unauthorized Key', 
     'E003' =>'Unauthorized Packet', 
     'E004' =>'Unauthorized Merchant', 
     'E005' =>'Unauthorized Return URL', 
     'E006' =>'"Transaction Already Paid, Received Confirmation from the Bank, Yet to Settle the transaction with the Bank', 
     'E007' =>'Transaction Failed', 
     'E008' =>'Failure from Third Party due to Technical Error', 
     'E009' =>'Bill Already Expired', 
     'E0031' =>'Mandatory fields coming from merchant are empty', 
     'E0032' =>'Mandatory fields coming from database are empty', 
     'E0033' =>'Payment mode coming from merchant is empty', 
     'E0034' =>'PG Reference number coming from merchant is empty', 
     'E0035' =>'Sub merchant id coming from merchant is empty', 
     'E0036' =>'Transaction amount coming from merchant is empty', 
     'E0037' =>'Payment mode coming from merchant is other than 0 to 9', 
     'E0038' =>'Transaction amount coming from merchant is more than 9 digit length', 
     'E0039' =>'Mandatory value Email in wrong format', 
     'E00310' =>'Mandatory value mobile number in wrong format', 
     'E00311' =>'Mandatory value amount in wrong format', 
     'E00312' =>'Mandatory value Pan card in wrong format', 
     'E00313' =>'Mandatory value Date in wrong format', 
     'E00314' =>'Mandatory value String in wrong format', 
     'E00315' =>'Optional value Email in wrong format', 
     'E00316' =>'Optional value mobile number in wrong format', 
     'E00317' =>'Optional value amount in wrong format', 
     'E00318' =>'Optional value pan card number in wrong format', 
     'E00319' =>'Optional value date in wrong format', 
     'E00320' =>'Optional value string in wrong format', 
     'E00321' =>'Request packet mandatory columns is not equal to mandatory columns set in enrolment or optional columns are not equal to optional columns length set in enrolment', 
     'E00322' =>'Reference Number Blank', 
     'E00323' =>'Mandatory Columns are Blank', 
     'E00324' =>'Merchant Reference Number and Mandatory Columns are Blank', 
     'E00325' =>'Merchant Reference Number Duplicate', 
     'E00326' =>'Sub merchant id coming from merchant is non numeric', 
     'E00327' =>'Cash Challan Generated', 
     'E00328' =>'Cheque Challan Generated', 
     'E00329' =>'NEFT Challan Generated', 
     'E00330' =>'Transaction Amount and Mandatory Transaction Amount mismatch in Request URL', 
     'E00331' =>'UPI Transaction Initiated Please Accept or Reject the Transaction', 
     'E00332' =>'Challan Already Generated, Please re-initiate with unique reference number', 
     'E00333' =>'Referer value is null / invalid Referer', 
     'E00334' =>'Value of Mandatory parameter Reference No and Request Reference No are not matched', 
     'E00335' =>'Payment has been cancelled',
     'E0801' =>'FAIL', 
     'E0802' =>'User Dropped', 
     'E0803' =>'Canceled by user', 
     'E0804' =>'User Request arrived but card brand not supported', 
     'E0805' =>'Checkout page rendered Card function not supported', 
     'E0806' =>'Forwarded / Exceeds withdrawal amount limit', 
     'E0807' =>'PG Fwd Fail / Issuer Authentication Server failure', 
     'E0808' =>'Session expiry / Failed Initiate Check, Card BIN not present', 
     'E0809' =>'Reversed / Expired Card', 
     'E0810' =>'Unable to Authorize', 
     'E0811' =>'Invalid Response Code or Guide received from Issuer', 
     'E0812' =>'Do not honor', 
     'E0813' =>'Invalid transaction', 
     'E0814' =>'Not Matched with the entered amount', 
     'E0815' =>'Not sufficient funds', 
     'E0816' =>'No Match with the card number', 
     'E0817' =>'General Error', 
     'E0818' =>'Suspected fraud', 
     'E0819' =>'User Inactive', 
     'E0820' =>'ECI 1 and ECI6 Error for Debit Cards and Credit Cards', 
     'E0821' =>'ECI 7 for Debit Cards and Credit Cards', 
     'E0822' =>'System error. Could not process transaction', 
     'E0823' =>'Invalid 3D Secure values', 
     'E0824' =>'Bad Track Data', 
     'E0825' =>'Transaction not permitted to cardholder', 
     'E0826' =>'Rupay timeout from issuing bank', 
     'E0827' =>'OCEAN for Debit Cards and Credit Cards', 
     'E0828' =>'E-commerce decline', 
     'E0829' =>'This transaction is already in process or already processed', 
     'E0830' =>'Issuer or switch is inoperative', 
     'E0831' =>'Exceeds withdrawal frequency limit', 
     'E0832' =>'Restricted card', 
     'E0833' =>'Lost card', 
     'E0834' =>'Communication Error with NPCI', 
     'E0835' =>'The order already exists in the database', 
     'E0836' =>'General Error Rejected by NPCI', 
     'E0837' =>'Invalid credit card number', 
     'E0838' =>'Invalid amount', 
     'E0839' =>'Duplicate Data Posted', 
     'E0840' =>'Format error', 
     'E0841' =>'SYSTEM ERROR', 
     'E0842' =>'Invalid expiration date', 
     'E0843' =>'Session expired for this transaction', 
     'E0844' =>'FRAUD - Purchase limit exceeded', 
     'E0845' =>'Verification decline', 
     'E0846' =>'Compliance error code for issuer', 
     'E0847' =>'Caught ERROR of type:[ System.Xml.XmlException ] . strXML is not a valid XML string', 
     'E0848' =>'Incorrect personal identification number', 
     'E0849' =>'Stolen card', 
     'E0850' =>'Transaction timed out, please retry', 
     'E0851' =>'Failed in Authorize - PE', 
     'E0852' =>'Cardholder did not return from Rupay', 
     'E0853' =>'Missing Mandatory Field(s)The field card_number has exceeded the maximum length of', 
     'E0854' =>'Exception in CheckEnrollmentStatus: Data at the root level is invalid. Line 1, position 1.', 
     'E0855' =>'CAF status = 0 or 9', 
     'E0856' =>'412', 
     'E0857' =>'Allowable number of PIN tries exceeded', 
     'E0858' =>'No such issuer', 
     'E0859' =>'Invalid Data Posted', 
     'E0860' =>'PREVIOUSLY AUTHORIZED', 
     'E0861' =>'Cardholder did not return from ACS', 
     'E0862' =>'Duplicate transmission', 
     'E0863' =>'Wrong transaction state', 
     'E0864' =>'Card acceptor contact acquirer');
 return $rc[$code];
 }
?>
<html>
<body>
<?php if(payment_success_exec()): ?>
<?php 
include "thank-you.php"; // Insert any content into the file you wish to display to the user when the payment is successful
?>
<?php else: ?>
<?php 
$response = response_code($_POST['Response_Code']);
echo "<div style='text-align:center; width: 100%;font-size:20px;'><p>Transaction failed due to some reason. Please check with your bank if amount has been deducted.</p> 
<p>Sorry for the inconvenience caused.</p>";
echo "<p>Your bank has returned the following error message: <b>".$response."</b></p>";
echo "<p> Click <a href='https://example.com/'>here</a> to return to the home page</p></div>";
?>
<?php endif; ?>
</body>
</html>

Step 5.2 : Sending an email to the owner and the payer 

We can easily send emails from our server using the PHPMailer library. Download the library and add it to the root folder in your server. Then include this at the top of the ResponseHandler.php, just after the session_start();

<?php
session_start();
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
?>

After that, add the following code below.

<?php
function send_email_via_smtp($to_email, $reply_to, $reply_name, $subject, $headermsg, $msgbody, $footermsg) {
	$mail = new PHPMailer();
	$mail->IsSMTP();
	$mail->Mailer = "smtp";
	$mail->SMTPDebug  = 0;  
	$mail->SMTPAuth   = TRUE;
	$mail->SMTPSecure = "tls";
	$mail->Port       = 587;
	$mail->Host       = "smtp.gmail.com";
	$mail->Username   = "your_emailid";
	$mail->Password   = "your_password";
	$mail->IsHTML(true);
	$mail->addReplyTo($reply_to, $reply_name);
	$mail->AddAddress($to_email, $_SESSION['payername']);
	$mail->SetFrom($reply_to, "Your Name");
	$mail->Subject = $subject;
	$mail->MsgHTML($headermsg.$msgbody.$footermsg); 
	if(!$mail->Send()) {
		return false;
	} else {
		return true;
	}
}		
<?php 
include "thank-you.php"; 
$headermsg = "<p> Your header message</p>";
$msgbody = "You message body";
$footermsg = "<p> Your footer message</p>";
//Send Email to the payer
send_email_via_smtp($_SESSION['payeremail'], "owner_email_id", "owner_name", "email_subject", $headermsg, $msgbody, $footermsg);

//Send Email to the owner
send_email_via_smtp("owner_email_id", $_SESSION['payeremail'], $_SESSION['payername'], "Add Payer Details", $msgbody, "");
?>

If everything works fine, then both the payer and the owner will be receiving emails with the content you have specified above.

Conclusion

If you found this post useful, don’t forget to clap. Feel free to leave a comment if you face any issues during the process and also how you fixed them.

Signing off for now.

Arigato Gozaimasu 🙂

+1

122