From 850825bd499e45378ec3dd255e5ecccbef7da8b3 Mon Sep 17 00:00:00 2001 From: Ng Chen Yaau Date: Tue, 24 Jul 2018 17:48:33 +0800 Subject: [PATCH] Update - Implement secret key feature. - Implement sandbox feature. --- .../admin/controller/payment/molpay.php | 53 ++- .../{english => en-gb}/payment/molpay.php | 18 +- .../payment/{op-alipay.jpg => op-alipay.png} | Bin .../admin/view/template/payment/molpay.tpl | 365 +++++++++--------- .../catalog/controller/payment/molpay.php | 178 +++++---- .../{english => en-gb}/payment/molpay.php | 9 +- .../catalog/model/payment/molpay.php | 8 + .../theme/default/template/payment/molpay.tpl | 2 +- dist/OpenCart2.0_Seamless_Plugin.zip | Bin 129828 -> 130345 bytes 9 files changed, 348 insertions(+), 285 deletions(-) rename OpenCart2.0_Seamless_Plugin/admin/language/{english => en-gb}/payment/molpay.php (80%) rename OpenCart2.0_Seamless_Plugin/admin/view/image/payment/{op-alipay.jpg => op-alipay.png} (100%) rename OpenCart2.0_Seamless_Plugin/catalog/language/{english => en-gb}/payment/molpay.php (90%) diff --git a/OpenCart2.0_Seamless_Plugin/admin/controller/payment/molpay.php b/OpenCart2.0_Seamless_Plugin/admin/controller/payment/molpay.php index 3e96ac1..1da8f4e 100644 --- a/OpenCart2.0_Seamless_Plugin/admin/controller/payment/molpay.php +++ b/OpenCart2.0_Seamless_Plugin/admin/controller/payment/molpay.php @@ -36,7 +36,8 @@ public function index() { $data['entry_mid'] = $this->language->get('entry_mid'); $data['entry_vkey'] = $this->language->get('entry_vkey'); - $data['entry_order_status'] = $this->language->get('entry_order_status'); + $data['entry_skey'] = $this->language->get('entry_skey'); + $data['entry_type'] = $this->language->get('entry_type'); $data['entry_completed_status'] = $this->language->get('entry_completed_status'); $data['entry_pending_status'] = $this->language->get('entry_pending_status'); $data['entry_failed_status'] = $this->language->get('entry_failed_status'); @@ -48,7 +49,9 @@ public function index() { $data['channel_list'] = $this->language->get('channel_list'); $data['help_vkey'] = $this->language->get('help_vkey'); - + $data['help_skey'] = $this->language->get('help_skey'); + $data['help_type'] = $this->language->get('help_type'); + $data['button_save'] = $this->language->get('button_save'); $data['button_cancel'] = $this->language->get('button_cancel'); @@ -70,6 +73,18 @@ public function index() { $data['error_vkey'] = ''; } + if (isset($this->error['skey'])) { + $data['error_skey'] = $this->error['skey']; + } else { + $data['error_skey'] = ''; + } + + if (isset($this->error['type'])) { + $data['error_type'] = $this->error['type']; + } else { + $data['error_type'] = ''; + } + $data['breadcrumbs'] = array(); $data['breadcrumbs'][] = array( @@ -102,10 +117,16 @@ public function index() { $data['molpay_vkey'] = $this->config->get('molpay_vkey'); } - if (isset($this->request->post['molpay_order_status_id'])) { - $data['molpay_order_status_id'] = $this->request->post['molpay_order_status_id']; + if (isset($this->request->post['molpay_skey'])) { + $data['molpay_skey'] = $this->request->post['molpay_skey']; + } else { + $data['molpay_skey'] = $this->config->get('molpay_skey'); + } + + if (isset($this->request->post['molpay_type'])) { + $data['molpay_type'] = $this->request->post['molpay_type']; } else { - $data['molpay_order_status_id'] = $this->config->get('molpay_order_status_id'); + $data['molpay_type'] = $this->config->get('molpay_type'); } if (isset($this->request->post['molpay_completed_status_id'])) { @@ -154,15 +175,11 @@ public function index() { //Load the data into variable - foreach($data['channel_list'] as $key=>$val) - { - if (isset($this->request->post['molpay_'.$key.'_status'])) - { - $data['molpay_'.$key.'_status'] = $this->request->post['molpay_'.$key.'_status']; - } - else - { - $data['molpay_'.$key.'_status'] = $this->config->get('molpay_'.$key.'_status'); + foreach ($data['channel_list'] as $key=>$val) { + if (isset($this->request->post['molpay_'.$key.'_status'])) { + $data["dbchannel_list"]['molpay_'.$key.'_status'] = $this->request->post['molpay_'.$key.'_status']; + } else { + $data["dbchannel_list"]['molpay_'.$key.'_status'] = $this->config->get('molpay_'.$key.'_status'); } } @@ -186,6 +203,14 @@ protected function validate() { $this->error['vkey'] = $this->language->get('error_vkey'); } + if (!$this->request->post['molpay_skey']) { + $this->error['skey'] = $this->language->get('error_skey'); + } + + if (!$this->request->post['molpay_type']) { + $this->error['type'] = $this->language->get('error_type'); + } + return !$this->error; } } diff --git a/OpenCart2.0_Seamless_Plugin/admin/language/english/payment/molpay.php b/OpenCart2.0_Seamless_Plugin/admin/language/en-gb/payment/molpay.php similarity index 80% rename from OpenCart2.0_Seamless_Plugin/admin/language/english/payment/molpay.php rename to OpenCart2.0_Seamless_Plugin/admin/language/en-gb/payment/molpay.php index 4f1a70c..b11fc0b 100644 --- a/OpenCart2.0_Seamless_Plugin/admin/language/english/payment/molpay.php +++ b/OpenCart2.0_Seamless_Plugin/admin/language/en-gb/payment/molpay.php @@ -4,12 +4,12 @@ * * @package Payment Gateway * @author MOLPay Technical Team - * @version 2.0 + * @version 2.0.1 */ // Versioning $_['molpay_ptype'] = "OpenCart"; -$_['molpay_pversion'] = "2.0"; +$_['molpay_pversion'] = "2.0.1"; // Heading $_['heading_title'] = 'MOLPay Malaysia Online Payment Gateway'; @@ -23,7 +23,8 @@ // Entry $_['entry_mid'] = 'MOLPay Merchant ID'; $_['entry_vkey'] = 'MOLPay Verify Key'; -$_['entry_order_status'] = 'Order Status'; +$_['entry_skey'] = 'MOLPay Secret Key'; +$_['entry_type'] = 'MOLPay Account Type'; $_['entry_completed_status'] = 'Completed Status'; $_['entry_pending_status'] = 'Pending Status'; $_['entry_failed_status'] = 'Failed Status'; @@ -52,18 +53,23 @@ 'credit3' => 'Multi Currency Credit Card', 'NGANLUONG' => 'NGANLUONG', 'crossborder' => 'Credit Card/ Debit Card (PayVision)', - 'PEXPLUS' => 'PEx+', - 'jompay' => 'JOMPay', + 'PEXPLUS' => 'PEx+', + 'jompay' => 'JOMPay', 'Cash-Esapay' => 'Cash Esapay', - 'alipay' => 'Alipay.com' + 'alipay' => 'Alipay.com' ); // Help $_['help_vkey'] = 'Please refer to your MOLPay Merchant Profile for this key.'; +$_['help_skey'] = 'Please refer to your MOLPay Merchant Profile for this key.'; +$_['help_type'] = 'Please choose your account type (Sandbox/Production)'; +$_['type'] = array(1=> "Production", 2=>"Sandbox"); // Error $_['error_permission'] = 'Warning: You do not have permission to modify MOLPay Malaysia Online Payment Gateway!'; $_['error_mid'] = 'MOLPay Merchant ID Required!'; $_['error_vkey'] = 'MOLPay Verify Key Required!'; +$_['error_skey'] = 'MOLPay Secret Key Required!'; +$_['error_type'] = 'MOLPay Account Type Required!'; $_['error_settings'] = 'MOLPay merchant id and verify key mismatch, contact support@molpay.com to assist.'; $_['error_status'] = 'Unable to connect MOLPay API.'; diff --git a/OpenCart2.0_Seamless_Plugin/admin/view/image/payment/op-alipay.jpg b/OpenCart2.0_Seamless_Plugin/admin/view/image/payment/op-alipay.png similarity index 100% rename from OpenCart2.0_Seamless_Plugin/admin/view/image/payment/op-alipay.jpg rename to OpenCart2.0_Seamless_Plugin/admin/view/image/payment/op-alipay.png diff --git a/OpenCart2.0_Seamless_Plugin/admin/view/template/payment/molpay.tpl b/OpenCart2.0_Seamless_Plugin/admin/view/template/payment/molpay.tpl index 497b8c4..6c1c971 100644 --- a/OpenCart2.0_Seamless_Plugin/admin/view/template/payment/molpay.tpl +++ b/OpenCart2.0_Seamless_Plugin/admin/view/template/payment/molpay.tpl @@ -1,189 +1,198 @@
- -
- -
- -
- -
-
-

-
-
-
-
- -
- -
-
-
- -
- - -
- -
-
-
- -
- - -
- -
-
-
- -
- -
-
-
- -
- + -
-
-
+
diff --git a/OpenCart2.0_Seamless_Plugin/catalog/controller/payment/molpay.php b/OpenCart2.0_Seamless_Plugin/catalog/controller/payment/molpay.php index e3b6430..3e2fd72 100644 --- a/OpenCart2.0_Seamless_Plugin/catalog/controller/payment/molpay.php +++ b/OpenCart2.0_Seamless_Plugin/catalog/controller/payment/molpay.php @@ -4,7 +4,7 @@ * * @package Payment Gateway * @author MOLPay Technical Team - * @version 2.0 + * @version 2.0.1 */ class ControllerPaymentMolpay extends Controller { @@ -15,18 +15,16 @@ public function index() { $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); - if (isset($this->session->data['guest'])) - { + if (isset($this->session->data['guest'])) { $email = $this->session->data['guest']['email']; $telephone = $this->session->data['guest']['telephone']; - } - else - { + } else { $email = $this->customer->getEmail(); $telephone = $this->customer->getTelephone(); } - $data['action'] = 'https://www.onlinepayment.com.my/MOLPay/pay/'.$this->config->get('molpay_mid').'/'; + $data['action'] = $this->config->get('molpay_type').'MOLPay/pay/'.$this->config->get('molpay_mid').'/'; + $data['js'] = $this->config->get('molpay_type')."/MOLPay/API/seamless/latest/js/MOLPay_seamless.deco.js"; $data['mid']= $this->config->get('molpay_mid'); $data['amount'] = $this->currency->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value'], false); $data['orderid'] = $this->session->data['order_id']; @@ -41,16 +39,15 @@ public function index() { $this->load->language('payment/molpay'); $channel_list = $this->language->get('channel_list'); - foreach($channel_list as $key=>$val) - { + foreach ($channel_list as $key=>$val) { $inGet = 'molpay_'.$key.'_status'; $data['channel_list'][$key] = $this->config->get($inGet); } $products = $this->cart->getProducts(); - foreach ($products as $product) { - $data['prod_desc'][]= $product['name']." x ".$product['quantity']; - } + foreach ($products as $product) { + $data['prod_desc'][]= $product['name']." x ".$product['quantity']; + } $data['lang'] = $this->session->data['language']; @@ -58,16 +55,13 @@ public function index() { $version_oc = substr(VERSION,0,3); - if($version_oc == "2.2") - { + if ($version_oc == "2.2") { if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/molpay.tpl')) { return $this->load->view($this->config->get('config_template') . '/template/payment/molpay.tpl', $data); } else { return $this->load->view('payment/molpay.tpl', $data); } - } - else - { + } else { if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/molpay.tpl')) { return $this->load->view($this->config->get('config_template') . '/template/payment/molpay.tpl', $data); } else { @@ -76,13 +70,16 @@ public function index() { } } + /***************************************************** + * Return with IPN(Instant Payment Notification) + ******************************************************/ public function return_ipn() { $this->load->model('checkout/order'); $order_info = $this->model_checkout_order->getOrder($this->request->post['orderid']); // orderid - $vkey = $this->config->get('molpay_vkey'); + $secretkey = $this->config->get('molpay_skey'); $_POST['treq']= 1; @@ -99,11 +96,11 @@ public function return_ipn() { /*********************************************************** * Backend acknowledge method for IPN (DO NOT MODIFY) ************************************************************/ - while ( list($k,$v) = each($_POST) ) { - $postData[]= $k."=".$v; - } + foreach ($_POST as $k => $v) { + $postData[]= $k."=".$v; + } $postdata = implode("&",$postData); - $url = "https://www.onlinepayment.com.my/MOLPay/API/chkstat/returnipn.php"; + $url = $this->config->get('molpay_type')."MOLPay/API/chkstat/returnipn.php"; $ch = curl_init(); curl_setopt($ch, CURLOPT_POST , 1); curl_setopt($ch, CURLOPT_POSTFIELDS , $postdata); @@ -112,7 +109,7 @@ public function return_ipn() { curl_setopt($ch, CURLINFO_HEADER_OUT , TRUE); curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , FALSE); - //curl_setopt($ch, CURLOPT_SSLVERSION , 3); + curl_setopt($ch, CURLOPT_SSLVERSION , 6); $result = curl_exec( $ch ); curl_close( $ch ); /*********************************************************** @@ -120,12 +117,10 @@ public function return_ipn() { ************************************************************/ $key0 = md5($tranID.$orderid.$status.$domain.$amount.$currency); - $key1 = md5($paydate.$domain.$key0.$appcode.$vkey); + $key1 = md5($paydate.$domain.$key0.$appcode.$secretkey); if ( $skey != $key1 ) $status = -1 ; - - $order_status_id = $this->config->get('config_order_status_id'); if ( $status == "00" ) { $order_status_id = $this->config->get('molpay_completed_status_id'); @@ -138,11 +133,12 @@ public function return_ipn() { } - if (!$order_info['order_status_id']) { - $this->model_checkout_order->addOrderHistory($orderid, $order_status_id); - } else { - $this->model_checkout_order->addOrderHistory($orderid, $order_status_id); + $response=array(); + foreach ($_POST as $k => $v) { + $response[] = "[".$k."]=".$v; } + if ($order_info['order_status_id'] != $this->config->get('molpay_completed_status_id')) + $this->model_checkout_order->addOrderHistory($orderid, $order_status_id, "RETURN URL \n".implode("\n ", $response), false, false); $successStatus = array('00','22'); if( in_array($status,$successStatus) ) { @@ -175,7 +171,7 @@ public function return_ipn() { public function callback_ipn() { $this->load->model('checkout/order'); - $vkey = $this->config->get('molpay_vkey'); + $secretkey = $this->config->get('molpay_skey'); $nbcb = (isset($_POST['nbcb']) && !empty($_POST['nbcb'])) ? $_POST['nbcb'] : ''; $tranID = (isset($_POST['tranID']) && !empty($_POST['tranID'])) ? $_POST['tranID'] : ''; @@ -189,35 +185,36 @@ public function callback_ipn() { $skey = (isset($_POST['skey']) && !empty($_POST['skey'])) ? $_POST['skey'] : ''; $key0 = md5($tranID.$orderid.$status.$domain.$amount.$currency); - $key1 = md5($paydate.$domain.$key0.$appcode.$vkey); + $key1 = md5($paydate.$domain.$key0.$appcode.$secretkey); if ( $skey != $key1 ) $status = -1 ; - if ($nbcb == 1) { - echo "CBTOKEN:MPSTATOK"; - $order_info = $this->model_checkout_order->getOrder($this->request->post['orderid']); // orderid - - - $order_status_id = $this->config->get('config_order_status_id'); - - if ( $status == "00" ) { - $order_status_id = $this->config->get('molpay_completed_status_id'); - - } elseif( $status == "22" ) { - $order_status_id = $this->config->get('molpay_pending_status_id'); - - } else { - $order_status_id = $this->config->get('molpay_failed_status_id'); - - } - - if (!$order_info['order_status_id']) { - $this->model_checkout_order->addOrderHistory($orderid, $order_status_id); - } else { - $this->model_checkout_order->addOrderHistory($orderid, $order_status_id); - } - } + $order_info = $this->model_checkout_order->getOrder($this->request->post['orderid']); // orderid + if ( $status == "00" ) { + $order_status_id = $this->config->get('molpay_completed_status_id'); + } elseif( $status == "22" ) { + $order_status_id = $this->config->get('molpay_pending_status_id'); + } else { + $order_status_id = $this->config->get('molpay_failed_status_id'); + } + + $response=array(); + foreach ($_POST as $k => $v) { + $response[] = "[".$k."]=".$v; + } + if ($order_info['order_status_id'] != $this->config->get('molpay_completed_status_id')) + $this->model_checkout_order->addOrderHistory($orderid, $order_status_id, "CALLBACK URL \n".implode("\n ", $response), false, false); + + /*********************************************************** + * Backend acknowledge method for IPN (DO NOT MODIFY) + ************************************************************/ + if ($nbcb == 1) { + echo "CBTOKEN:MPSTATOK";exit; + } + /*********************************************************** + * End of Acknowledge method for IPN + ************************************************************/ } /***************************************************** @@ -226,7 +223,7 @@ public function callback_ipn() { public function notification_ipn() { $this->load->model('checkout/order'); - $vkey = $this->config->get('molpay_vkey'); + $secretkey = $this->config->get('molpay_skey'); $nbcb = (isset($_POST['nbcb']) && !empty($_POST['nbcb'])) ? $_POST['nbcb'] : ''; $tranID = (isset($_POST['tranID']) && !empty($_POST['tranID'])) ? $_POST['tranID'] : ''; @@ -238,35 +235,54 @@ public function notification_ipn() { $appcode = (isset($_POST['appcode']) && !empty($_POST['appcode'])) ? $_POST['appcode'] : ''; $paydate = (isset($_POST['paydate']) && !empty($_POST['paydate'])) ? $_POST['paydate'] : ''; $skey = (isset($_POST['skey']) && !empty($_POST['skey'])) ? $_POST['skey'] : ''; + + /*********************************************************** + * Backend acknowledge method for IPN (DO NOT MODIFY) + ************************************************************/ + if ($nbcb == 2) { + foreach ($_POST as $k => $v) { + $postData[]= $k."=".$v; + } + $postdata = implode("&",$postData); + $url = $this->config->get('molpay_type')."MOLPay/API/chkstat/returnipn.php"; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_POST , 1); + curl_setopt($ch, CURLOPT_POSTFIELDS , $postdata); + curl_setopt($ch, CURLOPT_URL , $url); + curl_setopt($ch, CURLOPT_HEADER , 1); + curl_setopt($ch, CURLINFO_HEADER_OUT , TRUE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , FALSE); + curl_setopt($ch, CURLOPT_SSLVERSION , 6); + $result = curl_exec( $ch ); + curl_close( $ch ); + } + /*********************************************************** + * End of Acknowledge method for IPN + ************************************************************/ + $key0 = md5($tranID.$orderid.$status.$domain.$amount.$currency); - $key1 = md5($paydate.$domain.$key0.$appcode.$vkey); + $key1 = md5($paydate.$domain.$key0.$appcode.$secretkey); if ( $skey != $key1 ) $status = -1 ; + + $order_info = $this->model_checkout_order->getOrder($this->request->post['orderid']); // orderid - if ($nbcb == 2) { - echo "CBTOKEN:MPSTATOK"; - $order_info = $this->model_checkout_order->getOrder($this->request->post['orderid']); // orderid - - $order_status_id = $this->config->get('config_order_status_id'); - - if ( $status == "00" ) { - $order_status_id = $this->config->get('molpay_completed_status_id'); - - } elseif( $status == "22" ) { - $order_status_id = $this->config->get('molpay_pending_status_id'); - - } else { - $order_status_id = $this->config->get('molpay_failed_status_id'); - - } - - if (!$order_info['order_status_id']) { - $this->model_checkout_order->addOrderHistory($orderid, $order_status_id); - } else { - $this->model_checkout_order->addOrderHistory($orderid, $order_status_id); - } - } + if ( $status == "00" ) { + $order_status_id = $this->config->get('molpay_completed_status_id'); + } elseif( $status == "22" ) { + $order_status_id = $this->config->get('molpay_pending_status_id'); + } else { + $order_status_id = $this->config->get('molpay_failed_status_id'); + } + + $response=array(); + foreach ($_POST as $k => $v) { + $response[] = "[".$k."]=".$v; + } + if ($order_info['order_status_id'] != $this->config->get('molpay_completed_status_id')) + $this->model_checkout_order->addOrderHistory($orderid, $order_status_id, "NOTIFICATION URL \n".implode("\n ", $response), false, false); } } diff --git a/OpenCart2.0_Seamless_Plugin/catalog/language/english/payment/molpay.php b/OpenCart2.0_Seamless_Plugin/catalog/language/en-gb/payment/molpay.php similarity index 90% rename from OpenCart2.0_Seamless_Plugin/catalog/language/english/payment/molpay.php rename to OpenCart2.0_Seamless_Plugin/catalog/language/en-gb/payment/molpay.php index f0941fc..17dbf96 100644 --- a/OpenCart2.0_Seamless_Plugin/catalog/language/english/payment/molpay.php +++ b/OpenCart2.0_Seamless_Plugin/catalog/language/en-gb/payment/molpay.php @@ -4,7 +4,7 @@ * * @package Payment Gateway * @author MOLPay Technical Team - * @version 2.0 + * @version 2.0.1 */ // Text @@ -31,9 +31,8 @@ 'credit3' => 'Multi Currency Credit Card', 'NGANLUONG' => 'NGANLUONG', 'crossborder' => 'Credit Card/ Debit Card (PayVision)', - 'PEXPLUS' => 'PEx+', - 'jompay' => 'JOMPay', + 'PEXPLUS' => 'PEx+', + 'jompay' => 'JOMPay', 'Cash-Esapay' => 'Cash Esapay', - 'alipay' => 'Alipay.com' - + 'alipay' => 'Alipay.com' ); diff --git a/OpenCart2.0_Seamless_Plugin/catalog/model/payment/molpay.php b/OpenCart2.0_Seamless_Plugin/catalog/model/payment/molpay.php index fe50f77..d3f5dda 100644 --- a/OpenCart2.0_Seamless_Plugin/catalog/model/payment/molpay.php +++ b/OpenCart2.0_Seamless_Plugin/catalog/model/payment/molpay.php @@ -1,4 +1,12 @@ + * @version 2.0.1 + */ + class ModelPaymentMolpay extends Model { public function getMethod($address, $total) { $this->load->language('payment/molpay'); diff --git a/OpenCart2.0_Seamless_Plugin/catalog/view/theme/default/template/payment/molpay.tpl b/OpenCart2.0_Seamless_Plugin/catalog/view/theme/default/template/payment/molpay.tpl index 421016c..c50538c 100644 --- a/OpenCart2.0_Seamless_Plugin/catalog/view/theme/default/template/payment/molpay.tpl +++ b/OpenCart2.0_Seamless_Plugin/catalog/view/theme/default/template/payment/molpay.tpl @@ -12,7 +12,7 @@ " /> - +

Pay via:


diff --git a/dist/OpenCart2.0_Seamless_Plugin.zip b/dist/OpenCart2.0_Seamless_Plugin.zip index a6f40e8218075f306886beeac7c99b074d0d92c0..e13cb83fd125ed4a7c83e9a89ad4f47127daf4e5 100644 GIT binary patch delta 10473 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