<?php
/*
Documentation: https://goo.gl/w3kKoH
*/
require_once dirname( __FILE__ ).'/base.addon.php';

if( !class_exists( 'CPABC_PayTM' ) )
{
    class CPABC_PayTM extends CPABC_BaseAddon
    {
       
        /************* ADDON SYSTEM - ATTRIBUTES AND METHODS *************/
		protected $addonID = "addon-paytm-20160706";
		protected $name = "PayTM Payment Gateway";
		protected $description;
		
		public function get_addon_form_settings( $form_id )
		{
			global $wpdb;			
			// Insertion in database
			if( 
				isset( $_REQUEST[ 'cpabc_paytm_id' ] )
			)
			{

			    $wpdb->delete( $wpdb->prefix.$this->form_table, array( 'formid' => $form_id ), array( '%d' ) );
				$wpdb->insert( 	
								$wpdb->prefix.$this->form_table, 
								array( 
									'formid' => $form_id,
									'paytm_api_username'	 => $_REQUEST["paytm_api_username"],
									'paytm_api_password'	 => $_REQUEST["paytm_api_password"],																		
									'paytm_api_web'	 => $_REQUEST["paytm_api_web"],																		
									'paytm_api_industry' => $_REQUEST["paytm_api_industry"],																		
									'enabled'	 => $_REQUEST["paytm_enabled"],
									'paypal_mode'	 => $_REQUEST["paytm_mode"]
								), 
								array( '%d', '%s', '%s','%s', '%s', '%s', '%s' ) 
							);					
			}		

			
			$rows = $wpdb->get_results( 
						$wpdb->prepare( "SELECT * FROM ".$wpdb->prefix.$this->form_table." WHERE formid=%d", $form_id ) 
					);
			if (!count($rows))
			{
			    $row["paytm_api_username"] = "";
			    $row["paytm_api_password"] = "";
			    $row["paytm_api_web"] = "";			    
			    $row["paytm_api_industry"] = "";			    
			    $row["enabled"] = "0";
			    $row["paypal_mode"] = "production";
			} else {
			    $row["paytm_api_username"] = $rows[0]->paytm_api_username;
			    $row["paytm_api_password"] = $rows[0]->paytm_api_password;			    
			    $row["paytm_api_web"] = $rows[0]->paytm_api_web;			
			    $row["paytm_api_industry"] = $rows[0]->paytm_api_industry;						        
			    $row["enabled"] = $rows[0]->enabled;
			    $row["paypal_mode"] = $rows[0]->paypal_mode;
			}   
			
			?>
			<div id="metabox_basic_settings" class="postbox" >			
				<h3 class='hndle' style="padding:5px;"><span><?php print $this->name; ?></span></h3>
				<div class="inside"> 
				   <input type="hidden" name="cpabc_paytm_id" value="1" />
                   <table class="form-table">
                    <tr valign="top">        
                    <th scope="row"><?php _e('Enable PayTM? (if enabled PayPal Standard is disabled)', 'cpabc'); ?></th>
                    <td><select name="paytm_enabled">
                         <option value="0" <?php if (!$row["enabled"]) echo 'selected'; ?>><?php _e('No', 'cpabc'); ?></option>
                         <option value="1" <?php if ($row["enabled"]) echo 'selected'; ?>><?php _e('Yes', 'cpabc'); ?></option>
                         </select> 
                    </td>
                    </tr>   
                    <tr valign="top">        
                    <th scope="row"><?php _e('Merchant ID', 'cpabc'); ?></th>
                    <td><input type="text" name="paytm_api_username" size="20" value="<?php echo esc_attr($row["paytm_api_username"]); ?>" /><br />
                        <em>Change this value with MID (Merchant ID) received from Paytm<em></td>
                    </tr>   
                    <tr valign="top">        
                    <th scope="row"><?php _e('Merchant Key', 'cpabc');?></th>
                    <td><input type="text" name="paytm_api_password" size="40" value="<?php echo esc_attr($row["paytm_api_password"]); ?>" /><br />
                        <em>Change this value with Merchant key downloaded from portal</em></td>
                    </tr>                                           
                    <tr valign="top">        
                    <th scope="row"><?php _e('Website Name', 'cpabc');?></th>
                    <td><input type="text" name="paytm_api_web" size="40" value="<?php echo esc_attr($row["paytm_api_web"]); ?>" /><br />
                        <em>Change this value with Website name received from Paytm</em></td>
                    </tr>                                                               
                    <tr valign="top">        
                    <th scope="row"><?php _e('Industry Type ID', 'cpabc');?></th>
                    <td><input type="text" name="paytm_api_industry" size="40" value="<?php echo esc_attr($row["paytm_api_industry"]); ?>" /><br />
                        <em>Change this value with INDUSTRY_TYPE_ID value received from Paytm</em></td>
                    </tr>         
                    <tr valign="top">        
                    <th scope="row"><?php _e('Mode', 'cpabc');  ?></th>
                    <td><select name="paytm_mode">
                         <option value="production" <?php if ($row["paypal_mode"] != 'sandbox') echo 'selected'; ?>><?php _e('Production - real payments processed', 'cpabc'); ?></option> 
                         <option value="sandbox" <?php if ($row["paypal_mode"] == 'sandbox') echo 'selected'; ?>><?php _e('SandBox - Testing sandbox area', 'cpabc'); ?></option> 
                        </select>
                    </td>
                    </tr>                    
                   </table>  
				</div>
			</div>	
			<?php
		} // end get_addon_form_settings
		

		
		/************************ ADDON CODE *****************************/
		
        /************************ ATTRIBUTES *****************************/    
        
        private $form_table = 'cpabc_form_paytm';        
        private $_inserted = false;
        
        /************************ CONSTRUCT *****************************/
		
        function __construct()
        {
			$this->description = __("The add-on adds support for PayTM payments", 'cpabc' );
            // Check if the plugin is active
			if( !$this->addon_is_active() ) return;
			
			add_action( 'cpabc_process_data', array( &$this, 'pp_paytm' ), 1, 2 );						

			add_action( 'init', array( &$this, 'pp_paytm_update_status' ), 10, 1 );
			
			add_filter( 'cpabc_get_option', array( &$this, 'get_option' ), 10, 3 );					
			
            $this->update_database();
			
        } // End __construct
        

        
        /************************ PRIVATE METHODS *****************************/
        
		/**
         * Create the database tables
         */
        protected function update_database()
		{
			global $wpdb;			
			$sql = "CREATE TABLE IF NOT EXISTS ".$wpdb->prefix.$this->form_table." (
					id mediumint(9) NOT NULL AUTO_INCREMENT,
					formid INT NOT NULL,
					enabled varchar(10) DEFAULT '0' NOT NULL ,
					paytm_api_username varchar(255) DEFAULT '' NOT NULL ,
					paytm_api_password varchar(255) DEFAULT '' NOT NULL ,					
					paytm_api_web varchar(255) DEFAULT '' NOT NULL ,					
					paytm_api_industry varchar(255) DEFAULT '' NOT NULL ,					
					paypal_mode varchar(255) DEFAULT '' NOT NULL ,				
					UNIQUE KEY id (id)
				);";
				//  paytm_api_signature varchar(255) DEFAULT '' NOT NULL ,
				//	currency varchar(255) DEFAULT '' NOT NULL ,
				
			$wpdb->query($sql);
		} // end update_database		        	
        
        
		/************************ PUBLIC METHODS  *****************************/                               

               
		/**
         * process payment
         */		
		public function pp_paytm($params)
		{               
            global $wpdb;						
					
			// documentation: https://goo.gl/w3kKoH                     
           
            $rows = $wpdb->get_results( 
						$wpdb->prepare( "SELECT * FROM ".$wpdb->prefix.$this->form_table." WHERE formid=%d", $params["formid"] ) 
					);
			if (!$rows[0]->enabled)		
			    return;			    
            
            $checkSum = "";
            $paramList = array();
            
            $CUST_ID = $_POST["CUST_ID"];
            $INDUSTRY_TYPE_ID = $_POST["INDUSTRY_TYPE_ID"];
            $CHANNEL_ID = $_POST["CHANNEL_ID"];
            $TXN_AMOUNT = $_POST["TXN_AMOUNT"];
            
            // Create an array having all required parameters for creating checksum.
            $paramList["REQUEST_TYPE"] = 'DEFAULT';
            $paramList["MID"] = $rows[0]->paytm_api_username;
            $paramList["ORDER_ID"] = $params[ 'itemnumber' ];
            $paramList["CUST_ID"] = $params[ 'itemnumber' ];
            $paramList["INDUSTRY_TYPE_ID"] = $rows[0]->paytm_api_industry;
            $paramList["CHANNEL_ID"] = "WEB";
            $paramList["TXN_AMOUNT"] = $params["PRICE"];
            $paramList["WEBSITE"] = $rows[0]->paytm_api_web;
            $paramList["CALLBACK_URL"] = (cpabc_appointment_get_FULL_site_url().'/?cpabc_paytm_ipncheck=1&itemnumber='.$params["itemnumber"]);
            
            
            $paramList["MOBILE_NO"] = ""; //Mobile number of customer
            $paramList["EMAIL"] = $params["useremail"]; //Email ID of customer
            /**
            $paramList["VERIFIED_BY"] = "EMAIL"; //
            $paramList["IS_USER_VERIFIED"] = "YES"; //
            
            */
            
            //Here checksum string will return by getChecksumFromArray() function.
            $paytm = new CPABC_PayTMAPI($rows[0]->paytm_api_password, ($rows[0]->paypal_mode == 'sandbox'?'TEST':'PROD'));                       
            $checkSum = $paytm->getChecksumFromArray($paramList,$rows[0]->paytm_api_password);
                        
?>
<html>
<body>
<form method="post" action="<?php echo $paytm->getTxnURL() ?>" name="f1">	
			<?php
			foreach($paramList as $name => $value) {
				echo '<input type="hidden" name="' . $name .'" value="' . $value . '">';
			}
			?>
			<input type="hidden" name="CHECKSUMHASH" value="<?php echo $checkSum ?>">										
	</form>
	<script type="text/javascript">
			document.f1.submit();
	</script>
</body>
<?php            
            
            

            exit;   
		} // end pp_paytm               
		
		
		/**
		 * mark the item as paid
		 */
		private function _log($adarray = array())
		{
			$h = fopen( __DIR__.'/logs.txt', 'a' );
			$log = "";
			foreach( $_REQUEST as $KEY => $VAL )
			{
				$log .= $KEY.": ".$VAL."\n";
			}
			foreach( $adarray as $KEY => $VAL )
			{
				$log .= $KEY.": ".$VAL."\n";
			}
			$log .= "================================================\n";
			fwrite( $h, $log );
			fclose( $h );
		}
		
		public function pp_paytm_update_status( )
		{
            global $wpdb;      
            if ( !isset( $_GET['cpabc_paytm_ipncheck'] ) || $_GET['cpabc_paytm_ipncheck'] != '1' || !isset( $_GET["itemnumber"] ) )
                return;
                
            $itemnumber = explode(";",$_GET["itemnumber"]);            
            $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_TABLE_NAME." WHERE id=".intval($itemnumber[0]) );            
            $rows = $wpdb->get_results( 
						$wpdb->prepare( "SELECT * FROM ".$wpdb->prefix.$this->form_table." WHERE formid=%d", $myrows[0]->calendar ) 
					);		                    
            
            $paytm = new CPABC_PayTMAPI($rows[0]->paytm_api_password, ($rows[0]->paypal_mode == 'sandbox'?'TEST':'PROD'));                                               
            $ORDER_ID = $_POST["ORDER_ID"];
		    // Create an array having all required parameters for status query.
		    $requestParamList = array("MID" => PAYTM_MERCHANT_MID , "ORDERID" => $ORDER_ID);  
		    // Call the PG's getTxnStatus() function for verifying the transaction status.
		    $responseParamList = $paytm->getTxnStatus($requestParamList);

            // log data  
            $myrows1 = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_TABLE_NAME." WHERE id=".intval($itemnumber[0]) );
            $sql="UPDATE ".CPABC_APPOINTMENTS_TABLE_NAME." set question = '".$myrows1[0]->question
                 ."\n\nPayTM_ResponseCode:".$responseParamList["RESPCODE"]
                 ."\n\nPayTM_TXNID:".$responseParamList["TXNID"]
                 ."\n\nPayTM_ORDERID:".$responseParamList["ORDERID"]
                 ."' WHERE id=".intval($itemnumber[0]);            
            $wpdb->query($sql);		            
			
			if ($responseParamList["RESPCODE"] != '01')  // transaction failed
			    return;

            $location = cpabc_get_option('url_ok', CPABC_APPOINTMENTS_DEFAULT_OK_URL);            
            $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_TDEAPP_CALENDAR_DATA_TABLE." WHERE reference='".intval($itemnumber[0])."'" );
            if (count($myrows))
            {
                //echo 'OK - Already processed';
                header("Location: ".$location);		
                exit;
            }            
            cpabc_process_ready_to_go_appointment($_GET["itemnumber"]);            
            //echo 'OK';
            header("Location: ".$location);
    	        
            exit();              
              
		}

               
		/**
		 * Used to deactivate PayPal Standard if PayPal Pro is enabled for the form
		 */
		public function get_option( $value, $field, $id )
		{
			if( $field == 'enable_paypal' )
			{
			    global $wpdb;
			    $rows = $wpdb->get_results( 
						$wpdb->prepare( "SELECT enabled FROM ".$wpdb->prefix.$this->form_table." WHERE formid=%d", $id ) 
					);
			    if ( !empty( $rows ) && $rows[0]->enabled)
				    $value = 0;
			}	
			return $value;
		} // End get_option		
				              	          		        			
		
		
    } // End Class
    
    // Main add-on code
    $cpabc_paytm_obj = new CPABC_PayTM();
    
	// Add addon object to the objects list
	global $cpabc_addons_objs_list;
	$cpabc_addons_objs_list[ $cpabc_paytm_obj->get_addon_id() ] = $cpabc_paytm_obj;
}

if( !class_exists( 'CPABC_PayTMAPI' ) )
{
    
    class CPABC_PayTMAPI {
        
        private $PAYTM_DOMAIN;
        private $PAYTM_REFUND_URL;
        private $PAYTM_STATUS_QUERY_URL;
        private $PAYTM_TXN_URL;
        
        private $PAYTM_MERCHANT_KEY;        
        
        /**
         * Constructor
         */
        public function __construct($key, $mode = "PROD")
        {
            $this->PAYTM_MERCHANT_KEY = $key;
            
            $this->PAYTM_DOMAIN = "pguat.paytm.com";
            if ($mode == 'PROD')
                $this->PAYTM_DOMAIN = 'secure.paytm.in';
            $this->PAYTM_REFUND_URL = 'https://'.$this->PAYTM_DOMAIN.'/oltp/HANDLER_INTERNAL/REFUND';
            $this->PAYTM_STATUS_QUERY_URL = 'https://'.$this->PAYTM_DOMAIN.'/oltp/HANDLER_INTERNAL/TXNSTATUS';
            $this->PAYTM_TXN_URL = 'https://'.$this->PAYTM_DOMAIN.'/oltp-web/processTransaction';                
        }
        
        public function getTxnURL() 
        {
            return $this->PAYTM_TXN_URL;
        }

        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 pkcs5_pad_e($text, $blocksize) {
        	$pad = $blocksize - (strlen($text) % $blocksize);
        	return $text . str_repeat(chr($pad), $pad);
        }
        
        public function pkcs5_unpad_e($text) {
        	$pad = ord($text{strlen($text) - 1});
        	if ($pad > strlen($text))
        		return false;
        	return substr($text, 0, -1 * $pad);
        }
        
        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) {
        	$myvalue = ltrim($value);
        	$myvalue = rtrim($myvalue);
        	if ($myvalue == 'null')
        		$myvalue = '';
        	return $myvalue;
        }
        
        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->getArray2Str($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) {
        	$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 redirect2PG($paramList, $key) {
        	$hashString = getchecksumFromArray($paramList);
        	$checksum = $this->encrypt_e($hashString, $key);
        }
        
        public function removeCheckSumParam($arrayList) {
        	if (isset($arrayList["CHECKSUMHASH"])) {
        		unset($arrayList["CHECKSUMHASH"]);
        	}
        	return $arrayList;
        }
        
        public function getTxnStatus($requestParamList) {
        	return $this->callAPI($this->PAYTM_STATUS_QUERY_URL, $requestParamList);
        }
        
        public function initiateTxnRefund($requestParamList) {
        	$CHECKSUM = $this->getChecksumFromArray($requestParamList,$this->PAYTM_MERCHANT_KEY,0);
        	$requestParamList["CHECKSUM"] = $CHECKSUM;
        	return $this->callAPI($this->PAYTM_REFUND_URL, $requestParamList);
        }
        
        public function callAPI($apiURL, $requestParamList) {
        	$jsonResponse = "";
        	$responseParamList = array();
        	$JsonData =json_encode($requestParamList);
        	$postData = 'JsonData='.urlencode($JsonData);
        	$ch = curl_init($apiURL);
        	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
        	curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);                                                                  
        	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        	curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
        	curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
        	curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                         
        	'Content-Type: application/json', 
        	'Content-Length: ' . strlen($postData))                                                                       
        	);  
        	$jsonResponse = curl_exec($ch);   
        	$responseParamList = json_decode($jsonResponse,true);
        	return $responseParamList;
        }

    }

}

?>