Posted on / by Vivan Web Solution / in Symfony Development / 24 comments

Paytm Payment Gateway Integration with Symfony : Step by Step

In this tutorial we have explained Paytm Payment Gateway Integration in symfony. Paytm is the good choice for accepting payment online. It is safe, secure, and easy to integrate into website and mobile applications. Nowadays paytm is most popular and famous mobile wallet system. As per the company, over 7 million merchants across India use their QR code payment system to accept payments directly into their bank account.

Nowadays many ecommerce or other service websites start using Paytm payment gateway. Its also reduce the risk to exposing credit card details or banking password. Just send or receive payment via your Mobile Phone. So, no doubt Paytm is better service for online payment for your Website.

Benefits of using Paytm Payment Gateway

  1. Paytm accepts every mode of payment
    • Paytm Wallet
    • Bank account via UPI
    • Debit or Credit cards
    • Net Banking
    • EMI Option on cards
    • Paytm Postpaid
  2. Secure Payments
  3. Industry high success rate
  4. Checkout with saved cards
  5. Real-time bank settlements
  6. Business growth insights on Paytm Merchant Dashboard

Steps to Integrate Paytm Payment Gateway in PHP

Lets start the process of Paytm Payment Gateway Integration. Follow the below steps:

Step 1 : Register for Paytm Account

Sign Up for Paytm bussiness account from here :

https://paytm.com/business/payments/online

Step 2 : Configure Paytm Credential

Add following code in config.yml file.

parameters:

[php]

paytm_marchent_id: "YOUR_MERCHANT_ID"
paytm_marchent_key: "YOUR_MERCHANT_KEY"

[/php]

Step 3 : Create Paytm Integration Helper

Create helper into AppBundle->Helper->PaytmHelper.php
Add following code into PaytmHelper.php

[php]

<?php
namespace AppBundle\Helper;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\JsonResponse;
use AppBundle\Entity\User;

class PaytmHelper {

private $entityManager;
private $container;

public function __construct(EntityManager $entityManager, ContainerInterface $container, Session $session) {
$this->container = $container;
$this->entityManager = $entityManager;
$this->session = $session;
}

//All Functions of Paytm Integration
public function encrypt_e($input, $ky) {
$key = html_entity_decode($ky);
$iv = "@@@@&&&&####$$$$";
$data = openssl_encrypt ( $input , "AES-128-CBC" , $key, 0, $iv );
return $data;
}

public function decrypt_e($crypt, $ky) {
$key = html_entity_decode($ky);
$iv = "@@@@&&&&####$$$$";
$data = openssl_decrypt ( $crypt , "AES-128-CBC" , $key, 0, $iv );
return $data;
}

public function generateSalt_e($length) {
$random = "";
srand((double) microtime() * 1000000);

$data = "AbcDE123IJKLMN67QRSTUVWXYZ";
$data .= "aBCdefghijklmn123opq45rs67tuv89wxyz";
$data .= "0FGH45OP89";

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

return $random;
}

public function checkString_e($value) {
if ($value == ‘null’)
$value = ”;
return $value;
}

public function getChecksumFromArray($arrayList, $key, $sort=1) {
if ($sort != 0) {
ksort($arrayList);
}
$str = $this->getArray2Str($arrayList);
$salt = $this->generateSalt_e(4);
$finalString = $str . "|" . $salt;
$hash = hash("sha256", $finalString);
$hashString = $hash . $salt;
$checksum = $this->encrypt_e($hashString, $key);
return $checksum;
}

public function verifychecksum_e($arrayList, $key, $checksumvalue) {
$arrayList = $this->removeCheckSumParam($arrayList);
ksort($arrayList);
$str = $this->getArray2StrForVerify($arrayList);
$paytm_hash = $this->decrypt_e($checksumvalue, $key);
$salt = substr($paytm_hash, -4);

$finalString = $str . "|" . $salt;

$website_hash = hash("sha256", $finalString);
$website_hash .= $salt;

$validFlag = "FALSE";
if ($website_hash == $paytm_hash) {
$validFlag = "TRUE";
} else {
$validFlag = "FALSE";
}
return $validFlag;
}

public function getArray2Str($arrayList) {
$findme = ‘REFUND’;
$findmepipe = ‘|’;
$paramStr = "";
$flag = 1;
foreach ($arrayList as $value) {
$pos = strpos($value, $findme);
$pospipe = strpos($value, $findmepipe);
if ($pos !== false || $pospipe !== false)
{
continue;
}

if ($flag) {
$paramStr .= $this->checkString_e($value);
$flag = 0;
} else {
$paramStr .= "|" . $this->checkString_e($value);
}
}
return $paramStr;
}

public function getArray2StrForVerify($arrayList) {
$paramStr = "";
$flag = 1;
foreach ($arrayList as $key => $value) {
if ($flag) {
$paramStr .= $this->checkString_e($value);
$flag = 0;
} else {
$paramStr .= "|" . $this->checkString_e($value);
}
}
return $paramStr;
}

public function removeCheckSumParam($arrayList) {
if (isset($arrayList["CHECKSUMHASH"])) {
unset($arrayList["CHECKSUMHASH"]);
}
return $arrayList;
}

public function VerifierChecksum($request){
$data = $request->request->all();
$JsonData =json_encode($data);

$paytmChecksum = isset($data["CHECKSUMHASH"]) ? $data["CHECKSUMHASH"] : "";

$isValidChecksum = $this->verifychecksum_e($data, "&".$this->container->getParameter(‘paytm_marchent_key’), $paytmChecksum);

return $isValidChecksum;

}
}
[/php]

Step 4 : Create Paytm Entity

AppBundle->Entity->PaytmPayment.php

[php]</pre>
<?php

namespace DirectoryPlatform\AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* PaytmPayment
*
* @ORM\Table(name="directory_platform_paytm_payment")
* @ORM\Entity(repositoryClass="DirectoryPlatform\AppBundle\Repository\PaytmPaymentRepository")
*/
class PaytmPayment
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var int
*
* @ORM\Column(name="orderId", type="integer", length=255)
*/
private $orderId;

/**
* @var int
*
* @ORM\Column(name="userId", type="integer", length=255)
*/
private $userId;

/**
* @var int
*
* @ORM\Column(name="totalAmount", type="integer")
*/
private $totalAmount;

/**
* @var string
*
* @ORM\Column(name="currencyCode", type="string", length=255)
*/
private $currencyCode;

/**
* @var string
*
* @ORM\Column(name="clientEmail", type="string", length=255)
*/
private $clientEmail;

/**
* @var array
*
* @ORM\Column(name="description", type="json_array", length=255)
*/
private $description;

/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set orderId
*
* @param string $orderId
*
* @return PaytmPayment
*/
public function setOrderId($orderId)
{
$this->orderId = $orderId;

return $this;
}

/**
* Get orderId
*
* @return string
*/
public function getOrderId()
{
return $this->orderId;
}

/**
* Set userId
*
* @param string $userId
*
* @return PaytmPayment
*/
public function setUserId($userId)
{
$this->userId = $userId;

return $this;
}

/**
* Get userId
*
* @return string
*/
public function getUserId()
{
return $this->userId;
}

/**
* Set totalAmount
*
* @param integer $totalAmount
*
* @return PaytmPayment
*/
public function setTotalAmount($totalAmount)
{
$this->totalAmount = $totalAmount;

return $this;
}

/**
* Get totalAmount
*
* @return integer
*/
public function getTotalAmount()
{
return $this->totalAmount;
}

/**
* Set currencyCode
*
* @param string $currencyCode
*
* @return PaytmPayment
*/
public function setCurrencyCode($currencyCode)
{
$this->currencyCode = $currencyCode;

return $this;
}

/**
* Get currencyCode
*
* @return string
*/
public function getCurrencyCode()
{
return $this->currencyCode;
}

/**
* Set clientEmail
*
* @param string $clientEmail
*
* @return PaytmPayment
*/
public function setClientEmail($clientEmail)
{
$this->clientEmail = $clientEmail;

return $this;
}

/**
* {@inheritDoc}
*/
public function getClientEmail()
{
return $this->clientEmail;
}

/**
* {@inheritDoc}
*
* @param array|\Traversable $description
*/
public function setDescription($description)
{
if ($description instanceof \Traversable) {
$description = iterator_to_array($description);
}

$this->description = $description;
}

/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
}
<pre>?>
[/php]

Step 5 : Configure Order controller code

[php]</pre>
/**
* @Route("/accounts/checkout", name="checkout")
*/
public function checkoutAction(Request $request)
{
$baseurl = $request->getScheme() . ‘://’ . $request->getHttpHost() . $request->getBasePath();

// Calculate total price
$products = $request->getSession()->get(‘products’);
if (!$products) {
$this->addFlash(‘danger’, $this->get(‘translator’)->trans(‘Cart is empty. Not able to proceed checkout.’));

return $this->redirectToRoute(‘cart’);
}

$price = 0;
foreach ($products as $product) {
$price += $product[‘price’];
}

// Save order
if ($orderForm->isSubmitted() && $orderForm->isValid()) {
$order = $orderForm->getData();
$order->setStatus(Order::STATUS_NEW);
$order->setUser($this->getUser());
$order->setCurrency($this->getParameter(‘app.currency’));
$order->setPrice($price);

try {
$em = $this->getDoctrine()->getManager();
$em->persist($order);
$em->flush();
} catch (\Exception $e) {
$this->addFlash(‘danger’, $this->get(‘translator’)->trans(‘An error occurred whe saving order.’));
}

// Save order items
foreach ($products as $product) {
$listing = $this->getDoctrine()->getRepository(‘AppBundle:Listing’)->findOneBy([‘id’ => $product[‘listing_id’]]);

$orderItem = new OrderItem();
$orderItem->setOrder($order);
$orderItem->setPrice($product[‘price’]);
$orderItem->setType($product[‘type’]);
$orderItem->setListing($listing);
$orderItem->setDuration($product[‘duration’]);

try {
$em = $this->getDoctrine()->getManager();
$em->persist($orderItem);
$em->flush();
} catch (\Exception $e) {
$this->addFlash(‘danger’, $this->get(‘translator’)->trans(‘An error occurred whe saving order item.’));
}
}

$request->getSession()->remove(‘products’);
$this->addFlash(‘success’, $this->get(‘translator’)->trans(‘Order has been successfully saved.’));

$gatewayName = ‘paytm_standard_checkout’;

$storage = $this->get(‘payum’)->getStorage(Payment::class);

$payment = $storage->create();
$payment->setNumber(uniqid());
$payment->setCurrencyCode($this->getParameter(‘app.currency’));
$payment->setTotalAmount($price * 100);
$payment->setDescription(‘A description’);
$payment->setClientId($order->getUser()->getId());
$payment->setClientEmail($order->getUser()->getEmail());
$payment->setOrder($order);

$storage->update($payment);

$captureToken = $this->get(‘payum’)->getTokenFactory()->createCaptureToken($gatewayName, $payment, ‘paytmcheckout’);

$paytmParams = array(
"MID" => $this->container->getParameter(‘paytm_marchent_id’),
"WEBSITE" => "WEBSTAGING",
"INDUSTRY_TYPE_ID" => "Retail",
"CHANNEL_ID" => "WEB",
"ORDER_ID" => ($order->getId()),
"CUST_ID" => ($order->getUser()->getId()),
"EMAIL" => ($order->getUser()->getEmail()),
"TXN_AMOUNT" => ($price * 100),
"CALLBACK_URL" => $baseurl.$this->generateUrl(‘paytmcheckout’),
);

$checksum = $this->get(‘app.helper.paytm’)->getChecksumFromArray($paytmParams, "&".$this->container->getParameter(‘paytm_marchent_key’));

return $this->render(‘FrontBundle::Paytm/index.html.twig’,
[‘paytmParams’ => $paytmParams,
‘checksum’ => $checksum,
]);
}

return $this->render(‘FrontBundle::Order/checkout.html.twig’, [‘order’ => $orderForm->createView()]);
}

/**
* @Route("/accounts/paytmcheckout", name="paytmcheckout")
*/
//Paytm payment Response function and also use for databse entry.
public function paytmcheckoutAction(Request $request)
{
$token = $this->get(‘app.helper.paytm’)->VerifierChecksum($request);
$status = $request->request->get(‘STATUS’);
$orderId = $request->request->get(‘ORDERID’);

$order = $this->getDoctrine()->getRepository(‘AppBundle:Order’)->findOneBy(array(‘id’ => $orderId));

if($token == "TRUE") {
if ($status == "TXN_SUCCESS") {
$order->setStatus(Order::STATUS_COMPLETED);
$this->addFlash(‘success’, $this->get(‘translator’)->trans(‘Payment has been successful.’));
}else{
$order->setStatus(Order::STATUS_CANCELED);
$this->addFlash(‘danger’, $this->get(‘translator’)->trans(‘Payment has been Failed.’));
}
}else {
$order->setStatus(Order::STATUS_CANCELED);
$this->addFlash(‘danger’, $this->get(‘translator’)->trans(‘Payment has been Failed.’));
}

try {
$em = $this->getDoctrine()->getManager();
$em->persist($order);
$em->flush();
} catch (\Exception $e) {
$this->addFlash(‘danger’, $this->get(‘translator’)->trans(‘An error occurred when saving object.’));
}

return $this->redirectToRoute(‘order’);
}
<pre>
[/php]

Step 6 : Create twig file

[php]</pre>
{% extends ‘FrontBundle::Layout/base.html.twig’ %}

{% block content %}

<body>
<form method="post" action="https://securegw-stage.paytm.in/order/process" name="f1">
<table border="1">
<tbody>

{% for keyVal, paytmParam in paytmParams %}
<input type="hidden" name="{{ keyVal }}" value="{{ paytmParam }}">
{% endfor %}
<input type="hidden" name="CHECKSUMHASH" value="{{ checksum }}">
</tbody>
</table>
<script type="text/javascript">
document.f1.submit();
</script>
</form>
</body>
{% endblock %}
<pre>
[/php]

Conclusion: I hope this tutorial helpful for you, if you have any issue with integration, please comment below.

Thank You!

24 thoughts

Leave a Reply