Laravel

Paytm Js checkout with example

In this article, we will learn about how we can do a checkout using paytm js checkout, as I have seen many users facing difficulties in order to integrate the paytm js checkout.You can learn more about the paytm js checkout by using this link.

If you are looking for laravel paytm integration you can follow this link.

We are going to follow the below step in order to integrate paytm js checkout

  1. Create the developer account and save the keys
  2. Get the token
  3. Implement the js checkout with your code
  4. Test the integration

Step:1 Create the developer account

To create account as developer please click here.

After creating the Paytm account you need to take your API Credentials from Paytm, So after the login in the sidebar under developers you can see API keys. You have to click on that link to acquire your API credentials.

Step-2 Get the token

Now we need the token in order to to implement the paytm js checkout, so we have to initate transaction api to get this token and then we pass it to our javascript code on other side we will also the generate the checksum while doing this process.I am going to show you the php code example if you are looking for the other languages you can check here.

Create a file named as PaytmChecksum.php and add the below code into it.

/**
 * Paytm uses checksum signature to ensure that API requests and responses shared between your 
 * application and Paytm over network have not been tampered with. We use SHA256 hashing and 
 * AES128 encryption algorithm to ensure the safety of transaction data.
 *
 * @author     Lalit Kumar
 * @version    2.0
 * @link       https://developer.paytm.com/docs/checksum/#php
 */

class PaytmChecksum{

	private static $iv = "@@@@&&&&####$$$$";

	static public function encrypt($input, $key) {
		$key = html_entity_decode($key);

		if(function_exists('openssl_encrypt')){
			$data = openssl_encrypt ( $input , "AES-128-CBC" , $key, 0, self::$iv );
		} else {
			$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'cbc');
			$input = self::pkcs5Pad($input, $size);
			$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
			mcrypt_generic_init($td, $key, self::$iv);
			$data = mcrypt_generic($td, $input);
			mcrypt_generic_deinit($td);
			mcrypt_module_close($td);
			$data = base64_encode($data);
		}
		return $data;
	}

	static public function decrypt($encrypted, $key) {
		$key = html_entity_decode($key);
		
		if(function_exists('openssl_decrypt')){
			$data = openssl_decrypt ( $encrypted , "AES-128-CBC" , $key, 0, self::$iv );
		} else {
			$encrypted = base64_decode($encrypted);
			$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
			mcrypt_generic_init($td, $key, self::$iv);
			$data = mdecrypt_generic($td, $encrypted);
			mcrypt_generic_deinit($td);
			mcrypt_module_close($td);
			$data = self::pkcs5Unpad($data);
			$data = rtrim($data);
		}
		return $data;
	}

	static public function generateSignature($params, $key) {
		if(!is_array($params) && !is_string($params)){
			throw new Exception("string or array expected, ".gettype($params)." given");			
		}
		if(is_array($params)){
			$params = self::getStringByParams($params);			
		}
		return self::generateSignatureByString($params, $key);
	}

	static public function verifySignature($params, $key, $checksum){
		if(!is_array($params) && !is_string($params)){
			throw new Exception("string or array expected, ".gettype($params)." given");
		}
		if(isset($params['CHECKSUMHASH'])){
			unset($params['CHECKSUMHASH']);
		}
		if(is_array($params)){
			$params = self::getStringByParams($params);
		}		
		return self::verifySignatureByString($params, $key, $checksum);
	}

	static private function generateSignatureByString($params, $key){
		$salt = self::generateRandomString(4);
		return self::calculateChecksum($params, $key, $salt);
	}

	static private function verifySignatureByString($params, $key, $checksum){
		$paytm_hash = self::decrypt($checksum, $key);
		$salt = substr($paytm_hash, -4);
		return $paytm_hash == self::calculateHash($params, $salt) ? true : false;
	}

	static private function generateRandomString($length) {
		$random = "";
		srand((double) microtime() * 1000000);

		$data = "9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz!@#$&_";	

		for ($i = 0; $i < $length; $i++) {
			$random .= substr($data, (rand() % (strlen($data))), 1);
		}

		return $random;
	}

	static private function getStringByParams($params) {
		ksort($params);		
		$params = array_map(function ($value){
			return ($value !== null && strtolower($value) !== "null") ? $value : "";
	  	}, $params);
		return implode("|", $params);
	}

	static private function calculateHash($params, $salt){
		$finalString = $params . "|" . $salt;
		$hash = hash("sha256", $finalString);
		return $hash . $salt;
	}

	static private function calculateChecksum($params, $key, $salt){
		$hashString = self::calculateHash($params, $salt);
		return self::encrypt($hashString, $key);
	}

	static private function pkcs5Pad($text, $blocksize) {
		$pad = $blocksize - (strlen($text) % $blocksize);
		return $text . str_repeat(chr($pad), $pad);
	}

	static private function pkcs5Unpad($text) {
		$pad = ord($text[strlen($text) - 1]);
		if ($pad > strlen($text))
			return false;
		return substr($text, 0, -1 * $pad);
	}
}

Now another file as initiateTransaction.php and add the below code into it.

<?php
/*
* import checksum generation utility
* You can get this utility from https://developer.paytm.com/docs/checksum/
*/
require_once("PaytmChecksum.php");

$paytmParams = array();

$paytmParams["body"] = array(
    "requestType"   => "Payment",
    "mid"           => "YOUR_MID_HERE",
    "websiteName"   => "WEBSTAGING",
    "orderId"       => "ORDERID_98765",
    "callbackUrl"   => "https://merchant.com/callback",
    "txnAmount"     => array(
        "value"     => "1.00",
        "currency"  => "INR",
    ),
    "userInfo"      => array(
        "custId"    => "CUST_001",
    ),
);

/*
* Generate checksum by parameters we have in body
* Find your Merchant Key in your Paytm Dashboard at https://dashboard.paytm.com/next/apikeys 
*/
$checksum = PaytmChecksum::generateSignature(json_encode($paytmParams["body"], JSON_UNESCAPED_SLASHES), "YOUR_MERCHANT_KEY");

$paytmParams["head"] = array(
    "signature"    => $checksum
);

$post_data = json_encode($paytmParams, JSON_UNESCAPED_SLASHES);

/* for Staging */
$url = "https://securegw-stage.paytm.in/theia/api/v1/initiateTransaction?mid=YOUR_MID_HERE&orderId=ORDERID_98765";

/* for Production */
// $url = "https://securegw.paytm.in/theia/api/v1/initiateTransaction?mid=YOUR_MID_HERE&orderId=ORDERID_98765";

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json")); 
$response = curl_exec($ch);
print_r($response);

when you execute the above code,you will get the reponse like the below one.

{
    "head": {
        "responseTimestamp": "1526969112101",
        "version": "v1",
        "clientId": "C11",
        "signature": "TXBw50YPUKIgJd8gR8RpZuOMZ+csvCT7i0/YXmG//J8+BpFdY5goPBiLAkCzKlCkOvAQip/Op5aD6Vs+cNUTjFmC55JBxvp7WunZ45Ke2q0="
    },
    "body": {
        "resultInfo": {
            "resultStatus": "S",
            "resultCode": "0000",
            "resultMsg": "Success"
        },
        "txnToken": "fe795335ed3049c78a57271075f2199e1526969112097",
        "isPromoCodeValid": false,
        "authenticated": false
    }
}

From this code we need the tknToken which we will pass in our paytm js code.

Step-3 Implement the paytm js checkout

Now we will implement the paytm js script, in this step,I am going to create a file named as index.html and put all the code there, I will paytm js and css for the layout.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Demo Transaction with JS Checkout</title>
    <link rel="shortcut icon" type="image/png" href="https://developer.paytm.com/demo//static/images/icon.png?v=1.9" />
    <script type="application/javascript" src="https://developer.paytm.com/demo//static/js/jquery.min.js"></script>
    <link href="https://developer.paytm.com/demo//static/css/style.css?v=1.9" rel="stylesheet" />
    <script type="application/javascript"src="https://securegw-stage.paytm.in/merchantpgpui/checkoutjs/merchants/{your-mid}"></script>


</head>

<body>
    <header>
        <div class="header-container">
            <a href="https://developer.paytm.com/docs/">
                <div class="logo">
                    <span><img src="https://developer.paytm.com/demo//static/images/logo.png?v=1.9"
                            alt="paytm logo image" /></span>

                </div>
            </a>
        </div>

    </header>
    <div class="main-content">
        <div class="heading">
            <h1>Demo Transaction with JS Checkout</h1>
        </div>
        <div class="container">
            <div class="topitemDetailsBox">
                <h3 class="extra"> Shopping Cart : (1 item)</h3>
                <div class="itemDetailsBox">
                    <img src="https://developer.paytm.com/demo//static/images/shirt.png?v=1.8" alt="shirt">
                    <div class="item-discription">
                        <span class="itemHeading">Mock Formal Shirt</span>
                        <p class="star">
                            <span>&#9733;</span>
                            <span>&#9733;</span>
                            <span>&#9733;</span>
                            <span>&#9733;</span>
                            <span>&#9733;</span>
                        </p>
                        <p><b>Rs 1.00</b></p>
                        <p class="product-description extra">Paytm provides an end-to-end online payments solution. We
                            accept and validate
                            Internet payments via Credit Card, Debit Card, Net-Banking,
                            UPI and popular Wallets from the end customers in real-time.</p>
                    </div>
                </div>
            </div>
            <div class="topRightBox">
                <h3>Order Summary</h3>
                <div class="rightBox">
                    <div class="orderDetails">
                        <div class="orderSummaryBox">
                            <p class="itemprice extra"><span>Total MRP&nbsp;<b class="greyText">(Inclusive of all
                                        charges)</b></span><span>Rs 1.00</span></p>
                            <p class="itemprice extra"><span>Discount</span><span>Rs 0.00</span></p>
                            <p class="itemprice extra"><span>Shipping Charges</span>Rs 0.00<span></span></p>
                            <p class="itemprice"><span><b>Total Amount Payable</b></span><span><b>Rs 1.00</b></span></p>
                            <button class="button" id="paytmWithPaytm">Pay with Paytm</button>
                        </div>
                    </div>
                    <br>
                </div>
                <p class="grayText">*This is real transaction, and the money will be auto-refunded to your account in
                    4-5
                    days</p>
            </div>
            <!-- end of top right box -->
        </div>
    </div>


    <script type="text/javascript">
        //here we will pass txn token which you get from initate transaction api, the your orderId and and the amount
        document.getElementById("paytmWithPaytm").addEventListener("click", function () {
            onScriptLoad("1cc7b0347f1e49058d9fd21a31524e791632483261969", "1632482687285", "1.00");
        });

        function onScriptLoad(txnToken, orderId, amount) {
            var config = {
                "root": "",
                "flow": "DEFAULT",
                "merchant": {
                    "name": "XYZ Enterprises",
                    "logo": "https://developer.paytm.com/demo//static/images/merchant-logo.png?v=1.4"
                },
                "style": {
                    "headerBackgroundColor": "#8dd8ff",
                    "headerColor": "#3f3f40"
                },
                "data": {
                    "orderId": orderId,
                    "token": txnToken,
                    "tokenType": "TXN_TOKEN",
                    "amount": amount
                },
                "handler": {
                    "notifyMerchant": function (eventName, data) {
                        if (eventName == 'SESSION_EXPIRED') {
                            alert("Your session has expired!!");
                            location.reload();
                        }
                    }
                }
            };

            if (window.Paytm && window.Paytm.CheckoutJS) {
                // initialze configuration using init method
                window.Paytm.CheckoutJS.init(config).then(function onSuccess() {
                    console.log('Before JS Checkout invoke');
                    // after successfully update configuration invoke checkoutjs
                    window.Paytm.CheckoutJS.invoke();
                }).catch(function onError(error) {
                    console.log("Error => ", error);
                });
            }
        }
    </script>

    <footer>
        <div class="footer-bottom">
            <div class="lightBlue"></div>
            <div class="darkBlue"></div>
            <div class="linksdiv">
                <ul class="footerlinks">
                    <li><a href="https://paytm.com/about-us/our-policies/" target="_blank">Terms of Service</li></a>
                    </li>
                    <li><a href="https://paytm.com/about-us/our-policies/" target="_blank">Privacy Policy</a></li>
                </ul>
            </div>
            <div class="copyright footerlinks">
                <ul>
                    <li>© 2021, Codehunger Pvt. Ltd</li>
                </ul>
            </div>
        </div>
    </footer>
</body>

</html>

Step-4 Test the integration

Now we will test the integration, if every things goes well then you have the screen like the below one.when you click on the index.html file

paytm js checkout demo transaction page

when you click on the pay with paytm then the below screen will be executed, which means you have successfully integrated the paytm to your website.

paytm payment page

Shaiv Roy

Hy Myself shaiv roy, I am a passionate blogger and love to share ideas among people, I am having good experience with laravel, vue js, react, flutter and doing website and app development work from last 7 years.

Related Articles

3 Comments

  1. i want paytm js checkout upi payment mode when i use this code its not running
    “enablePaymentMode” => array(
     “mode” => “UPI”,
     “channels” => “UPIPUSH”,
      ),

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button