From c0bf806836ea00671a1ca6bd857efc93dfb03ab3 Mon Sep 17 00:00:00 2001 From: Snehal Patil Date: Fri, 29 Sep 2017 18:26:00 +0530 Subject: [PATCH] Issue #111481 fix: PayFast - Submit button - Don't have a value for the button --- payfast/en-GB/en-GB.plg_payment_payfast.ini | 2 +- payfast/payfast.php | 408 +++++++++++++------- payfast/payfast/tmpl/default.php | 22 +- 3 files changed, 285 insertions(+), 147 deletions(-) diff --git a/payfast/en-GB/en-GB.plg_payment_payfast.ini b/payfast/en-GB/en-GB.plg_payment_payfast.ini index d7a3141..d15d451 100755 --- a/payfast/en-GB/en-GB.plg_payment_payfast.ini +++ b/payfast/en-GB/en-GB.plg_payment_payfast.ini @@ -15,7 +15,7 @@ PLG_PAYMENT_PAYFAST_SANDBOX_DESC="When enabled, all transactions will be perform PLG_PAYMENT_PAYFAST_NO="No" PLG_PAYMENT_PAYFAST_YES="Yes" PLG_PAYMENT_PAYFAST_PINFO="Payment For Order %s" - +PLG_PAYMENT_PAYFAST_SUBMIT="Pay Now" PLG_PAYMENT_PAYFAST_LOG="Log payment gateway responses" PLG_PAYMENT_PAYFAST_LOG_DESC="Turn this on only if payment not working correctly & you want do debug it." diff --git a/payfast/payfast.php b/payfast/payfast.php index 556ba5a..d7e8ffb 100755 --- a/payfast/payfast.php +++ b/payfast/payfast.php @@ -1,108 +1,162 @@ load('plg_payment_payfast', JPATH_ADMINISTRATOR); -class plgPaymentPayfast extends JPlugin + +/** + * plgPaymentPayfast + * + * @package CPG + * @subpackage site + * @since 2.2 + */ +class PlgPaymentPayfast extends JPlugin { private $validHosts = array( - 'www.payfast.co.za', - 'sandbox.payfast.co.za', - 'w1w.payfast.co.za', - 'w2w.payfast.co.za', - ); - function __construct(& $subject, $config) + 'www.payfast.co.za', + 'sandbox.payfast.co.za', + 'w1w.payfast.co.za', + 'w2w.payfast.co.za', + ); + + /** + * Constructor + * + * @param string &$subject subject + * + * @param string $config config + */ + public function __construct(& $subject, $config) { parent::__construct($subject, $config); - //Set the language in the class - $config = JFactory::getConfig(); + // Set the language in the class + $config = JFactory::getConfig(); - //Define Payment Status codes in payfast And Respective Alias in Framework - $this->responseStatus = array( - 'COMPLETE' => 'C', - 'ERROR' => 'E' - ); + // Define Payment Status codes in payfast And Respective Alias in Framework + $this->responseStatus = array('COMPLETE' => 'C', + 'ERROR' => 'E' + ); } - /* Internal use functions */ - function buildLayoutPath($layout) { + /** + * Build Layout path + * + * @param string $layout Layout name + * + * @since 2.2 + * + * @return string Layout Path + */ + public function buildLayoutPath($layout) + { $app = JFactory::getApplication(); - $core_file = dirname(__FILE__) . '/' . $this->_name . '/tmpl/default.php'; - $override = JPATH_BASE . '/' . 'templates' . '/' . $app->getTemplate() . '/html/plugins/' . $this->_type . '/' . $this->_name . '/' . $layout.'.php'; - if(JFile::exists($override)) + $core_file = dirname(__FILE__) . '/' . $this->_name . '/tmpl/default.php'; + $override = JPATH_BASE . '/' . 'templates' . '/' . $app->getTemplate() . '/html/plugins/' . + $this->_type . '/' . $this->_name . '/' . $layout . '.php'; + + if (JFile::exists($override)) { return $override; } else { - return $core_file; + return $core_file; } } - //Builds the layout to be shown, along with hidden fields. - function buildLayout($vars, $layout = 'default' ) + /** + * Build Layout path + * + * @param array $vars object + * @param string $layout Layout name + * + * @since 2.2 + * + * @return string Layout Path + */ + public function buildLayout($vars, $layout = 'default' ) { // Load the layout & push variables ob_start(); - $layout = $this->buildLayoutPath($layout); - include($layout); - $html = ob_get_contents(); - ob_end_clean(); + $layout = $this->buildLayoutPath($layout); + include $layout; + $html = ob_get_contents(); + ob_end_clean(); + return $html; } - // Used to Build List of Payment Gateway in the respective Components - function onTP_GetInfo($config) + /** + * Builds the layout to be shown, along with hidden fields. + * + * @param object $config Plugin config + * + * @since 2.2 + * + * @return mixed return plugin config object + */ + public function onTP_GetInfo($config) { - - if(!in_array($this->_name,$config)) + if (!in_array($this->_name, $config)) + { return; + } + $obj = new stdClass; - $obj->name = $this->params->get( 'plugin_name' ); + $obj->name = $this->params->get('plugin_name'); $obj->id = $this->_name; + return $obj; } - //Constructs the Payment form in case of On Site Payment gateways like Auth.net & constructs the Submit button in case of offsite ones like Payu + // Constructs the Payment form in case of On Site Payment gateways like Auth.net & constructs the Submit button in case of offsite ones like Payfast + /** - * RETURN PAY HTML FORM - * */ - function onTP_GetHTML($vars) + * Builds the layout to be shown, along with hidden fields. + * + * @param object $vars Data from component + * + * @since 2.2 + * + * @return string Layout Path + */ + public function onTP_GetHTML($vars) { - $plgPaymentPayfastHelper = new plgPaymentPayfastHelper(); + $plgPaymentPayfastHelper = new plgPaymentPayfastHelper; $vars->action_url = $plgPaymentPayfastHelper->buildPayfastUrl(); - //Take this receiver email address from plugin if component not provided it - $vars->merchant_id = $this->params->get('merchant_id',''); - $vars->merchant_key = $this->params->get('merchant_key',''); - //$this->preFormatingData($vars); // fomating on data - $html = $this->buildLayout($vars); + // Take this receiver email address from plugin if component not provided it + + $vars->merchant_id = $this->params->get('merchant_id', ''); + $vars->merchant_key = $this->params->get('merchant_key', ''); + + // $this->preFormatingData($vars); // fomating on data + $html = $this->buildLayout($vars); return $html; } - /* This function falls under STEP 3 of the Common Payment Gateway flow - * If Process on the post data from the payment and pass a fixed format data to component for further process - * - * @param $data array Post data from gateway to notify url - * @return associative array gateway specific fixed format data required by the component to process payment - * */ - function onTP_Processpayment($data,$vars = array()) + /** + * Adds a row for the first time in the db, calls the layout view + * + * @param object $data Data from component + * @param object $vars Component data + * + * @since 2.2 + * + * @return object processeddata + */ + public function onTP_Processpayment($data, $vars = array()) { $isValid = true; $error = array(); @@ -110,50 +164,61 @@ function onTP_Processpayment($data,$vars = array()) $error['desc'] = ''; $trxnstatus = ''; - // 1.Check IPN data for validity (i.e. protect against fraud attempt) + // 1.Check IPN data for validity (i.e. protect against fraud attempt) $isValid = $this->isValidIPN($data); - if(!$isValid){ + + if (!$isValid) + { $data['error'] = 'Invalid response received.'; } - //2. Check that merchant_id is correct - if($isValid ) { - if($this->getMerchantID() != $data['merchant_id']) { + // 2. Check that merchant_id is correct + if ($isValid ) + { + if ($this->getMerchantID() != $data['merchant_id']) + { $isValid = false; $data['error'] = "The received merchant_id does not match the one that was sent."; } } - //3.compare response order id and send order id in notify URL - if($isValid ) { - if(!empty($vars) && $data['custom_str1'] != $vars->order_id ) + + // 3.compare response order id and send order id in notify URL + if ($isValid ) + { + if (!empty($vars) && $data['custom_str1'] != $vars->order_id ) { $isValid = false; $trxnstatus = 'ERROR'; - $data['error'] = "ORDER_MISMATCH" . "Invalid ORDERID; notify order_is ". $vars->order_id .", and response ".$data['custom_str1']; + $data['error'] = "ORDER_MISMATCH" . "Invalid ORDERID; notify order_is " + . $vars->order_id . ", and response " . $data['custom_str1']; } } + // Check that the amount is correct - if($isValid ) { - if(!empty($vars)) + if ($isValid ) + { + if (!empty($vars)) { // Check that the amount is correct $order_amount = (float) $vars->amount; $return_resp['status'] = '0'; - $data['total_paid_amt'] = (float)$data['amount_gross']; + $data['total_paid_amt'] = (float) $data['amount_gross']; $epsilon = 0.01; - if(($order_amount - $data['total_paid_amt']) > $epsilon) + if (($order_amount - $data['total_paid_amt']) > $epsilon) { $trxnstatus = 'ERROR'; $isValid = false; - $data['error'] = "ORDER_AMOUNT_MISTMATCH - order amount= ".$order_amount . ' response order amount = '.$data['total_paid_amt']; + $data['error'] = "ORDER_AMOUNT_MISTMATCH - order amount= " + . $order_amount . ' response order amount = ' . $data['total_paid_amt']; } } } // Translaet Payment status - if($trxnstatus == 'ERROR'){ + if ($trxnstatus == 'ERROR') + { $newStatus = $this->translateResponse($trxnstatus); } else @@ -161,63 +226,88 @@ function onTP_Processpayment($data,$vars = array()) $newStatus = $this->translateResponse($data['payment_status']); } - // Fraud attempt? Do nothing more! - //if(!$isValid) return false; - + // *if(!$isValid) return false; + $data['status'] = $newStatus; - $data['status']=$newStatus; - - //Error Handling - $error=array(); + // Error Handling + $error = array(); $error['code'] = 'ERROR'; $error['desc'] = (isset($data['error'])?$data['error']:''); $result = array( - 'order_id'=>$data['custom_str1'], - 'transaction_id'=>$data['pf_payment_id'], - 'buyer_email'=>$data['email_address'], - 'status'=>$newStatus, - 'txn_type'=>'', - 'total_paid_amt'=>(float)$data['amount_gross'], - 'raw_data'=>$data, - 'error'=>$error , + 'order_id' => $data['custom_str1'], + 'transaction_id' => $data['pf_payment_id'], + 'buyer_email' => $data['email_address'], + 'status' => $newStatus, + 'txn_type' => '', + 'total_paid_amt' => (float) $data['amount_gross'], + 'raw_data' => $data, + 'error' => $error , ); + return $result; } - /** + + /** * Validates the incoming data. + * + * @param object $data return data + * + * @since 2.2 + * + * @return object processeddata */ private function isValidIPN($data) { // 1. Check valid host $validIps = array(); - foreach($this->validHosts as $validHost){ - //Returns a list of IPv4 addresses to which the Internet host specified by hostname resolves. + + foreach ($this->validHosts as $validHost) + { + // Returns a list of IPv4 addresses to which the Internet host specified by hostname resolves. $ips = gethostbynamel($validHost); - if($ips !== false) { + + if ($ips !== false) + { $validIps = array_merge($validIps, $ips); } } $validIps = array_unique($validIps); - if(!in_array($_SERVER['REMOTE_ADDR'], $validIps)) { - //return false; + + if (!in_array($_SERVER['REMOTE_ADDR'], $validIps)) + { + // Return false; } // 2. Check signature // Build returnString from 'm_payment_id' onwards and exclude 'signature' - foreach($data as $key => $val ) { - if($key == 'm_payment_id') $returnString = ''; - if(! isset($returnString)) continue; - if($key == 'signature') continue; - $returnString .= $key . '=' . urlencode($val) . '&'; + foreach ($data as $key => $val) + { + if ($key == 'm_payment_id') + { + $returnString = ''; + } + + if (!isset($returnString)) + { + continue; + } + + if ($key == 'signature') + { + continue; + } + + $returnString .= $key . '=' . urlencode($val) . '&'; } $returnString = substr($returnString, 0, -1); - if(md5($returnString) != $data['signature']) { + if (md5($returnString) != $data['signature']) + { return false; } @@ -229,37 +319,64 @@ private function isValidIPN($data) // Connect to server $fp = fsockopen($this->getCallbackURL(), 443, $errno, $errstr, 10); - if (!$fp) { + if (!$fp) + { // HTTP ERROR return false; - } else { - // Send command to server + } + else + { + // Send command to server fputs($fp, $header . $returnString); // Read the response from the server - while(! feof($fp)) { + while (! feof($fp)) + { $res = fgets($fp, 1024); - if (strcmp($res, "VALID") == 0) { + + if (strcmp($res, "VALID") == 0) + { fclose($fp); + return true; } } } fclose($fp); + return false; - } // end of isValidIPN + } - function translateResponse($payment_status){ - foreach($this->responseStatus as $key=>$value) + /** + * This function transalate the response got from payment getway + * + * @param object $payment_status payment_status + * + * @since 2.2 + * + * @return string value + */ + public function translateResponse($payment_status) + { + foreach ($this->responseStatus as $key => $value) + { + if ($key == $payment_status) { - if($key == $payment_status){ - return $value; - } + return $value; } - + } } - function onTP_Storelog($data) + + /** + * Store log + * + * @param array $data data. + * + * @since 2.2 + * @return list. + */ + public function onTP_Storelog($data) { $log_write = $this->params->get('log_write', '0'); @@ -268,41 +385,60 @@ function onTP_Storelog($data) $log = plgPaymentPayfastHelper::Storelog($this->_name, $data); } } - /* - @params $vars :: object - @return $vars :: formatted object - */ - function preFormatingData($vars) + + /** + * To preformat + * + * @param array $vars object + * + * @sice 2.2 + * + * @return formatted object + */ + public function preFormatingData($vars) { - foreach($vars as $key=>$value) + foreach ($vars as $key => $value) { - $vars->$key=trim($value); - if($key == 'amount') + $vars->$key = trim($value); + + if ($key == 'amount') + { $vars->$key = round($value); + } } } - /** + + /** * Gets the PayFast Merchant ID + * + * @sice 2.2 + * + * @return merchant ID */ - function getMerchantID() + public function getMerchantID() { - //$sandbox = $this->params->get('sandbox',0); - return trim($this->params->get('merchant_id','')); - + // $sandbox = $this->params->get('sandbox',0); + return trim($this->params->get('merchant_id', '')); } + /** * Gets the IPN callback URL + * + * @sice 2.2 + * + * @return merchant ID */ private function getCallbackURL() { - $sandbox = $this->params->get('sandbox',0); - if($sandbox) { + $sandbox = $this->params->get('sandbox', 0); + + if ($sandbox) + { return 'ssl://sandbox.payfast.co.za'; - } else { + } + else + { return 'ssl://www.payfast.co.za'; } } - - - } diff --git a/payfast/payfast/tmpl/default.php b/payfast/payfast/tmpl/default.php index 707b725..310e722 100755 --- a/payfast/payfast/tmpl/default.php +++ b/payfast/payfast/tmpl/default.php @@ -1,11 +1,11 @@ -item_name=JText::sprintf('PLG_PAYMENT_PAYFAST_PINFO',$vars->order_id); +//$vars->item_name=JText::sprintf('PLG_PAYMENT_PAYFAST_PINFO',$vars->order_id); $txnid=$vars->order_id; //$txnid = substr(hash('sha256', mt_rand() . microtime()), 0, 20); @@ -26,20 +26,20 @@ - - + + - - + + - + merchant_id). "&merchant_key=".urlencode($vars->merchant_key). "&return_url=".urlencode($return_url). "&cancel_url=".urlencode($cancel_url). "¬ify_url=".urlencode($notify_url). "&name_first=".urlencode($vars->user_firstname). @@ -52,7 +52,9 @@ // DOC LINK =https://www.payfast.co.za/help/integration ?> - +
+ +