From 3eeb71bf6956bd921ca1dc196d65f6a51cae4d03 Mon Sep 17 00:00:00 2001 From: htdat Date: Mon, 17 Apr 2017 21:46:56 +0700 Subject: [PATCH 01/18] The skeleton files for OnePay Domestic --- inc/class-wooviet-onepay-domestic.php | 86 +++++++++++++++++++++++++++ inc/onepay/domestic-settings.php | 71 ++++++++++++++++++++++ woo-viet.php | 13 ++++ 3 files changed, 170 insertions(+) create mode 100644 inc/class-wooviet-onepay-domestic.php create mode 100644 inc/onepay/domestic-settings.php diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php new file mode 100644 index 0000000..8a6666b --- /dev/null +++ b/inc/class-wooviet-onepay-domestic.php @@ -0,0 +1,86 @@ +id = 'wooviet_onepay_domestic'; + $this->has_fields = false; + $this->order_button_text = __( 'Proceed to OnePay', 'woo-viet' ); + $this->method_title = __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ); + // @todo - check the method description + $this->method_description = __( 'OnePay supports all major bank ATMs in Vietnam.', 'woo-viet' ); + $this->supports = array( + 'products', + ); + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->merchant_id = $this->get_option( 'merchant_id' ); + $this->access_code = $this->get_option( 'access_code' ); + $this->secure_secret = $this->get_option( 'secure_secret' ); + + // @todo: the sandbox option + + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + } + /** + * Initialise Gateway Settings Form Fields. + */ + public function init_form_fields() { + $this->form_fields = include( 'onepay/domestic-settings.php' ); + } + /** + * Process the payment. + */ + public function process_payment( $order_id ) { + $order = wc_get_order( $order_id ); + return array( + 'result' => 'success', + 'redirect' => $this->get_pay_url( $order ) + ); + } + /** + * Get the OnePay pay URL for an order. + * @param WC_Order $order + * @return string + */ + public function get_pay_url ( $order ) { + $access_key = $this->access_key; + $secret = $this->secret; // require your secret key from 1pay + $return_url = $this->get_1pay_return_url(); + $command = 'request_transaction'; + $amount = $order->get_total(); // >10000 + $order_id = $order->id; + $order_info = sprintf( 'The payment for the order number %1$s on the site: %2$s', $order->id, get_home_url()); + + // @todo: review and see the file do.php in the demo files + + } + + // @todo review this function + /* + public function static get_return_url(){ + return WC()->api_request_url( __CLASS__ ); + } + */ +} diff --git a/inc/onepay/domestic-settings.php b/inc/onepay/domestic-settings.php new file mode 100644 index 0000000..baa53d4 --- /dev/null +++ b/inc/onepay/domestic-settings.php @@ -0,0 +1,71 @@ + array( + 'title' => __( 'Enable/Disable', 'woo-viet' ), + 'type' => 'checkbox', + 'label' => __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ), + 'default' => 'yes' + ), + 'title' => array( + 'title' => __( 'Title', 'woo-viet' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woo-viet' ), + 'default' => __( 'OnePay Domestic Gateway', 'woo-viet' ), + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __( 'Description', 'woo-viet' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => __( 'This controls the description which the user sees during checkout.', 'woo-viet' ), + 'default' => __( 'With OnePay Bank, you can make payment by using any local Vietnam ATM card.', 'woo-viet' ) + ), + 'api_details' => array( + 'title' => __( 'API Credentials', 'woo-viet' ), + 'type' => 'title', + 'description' => sprintf( __( 'Enter your OnePay API credentials. Contact OnePay to have your credentials %shere%s.', 'woo-viet' ), '', '' ), + ), + 'merchant_id' => array( + 'title' => __( 'Merchant ID', 'woo-viet' ), + 'type' => 'text', + 'description' => __( 'Get your Merchant ID from OnePay.', 'woo-viet' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) + ), + 'access code' => array( + 'title' => __( 'Access Code', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your Access Code from from OnePay.', 'woo-viet' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) + ), + 'secure_secret' => array( + 'title' => __( 'Secure Secret', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your Secure Secret from from OnePay.', 'woo-viet' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) + ), + /* + // @todo: Add more help info later + + 'help_title' => array( + 'title' => __( 'More info about 1Pay', 'woo-viet' ), + 'type' => 'title', + 'description' => __( 'You can see more info at this link.', 'woo-viet' ) + ), + */ + +); \ No newline at end of file diff --git a/woo-viet.php b/woo-viet.php index e056150..2b4b469 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -119,11 +119,24 @@ class WooViet { load_plugin_textdomain( 'woo-viet', false, basename( dirname( __FILE__ ) ) . '/languages/' ); } + + public function add_gateway_class( $methods ) { + $methods[] = 'WooViet_OnePay_Domestic'; + return $methods; + + } + /** * The main method to load the components */ public function main() { + // @todo: ver 1.3 check this + add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) ); + + include( 'inc/class-wooviet-onepay-domestic.php'); + + if ( is_admin() ) { // Add the admin setting page include( WOO_VIET_DIR . 'inc/class-wooviet-admin-page.php' ); From 5f43aeb47daccab76f189e38541c43c9a8ef797b Mon Sep 17 00:00:00 2001 From: htdat Date: Tue, 18 Apr 2017 10:06:25 +0700 Subject: [PATCH 02/18] Finish: Build the payment URL --- inc/class-wooviet-onepay-domestic.php | 81 ++++++++++++++++++++++----- inc/onepay/domestic-settings.php | 11 +++- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index 8a6666b..a10bbf4 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -1,5 +1,4 @@ title = $this->get_option( 'title' ); $this->description = $this->get_option( 'description' ); + $this->testmode = 'yes' === $this->get_option( 'testmode', 'no' ); $this->merchant_id = $this->get_option( 'merchant_id' ); $this->access_code = $this->get_option( 'access_code' ); $this->secure_secret = $this->get_option( 'secure_secret' ); @@ -65,22 +65,75 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { * @return string */ public function get_pay_url ( $order ) { - $access_key = $this->access_key; - $secret = $this->secret; // require your secret key from 1pay - $return_url = $this->get_1pay_return_url(); - $command = 'request_transaction'; - $amount = $order->get_total(); // >10000 - $order_id = $order->id; - $order_info = sprintf( 'The payment for the order number %1$s on the site: %2$s', $order->id, get_home_url()); + $args = array( + 'Title' => __('OnePay Payment Title', 'woo-viet'), + 'vpc_Merchant' => $this->merchant_id, + 'vpc_AccessCode' => $this->access_code, + 'vpc_MerchTxnRef' => sprintf('%1$s_%2$s', $order->id, date ( 'YmdHis' )), + 'vpc_OrderInfo' => substr( + sprintf('Order #%1$s - %2$s', $order->id, get_home_url()), + 0, + 32 ), // Limit 32 characters + 'vpc_Amount' => $order->get_total() * 100, // Multiplying 100 is a requirement from OnePay + 'vpc_ReturnURL' => $this->get_onepay_return_url(), + 'vpc_Version' => '2', + 'vpc_Command' => 'pay', + 'vpc_Locale' => ( 'vi' == get_locale() ) ? 'vn' : 'en', + 'vpc_Currency' => 'VND', + 'vpc_TicketNo' => $_SERVER['REMOTE_ADDR'], + ); + + // Get the secure hash + $vpc_SecureHash = $this->create_vpc_SecureHash( $args ); + + // Add the secure hash to the args + $args['vpc_SecureHash'] = $vpc_SecureHash; + $http_args = http_build_query( $args, '', '&' ); + + + if ( $this->testmode ) { + return 'https://mtf.onepay.vn/onecomm-pay/vpc.op?' . $http_args; + } else { + return 'https://onepay.vn/onecomm-pay/vpc.op?' . $http_args; + } + - // @todo: review and see the file do.php in the demo files } - - // @todo review this function - /* - public function static get_return_url(){ + // @todo: need to check this and WC_Payment_Gateway::get_return_url($order = NULL) + public function get_onepay_return_url(){ return WC()->api_request_url( __CLASS__ ); } - */ + + /** + * Get the PayPal request URL for an order. + * @param array $args + * @return string + */ + public function create_vpc_SecureHash ( $args ){ + $stringHashData = ""; + + // arrange array data a-z before make a hash + ksort ($args ); + + foreach($args as $key => $value) { + + // tạo chuỗi đầu dữ liệu những tham số có dữ liệu + if (strlen($value) > 0) { + //sử dụng cả tên và giá trị tham số để mã hóa + if ((strlen($value) > 0) && ((substr($key, 0,4)=="vpc_") || (substr($key,0,5) =="user_"))) { + $stringHashData .= $key . "=" . $value . "&"; + } + } + } + //xóa ký tự & ở thừa ở cuối chuỗi dữ liệu mã hóa***************************** + $stringHashData = rtrim($stringHashData, "&"); + + return strtoupper(hash_hmac('SHA256', $stringHashData, pack('H*', $this->secure_secret ))); + } + + public function process_return_url (){ + // http://localhost/woo-viet/wc-api/WooViet_OnePay_Domestic/?vpc_AdditionData=686868&vpc_Amount=40000000&vpc_Command=pay&vpc_CurrencyCode=VND&vpc_Locale=en&vpc_MerchTxnRef=%23133_20170418024557&vpc_Merchant=ONEPAY&vpc_OrderInfo=%23133+-+http%3A%2F%2Flocalhost%2Fwoo-viet&vpc_TransactionNo=1576998&vpc_TxnResponseCode=0&vpc_Version=2&vpc_SecureHash=25C4443CFF95F6D5BCE4AD86DAA6756960688BD8868CBE898989125050504361 + } + } diff --git a/inc/onepay/domestic-settings.php b/inc/onepay/domestic-settings.php index baa53d4..aa77cd3 100644 --- a/inc/onepay/domestic-settings.php +++ b/inc/onepay/domestic-settings.php @@ -15,6 +15,13 @@ return array( 'label' => __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ), 'default' => 'yes' ), + 'testmode' => array( + 'title' => __( 'OnePay Sandbox', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable OnePay sandbox (testing)', 'woocommerce' ), + 'default' => 'no', + 'description' => sprintf( __( 'OnePay sandbox can be used to test payments. See the testing info.', 'woocommerce' ), 'https://mtf.onepay.vn/developer/?page=modul_noidia' ), + ), 'title' => array( 'title' => __( 'Title', 'woo-viet' ), 'type' => 'text', @@ -27,7 +34,7 @@ return array( 'type' => 'text', 'desc_tip' => true, 'description' => __( 'This controls the description which the user sees during checkout.', 'woo-viet' ), - 'default' => __( 'With OnePay Bank, you can make payment by using any local Vietnam ATM card.', 'woo-viet' ) + 'default' => __( 'With OnePay, you can make payment by using any local Vietnam ATM card.', 'woo-viet' ) ), 'api_details' => array( 'title' => __( 'API Credentials', 'woo-viet' ), @@ -42,7 +49,7 @@ return array( 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) ), - 'access code' => array( + 'access_code' => array( 'title' => __( 'Access Code', 'woocommerce' ), 'type' => 'text', 'description' => __( 'Get your Access Code from from OnePay.', 'woo-viet' ), From cb989175a5a117c4f00bfd5f734cd591d633e3c5 Mon Sep 17 00:00:00 2001 From: htdat Date: Tue, 18 Apr 2017 19:01:50 +0700 Subject: [PATCH 03/18] Added functions to handle IPN and return URL Still need to consider something more --- inc/class-wooviet-onepay-domestic.php | 144 ++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 9 deletions(-) diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index a10bbf4..cb32156 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -19,11 +19,10 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { * Constructor for the gateway. */ public function __construct() { - $this->id = 'wooviet_onepay_domestic'; + $this->id = strtolower(__CLASS__); $this->has_fields = false; $this->order_button_text = __( 'Proceed to OnePay', 'woo-viet' ); $this->method_title = __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ); - // @todo - check the method description $this->method_description = __( 'OnePay supports all major bank ATMs in Vietnam.', 'woo-viet' ); $this->supports = array( 'products', @@ -39,9 +38,11 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { $this->access_code = $this->get_option( 'access_code' ); $this->secure_secret = $this->get_option( 'secure_secret' ); - // @todo: the sandbox option - add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + + add_action('woocommerce_thankyou_' . $this->id, array($this, 'handle_onepay_return_url')); + + add_action('woocommerce_api_' . strtolower(__CLASS__), array($this, 'handle_onepay_ipn' ) ); } /** * Initialise Gateway Settings Form Fields. @@ -75,7 +76,7 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { 0, 32 ), // Limit 32 characters 'vpc_Amount' => $order->get_total() * 100, // Multiplying 100 is a requirement from OnePay - 'vpc_ReturnURL' => $this->get_onepay_return_url(), + 'vpc_ReturnURL' => $this->get_return_url($order), 'vpc_Version' => '2', 'vpc_Command' => 'pay', 'vpc_Locale' => ( 'vi' == get_locale() ) ? 'vn' : 'en', @@ -100,13 +101,12 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { } - // @todo: need to check this and WC_Payment_Gateway::get_return_url($order = NULL) + // @todo: need to check this and WC_Payment_Gateway::get_return_url($order = NULL). This might be used for IPN only public function get_onepay_return_url(){ return WC()->api_request_url( __CLASS__ ); } /** - * Get the PayPal request URL for an order. * @param array $args * @return string */ @@ -132,8 +132,134 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { return strtoupper(hash_hmac('SHA256', $stringHashData, pack('H*', $this->secure_secret ))); } - public function process_return_url (){ - // http://localhost/woo-viet/wc-api/WooViet_OnePay_Domestic/?vpc_AdditionData=686868&vpc_Amount=40000000&vpc_Command=pay&vpc_CurrencyCode=VND&vpc_Locale=en&vpc_MerchTxnRef=%23133_20170418024557&vpc_Merchant=ONEPAY&vpc_OrderInfo=%23133+-+http%3A%2F%2Flocalhost%2Fwoo-viet&vpc_TransactionNo=1576998&vpc_TxnResponseCode=0&vpc_Version=2&vpc_SecureHash=25C4443CFF95F6D5BCE4AD86DAA6756960688BD8868CBE898989125050504361 + + public function check_vpc_SecureHash ($args, $vpc_SecureHash) { + // Generate the "vpc_SecureHash" value from $args + $vpc_SecureHash_from_args = $this->create_vpc_SecureHash($args); + + if ($vpc_SecureHash_from_args == $vpc_SecureHash ) { + return true; + } else { + return false; + } } + public function handle_onepay_return_url(){ + if (isset($_GET['vpc_SecureHash'])) { + + $this->process_onepay_response_data( $_GET ); + + // @todo NEXT check this part + // Redirect to the return URL without the OnePay parameters + // wp_redirect($this->get_return_url( $order )); + } + } + + public function process_onepay_response_data ($args ) { + $vpc_SecureHash = $args['vpc_SecureHash']; + + // Remove the parameter "vpc_SecureHash" for validating SecureHash + unset($args['vpc_SecureHash']); + + $check_vpc_SecureHash = $this->check_vpc_SecureHash($args, $vpc_SecureHash); + + if ( $check_vpc_SecureHash ) { + /** + * $vpc_MerchTxnRef looks like this "139_20170418101843" or {order_id}_{date_time} + * @see $this->get_pay_url(); + */ + $vpc_MerchTxnRef = $args['vpc_MerchTxnRef']; + + // Get the order_id part only + $order_id = substr($vpc_MerchTxnRef,0,strrpos($vpc_MerchTxnRef,'_')); + + $order = wc_get_order($order_id); + + $vpc_TxnResponseCode = $args['vpc_TxnResponseCode']; + + // The payment was made successfully + if ("0" == $vpc_TxnResponseCode ) { + $order->payment_complete(); + } + + // Add the order note for the reference + $order_note = sprintf( + __('OnePay Domestic Gateway Info | Code: %1$s | Message: %2$s | MerchantTxnRef: %3$s', 'woo-viet'), + $vpc_TxnResponseCode, + $this->OnePay_getResponseDescription($vpc_TxnResponseCode), + $vpc_MerchTxnRef + ); + $order->add_order_note($order_note); + + // return $order; + + } + } + + public function handle_onepay_ipn() { + if (isset($_POST['vpc_SecureHash'])) { + + $this->process_onepay_response_data( $_POST ); + + // Write the response + } + } + + public function OnePay_getResponseDescription($responseCode) { + + switch ($responseCode) { + case "0" : + $result = "Giao dịch thành công - Approved"; + break; + case "1" : + $result = "Ngân hàng từ chối giao dịch - Bank Declined"; + break; + case "3" : + $result = "Mã đơn vị không tồn tại - Merchant not exist"; + break; + case "4" : + $result = "Không đúng access code - Invalid access code"; + break; + case "5" : + $result = "Số tiền không hợp lệ - Invalid amount"; + break; + case "6" : + $result = "Mã tiền tệ không tồn tại - Invalid currency code"; + break; + case "7" : + $result = "Lỗi không xác định - Unspecified Failure "; + break; + case "8" : + $result = "Số thẻ không đúng - Invalid card Number"; + break; + case "9" : + $result = "Tên chủ thẻ không đúng - Invalid card name"; + break; + case "10" : + $result = "Thẻ hết hạn/Thẻ bị khóa - Expired Card"; + break; + case "11" : + $result = "Thẻ chưa đăng ký sử dụng dịch vụ - Card Not Registed Service(internet banking)"; + break; + case "12" : + $result = "Ngày phát hành/Hết hạn không đúng - Invalid card date"; + break; + case "13" : + $result = "Vượt quá hạn mức thanh toán - Exist Amount"; + break; + case "21" : + $result = "Số tiền không đủ để thanh toán - Insufficient fund"; + break; + case "99" : + $result = "Người sủ dụng hủy giao dịch - User cancel"; + break; + default : + $result = "Giao dịch thất bại - Failured"; + } + return $result; + } + + + + } From 70d2182b5044e2682f461079feb79b613aae0911 Mon Sep 17 00:00:00 2001 From: htdat Date: Thu, 20 Apr 2017 17:02:19 +0700 Subject: [PATCH 04/18] Almost finish Need to check: IPN and queryDR And add the option in WooViet settings page --- inc/class-wooviet-onepay-domestic.php | 217 ++++++++++++++++++++------ inc/onepay/domestic-settings.php | 34 ++-- woo-viet.php | 2 + 3 files changed, 196 insertions(+), 57 deletions(-) diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index cb32156..4394147 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -11,9 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * */ - - - class WooViet_OnePay_Domestic extends WC_Payment_Gateway { /** * Constructor for the gateway. @@ -27,9 +24,11 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { $this->supports = array( 'products', ); + // Load the settings. $this->init_form_fields(); $this->init_settings(); + // Define user set variables. $this->title = $this->get_option( 'title' ); $this->description = $this->get_option( 'description' ); @@ -37,12 +36,18 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { $this->merchant_id = $this->get_option( 'merchant_id' ); $this->access_code = $this->get_option( 'access_code' ); $this->secure_secret = $this->get_option( 'secure_secret' ); + $this->user = $this->get_option( 'user' ); + $this->password = $this->get_option( 'password' ); + // Process the admin options add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); add_action('woocommerce_thankyou_' . $this->id, array($this, 'handle_onepay_return_url')); add_action('woocommerce_api_' . strtolower(__CLASS__), array($this, 'handle_onepay_ipn' ) ); + + // @todo: check whether or not this can be lodded in the cron job + add_action('wooviet_handle_onepay_querydr', array($this, 'handle_onepay_querydr'), 10, 1); } /** * Initialise Gateway Settings Form Fields. @@ -50,8 +55,12 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { public function init_form_fields() { $this->form_fields = include( 'onepay/domestic-settings.php' ); } + /** - * Process the payment. + * Process the payment + * @param int $order_id + * + * @return array */ public function process_payment( $order_id ) { $order = wc_get_order( $order_id ); @@ -60,8 +69,26 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { 'redirect' => $this->get_pay_url( $order ) ); } + /** - * Get the OnePay pay URL for an order. + * Set the cron job running queryDR in 20 mintues + * Because the OnePay payment timeout is 15 minutes + * + * @param string $vpc_MerchTxnRef + */ + public function set_onepay_querydr_cron( $vpc_MerchTxnRef ) { + + wp_schedule_single_event( + time() + 20 * 60, + 'wooviet_handle_onepay_querydr', + array( $vpc_MerchTxnRef ) // @todo check this + ); + + } + /** + * Get the OnePay pay URL for an order + * AND set the queryDR cron for this transaction + * * @param WC_Order $order * @return string */ @@ -84,6 +111,9 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { 'vpc_TicketNo' => $_SERVER['REMOTE_ADDR'], ); + // Set the queryDR cron for this transaction + $this->set_onepay_querydr_cron($args['vpc_MerchTxnRef']); + // Get the secure hash $vpc_SecureHash = $this->create_vpc_SecureHash( $args ); @@ -91,22 +121,26 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { $args['vpc_SecureHash'] = $vpc_SecureHash; $http_args = http_build_query( $args, '', '&' ); - if ( $this->testmode ) { return 'https://mtf.onepay.vn/onecomm-pay/vpc.op?' . $http_args; } else { return 'https://onepay.vn/onecomm-pay/vpc.op?' . $http_args; } - - } - // @todo: need to check this and WC_Payment_Gateway::get_return_url($order = NULL). This might be used for IPN only - public function get_onepay_return_url(){ + + /** + * Get the IPN URL for OnePay + * Format: http://my-site.com/wc-api/WooViet_OnePay_Domestic/ + */ + static function get_onepay_ipn_url(){ return WC()->api_request_url( __CLASS__ ); } /** + * Create the vpc_SecureHash value. + * @see https://mtf.onepay.vn/developer/?page=modul_noidia_php + * * @param array $args * @return string */ @@ -118,21 +152,28 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { foreach($args as $key => $value) { - // tạo chuỗi đầu dữ liệu những tham số có dữ liệu if (strlen($value) > 0) { - //sử dụng cả tên và giá trị tham số để mã hóa if ((strlen($value) > 0) && ((substr($key, 0,4)=="vpc_") || (substr($key,0,5) =="user_"))) { $stringHashData .= $key . "=" . $value . "&"; } } } - //xóa ký tự & ở thừa ở cuối chuỗi dữ liệu mã hóa***************************** + //Remove the last character "&" $stringHashData = rtrim($stringHashData, "&"); return strtoupper(hash_hmac('SHA256', $stringHashData, pack('H*', $this->secure_secret ))); } - + /** + * Whether or not the arguments and a provided $vpc_SecureHash are the same + * + * @see https://mtf.onepay.vn/developer/?page=modul_noidia_php + * + * @param $args + * @param $vpc_SecureHash + * + * @return bool + */ public function check_vpc_SecureHash ($args, $vpc_SecureHash) { // Generate the "vpc_SecureHash" value from $args $vpc_SecureHash_from_args = $this->create_vpc_SecureHash($args); @@ -143,68 +184,153 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { return false; } } - + /** + * Handle the return URL - GET request from OnePay + */ public function handle_onepay_return_url(){ + if (isset($_GET['vpc_SecureHash'])) { - $this->process_onepay_response_data( $_GET ); + $this->process_onepay_response_data( $_GET, 'return' ); - // @todo NEXT check this part - // Redirect to the return URL without the OnePay parameters - // wp_redirect($this->get_return_url( $order )); } } - public function process_onepay_response_data ($args ) { - $vpc_SecureHash = $args['vpc_SecureHash']; + /** + * Handle the IPN POST request from OnePay + */ + public function handle_onepay_ipn() { - // Remove the parameter "vpc_SecureHash" for validating SecureHash - unset($args['vpc_SecureHash']); + if (isset($_POST['vpc_SecureHash'])) { - $check_vpc_SecureHash = $this->check_vpc_SecureHash($args, $vpc_SecureHash); + $this->process_onepay_response_data( $_POST ); - if ( $check_vpc_SecureHash ) { + } + } + + /** + * Handle the queryDR request + * @param string $vpc_MerchTxnRef + */ + public function handle_onepay_querydr( $vpc_MerchTxnRef ) { + // Build the queryDR link + $args = array( + 'vpc_Command' => 'queryDR', + 'vpc_Version' => '1', + 'vpc_MerchTxnRef' => $vpc_MerchTxnRef, + 'vpc_Merchant' => $this->merchant_id, + 'vpc_AccessCode' => $this->access_code, + 'vpc_User' => $this->user, + 'vpc_Password' => $this->password, + ); + + $http_args = http_build_query( $args, '', '&' ); + + if ( $this->testmode ) { + $http_link = 'https://mtf.onepay.vn/onecomm-pay/Vpcdps.op?' . $http_args; + } else { + $http_link = 'https://onepay.vn/onecomm-pay/Vpcdps.op?' . $http_args; + } + + // Connect to OnePay to get the queryDR info + $http_response = wp_remote_get( $http_link ); + parse_str( wp_remote_retrieve_body( $http_response ), $args_response ); + + // Process the data + $this->process_onepay_response_data($args_response); + + } + + /** + * Handle the repsonse data from OnePay + * @param string $args the response data from OnePay + * @param string $type + */ + public function process_onepay_response_data ($args, $type = '' ) { + $types_accepted = array( + 'return', + 'ipn', + 'querydr', + ); + + // Do nothing if the type is wrong + if ( ! in_array($type, $types_accepted) ) { + return; + } + + $is_secure = false; + $is_querydr_exists = false; + + if ('return' == $type OR 'ipn' == $type ) { + $vpc_SecureHash = $args['vpc_SecureHash']; + + // Remove the parameter "vpc_SecureHash" for validating SecureHash + unset($args['vpc_SecureHash']); + + $is_secure = $this->check_vpc_SecureHash($args, $vpc_SecureHash); + + } elseif ('querydr' == $type ) { + $is_querydr_exists = ( 'Y' == $args['vpc_DRExists'] ); + + } + + // Process the data + if ( $is_secure OR $is_querydr_exists ) { /** * $vpc_MerchTxnRef looks like this "139_20170418101843" or {order_id}_{date_time} * @see $this->get_pay_url(); */ $vpc_MerchTxnRef = $args['vpc_MerchTxnRef']; + $vpc_TxnResponseCode = $args['vpc_TxnResponseCode']; // Get the order_id part only $order_id = substr($vpc_MerchTxnRef,0,strrpos($vpc_MerchTxnRef,'_')); $order = wc_get_order($order_id); - $vpc_TxnResponseCode = $args['vpc_TxnResponseCode']; - - // The payment was made successfully - if ("0" == $vpc_TxnResponseCode ) { - $order->payment_complete(); - } - // Add the order note for the reference $order_note = sprintf( - __('OnePay Domestic Gateway Info | Code: %1$s | Message: %2$s | MerchantTxnRef: %3$s', 'woo-viet'), + __('OnePay Domestic Gateway Info | Code: %1$s | Message: %2$s | MerchantTxnRef: %3$s | Type: %4$s', 'woo-viet'), $vpc_TxnResponseCode, $this->OnePay_getResponseDescription($vpc_TxnResponseCode), - $vpc_MerchTxnRef + $vpc_MerchTxnRef, + $type ); $order->add_order_note($order_note); - // return $order; + // If the payment is successful, update the order + if ("0" == $vpc_TxnResponseCode ) + $order->payment_complete(); + switch ( $type ) { + + case 'return': + wp_redirect($this->get_return_url( $order )); + break; + + case 'ipn': + wp_die('responsecode=1&desc=confirm-success'); + break; + + case 'querydr': + // Do nothing + break; + } + + } else { + if ( 'ipn' == $type ) + wp_die('responsecode=0&desc=confirm-success'); } } - public function handle_onepay_ipn() { - if (isset($_POST['vpc_SecureHash'])) { - - $this->process_onepay_response_data( $_POST ); - - // Write the response - } - } - + /** + * Get the response description based on the response code + * This is code is from OnePay + * + * @param string $responseCode + * + * @return string + */ public function OnePay_getResponseDescription($responseCode) { switch ($responseCode) { @@ -259,7 +385,4 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { return $result; } - - - } diff --git a/inc/onepay/domestic-settings.php b/inc/onepay/domestic-settings.php index aa77cd3..522cb14 100644 --- a/inc/onepay/domestic-settings.php +++ b/inc/onepay/domestic-settings.php @@ -4,7 +4,6 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } -// @todo - ver 1.3 - check all texts /** * Settings for 1Pay Gateway. */ @@ -21,6 +20,7 @@ return array( 'label' => __( 'Enable OnePay sandbox (testing)', 'woocommerce' ), 'default' => 'no', 'description' => sprintf( __( 'OnePay sandbox can be used to test payments. See the testing info.', 'woocommerce' ), 'https://mtf.onepay.vn/developer/?page=modul_noidia' ), + //@todo: add the logo https://mtf.onepay.vn/developer/?page=logo ), 'title' => array( 'title' => __( 'Title', 'woo-viet' ), @@ -31,7 +31,7 @@ return array( ), 'description' => array( 'title' => __( 'Description', 'woo-viet' ), - 'type' => 'text', + 'type' => 'textarea', 'desc_tip' => true, 'description' => __( 'This controls the description which the user sees during checkout.', 'woo-viet' ), 'default' => __( 'With OnePay, you can make payment by using any local Vietnam ATM card.', 'woo-viet' ) @@ -65,14 +65,28 @@ return array( 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) ), - /* - // @todo: Add more help info later - - 'help_title' => array( - 'title' => __( 'More info about 1Pay', 'woo-viet' ), - 'type' => 'title', - 'description' => __( 'You can see more info at this link.', 'woo-viet' ) + 'user' => array( + 'title' => __( 'User for queryDR. Test value: op01', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your user info from from OnePay.', 'woo-viet' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Required. Provided by OnePay', 'woo-viet' ) + ), + 'password' => array( + 'title' => __( 'Password for queryDR. Test value: op123456', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your password info from from OnePay.', 'woo-viet' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) + ), + 'more_info' => array( + 'title' => __( 'Instant Payment Notification (IPN)', 'woo-viet' ), + 'type' => 'title', + 'description' => + sprintf('URL: %s', WooViet_OnePay_Domestic::get_onepay_ipn_url() ) . '

' . + sprintf( __( '%sContact OnePay%s to configure this URL on its site. This is required based on its guidelines.', 'woo-viet' ), '', '' ), ), - */ ); \ No newline at end of file diff --git a/woo-viet.php b/woo-viet.php index 2b4b469..d1b85ee 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -135,6 +135,8 @@ class WooViet { add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) ); include( 'inc/class-wooviet-onepay-domestic.php'); + $WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); + add_action('wooviet_handle_onepay_querydr', array($WooViet_OnePay_Domestic_Hook, 'handle_onepay_querydr'), 10, 1); if ( is_admin() ) { From 0e252a978a855216c3ceb9aea6d110833ebffd52 Mon Sep 17 00:00:00 2001 From: htdat Date: Thu, 20 Apr 2017 17:39:11 +0700 Subject: [PATCH 05/18] Add the option in the Woo Viet setting page --- inc/class-wooviet-admin-page.php | 18 ++++++++++++++++++ woo-viet.php | 24 +++++++++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/inc/class-wooviet-admin-page.php b/inc/class-wooviet-admin-page.php index d572d55..f81f2a6 100644 --- a/inc/class-wooviet-admin-page.php +++ b/inc/class-wooviet-admin-page.php @@ -88,6 +88,24 @@ class WooViet_Admin_Page { value=""> + + + + + @@ -117,14 +118,14 @@ class WooViet_Admin_Page { - diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index cd39918..641a860 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -2,6 +2,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } + /** * The class to handle the domestic OnePay gateway https://mtf.onepay.vn/developer/?page=modul_noidia * @@ -10,17 +11,16 @@ if ( ! defined( 'ABSPATH' ) ) { * @since 1.3 * */ - class WooViet_OnePay_Domestic extends WC_Payment_Gateway { /** * Constructor for the gateway. */ public function __construct() { - $this->id = strtolower(__CLASS__); + $this->id = strtolower( __CLASS__ ); $this->has_fields = false; $this->order_button_text = __( 'Proceed to OnePay', 'woo-viet' ); $this->method_title = __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ); - $this->method_description = __( 'OnePay supports all major bank ATMs in Vietnam.', 'woo-viet' ); + $this->method_description = __( 'OnePay supports all major bank ATMs in Vietnam.', 'woo-viet' ); $this->supports = array( 'products', ); @@ -30,25 +30,29 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { $this->init_settings(); // Define user set variables. - $this->title = $this->get_option( 'title' ); - $this->description = $this->get_option( 'description' ); - $this->testmode = 'yes' === $this->get_option( 'testmode', 'no' ); - $this->merchant_id = $this->get_option( 'merchant_id' ); - $this->access_code = $this->get_option( 'access_code' ); - $this->secure_secret = $this->get_option( 'secure_secret' ); + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->testmode = 'yes' === $this->get_option( 'testmode', 'no' ); + $this->merchant_id = $this->get_option( 'merchant_id' ); + $this->access_code = $this->get_option( 'access_code' ); + $this->secure_secret = $this->get_option( 'secure_secret' ); $this->user = $this->get_option( 'user' ); - $this->password = $this->get_option( 'password' ); + $this->password = $this->get_option( 'password' ); // Process the admin options - add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( + $this, + 'process_admin_options' + ) ); - add_action('woocommerce_thankyou_' . $this->id, array($this, 'handle_onepay_return_url')); + add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'handle_onepay_return_url' ) ); - add_action('woocommerce_api_' . strtolower(__CLASS__), array($this, 'handle_onepay_ipn' ) ); + add_action( 'woocommerce_api_' . strtolower( __CLASS__ ), array( $this, 'handle_onepay_ipn' ) ); // @todo: check whether or not this can be lodded in the cron job - add_action('wooviet_handle_onepay_querydr', array($this, 'handle_onepay_querydr'), 10, 1); + add_action( 'wooviet_handle_onepay_querydr', array( $this, 'handle_onepay_querydr' ), 10, 1 ); } + /** * Initialise Gateway Settings Form Fields. */ @@ -56,20 +60,75 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { $this->form_fields = include( 'onepay/domestic-settings.php' ); } + /** + * Get the IPN URL for OnePay + * Format: http://my-site.com/wc-api/WooViet_OnePay_Domestic/ + */ + static function get_onepay_ipn_url() { + return WC()->api_request_url( __CLASS__ ); + } + /** * Process the payment + * * @param int $order_id * * @return array */ public function process_payment( $order_id ) { - $order = wc_get_order( $order_id ); + $order = wc_get_order( $order_id ); + return array( 'result' => 'success', 'redirect' => $this->get_pay_url( $order ) ); } + /** + * Get the OnePay pay URL for an order + * AND set the queryDR cron for this transaction + * + * @param WC_Order $order + * + * @return string + */ + public function get_pay_url( $order ) { + $args = array( + 'Title' => __( 'OnePay Payment Title', 'woo-viet' ), + 'vpc_Merchant' => $this->merchant_id, + 'vpc_AccessCode' => $this->access_code, + 'vpc_MerchTxnRef' => sprintf( '%1$s_%2$s', $order->id, date( 'YmdHis' ) ), + 'vpc_OrderInfo' => substr( + sprintf( 'Order #%1$s - %2$s', $order->id, get_home_url() ), + 0, + 32 ), // Limit 32 characters + 'vpc_Amount' => $order->get_total() * 100, // Multiplying 100 is a requirement from OnePay + 'vpc_ReturnURL' => $this->get_return_url( $order ), + 'vpc_Version' => '2', + 'vpc_Command' => 'pay', + 'vpc_Locale' => ( 'vi' == get_locale() ) ? 'vn' : 'en', + 'vpc_Currency' => 'VND', + 'vpc_TicketNo' => $_SERVER['REMOTE_ADDR'], + ); + + // Set the queryDR cron for this transaction + $this->set_onepay_querydr_cron( $args['vpc_MerchTxnRef'] ); + + // Get the secure hash + $vpc_SecureHash = $this->create_vpc_SecureHash( $args ); + + // Add the secure hash to the args + $args['vpc_SecureHash'] = $vpc_SecureHash; + $http_args = http_build_query( $args, '', '&' ); + + if ( $this->testmode ) { + return 'https://mtf.onepay.vn/onecomm-pay/vpc.op?' . $http_args; + } else { + return 'https://onepay.vn/onecomm-pay/vpc.op?' . $http_args; + } + + } + /** * Set the cron job running queryDR in 20 mintues * Because the OnePay payment timeout is 15 minutes @@ -85,83 +144,131 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { ); } - /** - * Get the OnePay pay URL for an order - * AND set the queryDR cron for this transaction - * - * @param WC_Order $order - * @return string - */ - public function get_pay_url ( $order ) { - $args = array( - 'Title' => __('OnePay Payment Title', 'woo-viet'), - 'vpc_Merchant' => $this->merchant_id, - 'vpc_AccessCode' => $this->access_code, - 'vpc_MerchTxnRef' => sprintf('%1$s_%2$s', $order->id, date ( 'YmdHis' )), - 'vpc_OrderInfo' => substr( - sprintf('Order #%1$s - %2$s', $order->id, get_home_url()), - 0, - 32 ), // Limit 32 characters - 'vpc_Amount' => $order->get_total() * 100, // Multiplying 100 is a requirement from OnePay - 'vpc_ReturnURL' => $this->get_return_url($order), - 'vpc_Version' => '2', - 'vpc_Command' => 'pay', - 'vpc_Locale' => ( 'vi' == get_locale() ) ? 'vn' : 'en', - 'vpc_Currency' => 'VND', - 'vpc_TicketNo' => $_SERVER['REMOTE_ADDR'], - ); - - // Set the queryDR cron for this transaction - $this->set_onepay_querydr_cron($args['vpc_MerchTxnRef']); - - // Get the secure hash - $vpc_SecureHash = $this->create_vpc_SecureHash( $args ); - - // Add the secure hash to the args - $args['vpc_SecureHash'] = $vpc_SecureHash; - $http_args = http_build_query( $args, '', '&' ); - - if ( $this->testmode ) { - return 'https://mtf.onepay.vn/onecomm-pay/vpc.op?' . $http_args; - } else { - return 'https://onepay.vn/onecomm-pay/vpc.op?' . $http_args; - } - - } - - /** - * Get the IPN URL for OnePay - * Format: http://my-site.com/wc-api/WooViet_OnePay_Domestic/ - */ - static function get_onepay_ipn_url(){ - return WC()->api_request_url( __CLASS__ ); - } /** * Create the vpc_SecureHash value. * @see https://mtf.onepay.vn/developer/?page=modul_noidia_php * * @param array $args + * * @return string */ - public function create_vpc_SecureHash ( $args ){ + public function create_vpc_SecureHash( $args ) { $stringHashData = ""; // arrange array data a-z before make a hash - ksort ($args ); + ksort( $args ); - foreach($args as $key => $value) { + foreach ( $args as $key => $value ) { - if (strlen($value) > 0) { - if ((strlen($value) > 0) && ((substr($key, 0,4)=="vpc_") || (substr($key,0,5) =="user_"))) { + if ( strlen( $value ) > 0 ) { + if ( ( strlen( $value ) > 0 ) && ( ( substr( $key, 0, 4 ) == "vpc_" ) || ( substr( $key, 0, 5 ) == "user_" ) ) ) { $stringHashData .= $key . "=" . $value . "&"; } } } //Remove the last character "&" - $stringHashData = rtrim($stringHashData, "&"); + $stringHashData = rtrim( $stringHashData, "&" ); - return strtoupper(hash_hmac('SHA256', $stringHashData, pack('H*', $this->secure_secret ))); + return strtoupper( hash_hmac( 'SHA256', $stringHashData, pack( 'H*', $this->secure_secret ) ) ); + } + + /** + * Handle the return URL - GET request from OnePay + */ + public function handle_onepay_return_url() { + + if ( isset( $_GET['vpc_SecureHash'] ) ) { + + $this->process_onepay_response_data( $_GET, 'return' ); + + } + } + + /** + * Handle the repsonse data from OnePay + * + * @param string $args the response data from OnePay + * @param string $type + */ + public function process_onepay_response_data( $args, $type ) { + $types_accepted = array( + 'return', + 'ipn', + 'querydr', + ); + + // Do nothing if the type is wrong + if ( ! in_array( $type, $types_accepted ) ) { + return; + } + + $is_secure = false; + $is_querydr_exists = false; + + if ( 'return' == $type OR 'ipn' == $type ) { + $vpc_SecureHash = $args['vpc_SecureHash']; + + // Remove the parameter "vpc_SecureHash" for validating SecureHash + unset( $args['vpc_SecureHash'] ); + + $is_secure = $this->check_vpc_SecureHash( $args, $vpc_SecureHash ); + + } elseif ( 'querydr' == $type ) { + $is_querydr_exists = ( 'Y' == $args['vpc_DRExists'] ); + + } + + // Process the data + if ( $is_secure OR $is_querydr_exists ) { + /** + * $vpc_MerchTxnRef looks like this "139_20170418101843" or {order_id}_{date_time} + * @see $this->get_pay_url(); + */ + $vpc_MerchTxnRef = $args['vpc_MerchTxnRef']; + $vpc_TxnResponseCode = $args['vpc_TxnResponseCode']; + + // Get the order_id part only + $order_id = substr( $vpc_MerchTxnRef, 0, strrpos( $vpc_MerchTxnRef, '_' ) ); + + $order = wc_get_order( $order_id ); + + // Add the order note for the reference + $order_note = sprintf( + __( 'OnePay Domestic Gateway Info | Code: %1$s | Message: %2$s | MerchantTxnRef: %3$s | Type: %4$s', 'woo-viet' ), + $vpc_TxnResponseCode, + $this->OnePay_getResponseDescription( $vpc_TxnResponseCode ), + $vpc_MerchTxnRef, + $type + ); + $order->add_order_note( $order_note ); + + // If the payment is successful, update the order + if ( "0" == $vpc_TxnResponseCode ) { + $order->payment_complete(); + } + + switch ( $type ) { + + case 'return': + wp_redirect( $this->get_return_url( $order ) ); + break; + + case 'ipn': + exit( 'responsecode=1&desc=confirm-success' ); + break; + + case 'querydr': + // Do nothing + break; + } + + } else { + if ( 'ipn' == $type ) { + exit( 'responsecode=0&desc=confirm-success' ); + } + + } } /** @@ -174,155 +281,16 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { * * @return bool */ - public function check_vpc_SecureHash ($args, $vpc_SecureHash) { + public function check_vpc_SecureHash( $args, $vpc_SecureHash ) { // Generate the "vpc_SecureHash" value from $args - $vpc_SecureHash_from_args = $this->create_vpc_SecureHash($args); + $vpc_SecureHash_from_args = $this->create_vpc_SecureHash( $args ); - if ($vpc_SecureHash_from_args == $vpc_SecureHash ) { + if ( $vpc_SecureHash_from_args == $vpc_SecureHash ) { return true; } else { return false; } } - /** - * Handle the return URL - GET request from OnePay - */ - public function handle_onepay_return_url(){ - - if (isset($_GET['vpc_SecureHash'])) { - - $this->process_onepay_response_data( $_GET, 'return' ); - - } - } - - /** - * Handle the IPN POST request from OnePay - */ - public function handle_onepay_ipn() { - - if (isset($_REQUEST['vpc_SecureHash'])) { - - $this->process_onepay_response_data( $_REQUEST, 'ipn' ); - - } - } - - /** - * Handle the queryDR request - * @param string $vpc_MerchTxnRef - */ - public function handle_onepay_querydr( $vpc_MerchTxnRef ) { - // Build the queryDR link - $args = array( - 'vpc_Command' => 'queryDR', - 'vpc_Version' => '1', - 'vpc_MerchTxnRef' => $vpc_MerchTxnRef, - 'vpc_Merchant' => $this->merchant_id, - 'vpc_AccessCode' => $this->access_code, - 'vpc_User' => $this->user, - 'vpc_Password' => $this->password, - ); - - $http_args = http_build_query( $args, '', '&' ); - - if ( $this->testmode ) { - $http_link = 'https://mtf.onepay.vn/onecomm-pay/Vpcdps.op?' . $http_args; - } else { - $http_link = 'https://onepay.vn/onecomm-pay/Vpcdps.op?' . $http_args; - } - - // Connect to OnePay to get the queryDR info - $http_response = wp_remote_get( $http_link ); - parse_str( wp_remote_retrieve_body( $http_response ), $args_response ); - - // Process the data - $this->process_onepay_response_data($args_response, 'querydr'); - - } - - /** - * Handle the repsonse data from OnePay - * @param string $args the response data from OnePay - * @param string $type - */ - public function process_onepay_response_data ($args, $type ) { - $types_accepted = array( - 'return', - 'ipn', - 'querydr', - ); - - // Do nothing if the type is wrong - if ( ! in_array($type, $types_accepted) ) { - return; - } - - $is_secure = false; - $is_querydr_exists = false; - - if ('return' == $type OR 'ipn' == $type ) { - $vpc_SecureHash = $args['vpc_SecureHash']; - - // Remove the parameter "vpc_SecureHash" for validating SecureHash - unset($args['vpc_SecureHash']); - - $is_secure = $this->check_vpc_SecureHash($args, $vpc_SecureHash); - - } elseif ('querydr' == $type ) { - $is_querydr_exists = ( 'Y' == $args['vpc_DRExists'] ); - - } - - // Process the data - if ( $is_secure OR $is_querydr_exists ) { - /** - * $vpc_MerchTxnRef looks like this "139_20170418101843" or {order_id}_{date_time} - * @see $this->get_pay_url(); - */ - $vpc_MerchTxnRef = $args['vpc_MerchTxnRef']; - $vpc_TxnResponseCode = $args['vpc_TxnResponseCode']; - - // Get the order_id part only - $order_id = substr($vpc_MerchTxnRef,0,strrpos($vpc_MerchTxnRef,'_')); - - $order = wc_get_order($order_id); - - // Add the order note for the reference - $order_note = sprintf( - __('OnePay Domestic Gateway Info | Code: %1$s | Message: %2$s | MerchantTxnRef: %3$s | Type: %4$s', 'woo-viet'), - $vpc_TxnResponseCode, - $this->OnePay_getResponseDescription($vpc_TxnResponseCode), - $vpc_MerchTxnRef, - $type - ); - $order->add_order_note($order_note); - - // If the payment is successful, update the order - if ("0" == $vpc_TxnResponseCode ) - $order->payment_complete(); - - switch ( $type ) { - - case 'return': - wp_redirect($this->get_return_url( $order )); - break; - - case 'ipn': - exit( 'responsecode=1&desc=confirm-success'); - break; - - case 'querydr': - // Do nothing - break; - } - - } else { - if ( 'ipn' == $type ) - exit('responsecode=0&desc=confirm-success'); - - } - } /** * Get the response description based on the response code @@ -332,9 +300,9 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { * * @return string */ - public function OnePay_getResponseDescription($responseCode) { + public function OnePay_getResponseDescription( $responseCode ) { - switch ($responseCode) { + switch ( $responseCode ) { case "0" : $result = "Giao dịch thành công - Approved"; break; @@ -383,7 +351,54 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { default : $result = "Giao dịch thất bại - Failured"; } + return $result; } + /** + * Handle the IPN POST request from OnePay + */ + public function handle_onepay_ipn() { + + if ( isset( $_REQUEST['vpc_SecureHash'] ) ) { + + $this->process_onepay_response_data( $_REQUEST, 'ipn' ); + + } + } + + /** + * Handle the queryDR request + * + * @param string $vpc_MerchTxnRef + */ + public function handle_onepay_querydr( $vpc_MerchTxnRef ) { + // Build the queryDR link + $args = array( + 'vpc_Command' => 'queryDR', + 'vpc_Version' => '1', + 'vpc_MerchTxnRef' => $vpc_MerchTxnRef, + 'vpc_Merchant' => $this->merchant_id, + 'vpc_AccessCode' => $this->access_code, + 'vpc_User' => $this->user, + 'vpc_Password' => $this->password, + ); + + $http_args = http_build_query( $args, '', '&' ); + + if ( $this->testmode ) { + $http_link = 'https://mtf.onepay.vn/onecomm-pay/Vpcdps.op?' . $http_args; + } else { + $http_link = 'https://onepay.vn/onecomm-pay/Vpcdps.op?' . $http_args; + } + + // Connect to OnePay to get the queryDR info + $http_response = wp_remote_get( $http_link ); + parse_str( wp_remote_retrieve_body( $http_response ), $args_response ); + + // Process the data + $this->process_onepay_response_data( $args_response, 'querydr' ); + + } + } diff --git a/inc/onepay/domestic-settings.php b/inc/onepay/domestic-settings.php index 80b24ad..99dcc41 100644 --- a/inc/onepay/domestic-settings.php +++ b/inc/onepay/domestic-settings.php @@ -8,13 +8,13 @@ if ( ! defined( 'ABSPATH' ) ) { * Settings for 1Pay Gateway. */ return array( - 'enabled' => array( + 'enabled' => array( 'title' => __( 'Enable/Disable', 'woo-viet' ), 'type' => 'checkbox', 'label' => __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ), 'default' => 'no' ), - 'testmode' => array( + 'testmode' => array( 'title' => __( 'OnePay Sandbox', 'woocommerce' ), 'type' => 'checkbox', 'label' => __( 'Enable OnePay sandbox (testing)', 'woocommerce' ), @@ -22,26 +22,26 @@ return array( 'description' => sprintf( __( 'OnePay sandbox can be used to test payments. See the testing info.', 'woocommerce' ), 'https://mtf.onepay.vn/developer/?page=modul_noidia' ), //@todo: add the logo https://mtf.onepay.vn/developer/?page=logo ), - 'title' => array( + 'title' => array( 'title' => __( 'Title', 'woo-viet' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'woo-viet' ), 'default' => __( 'OnePay Domestic Gateway', 'woo-viet' ), 'desc_tip' => true, ), - 'description' => array( + 'description' => array( 'title' => __( 'Description', 'woo-viet' ), 'type' => 'textarea', 'desc_tip' => true, 'description' => __( 'This controls the description which the user sees during checkout.', 'woo-viet' ), 'default' => __( 'With OnePay, you can make payment by using any local Vietnam ATM card.', 'woo-viet' ) ), - 'api_details' => array( + 'api_details' => array( 'title' => __( 'API Credentials', 'woo-viet' ), 'type' => 'title', 'description' => sprintf( __( 'Enter your OnePay API credentials. Contact OnePay to have your credentials %shere%s.', 'woo-viet' ), '', '' ), ), - 'merchant_id' => array( + 'merchant_id' => array( 'title' => __( 'Merchant ID', 'woo-viet' ), 'type' => 'text', 'description' => __( 'Get your Merchant ID from OnePay.', 'woo-viet' ), @@ -49,7 +49,7 @@ return array( 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) ), - 'access_code' => array( + 'access_code' => array( 'title' => __( 'Access Code', 'woocommerce' ), 'type' => 'text', 'description' => __( 'Get your Access Code from from OnePay.', 'woo-viet' ), @@ -65,7 +65,7 @@ return array( 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) ), - 'user' => array( + 'user' => array( 'title' => __( 'User for queryDR. Test value: op01', 'woocommerce' ), 'type' => 'text', 'description' => __( 'Get your user info from from OnePay.', 'woo-viet' ), @@ -73,7 +73,7 @@ return array( 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay', 'woo-viet' ) ), - 'password' => array( + 'password' => array( 'title' => __( 'Password for queryDR. Test value: op123456', 'woocommerce' ), 'type' => 'text', 'description' => __( 'Get your password info from from OnePay.', 'woo-viet' ), @@ -81,11 +81,11 @@ return array( 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) ), - 'more_info' => array( + 'more_info' => array( 'title' => __( 'Instant Payment Notification (IPN)', 'woo-viet' ), 'type' => 'title', 'description' => - sprintf('URL: %s', WooViet_OnePay_Domestic::get_onepay_ipn_url() ) . '

' . + sprintf( 'URL: %s', WooViet_OnePay_Domestic::get_onepay_ipn_url() ) . '

' . sprintf( __( '%sContact OnePay%s to configure this URL on its site. This is required based on its guidelines.', 'woo-viet' ), '', '' ), ), From 44c0a34fe8b0ea2e3e67ceb07b93162c34387564 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 11:47:46 +0700 Subject: [PATCH 12/18] Improve calling the cron job queryDR, avoid adding the note 2 times to the order Issue: OnePay Gateway - For the type return, the $order->add_order_note() run 2 times #19 --- woo-viet.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/woo-viet.php b/woo-viet.php index 7a79b50..17d4ad4 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -145,11 +145,13 @@ class WooViet { // Add the action to check the cron job for handling queryDR // It's not possible to add in the class "WooViet_OnePay_Domestic_Hook" because it's NOT always loadded - $this->WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); - add_action( 'wooviet_handle_onepay_querydr', array( - $this->WooViet_OnePay_Domestic_Hook, - 'handle_onepay_querydr' - ), 10, 1 ); + if ( defined( 'DOING_CRON' ) and DOING_CRON ) { + $this->WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); + add_action( 'wooviet_handle_onepay_querydr', array( + $this->WooViet_OnePay_Domestic_Hook, + 'handle_onepay_querydr' + ), 10, 1 ); + } } From 69c7dfae3c5cd5de2f826d0eb5e4f3077466ca08 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 11:48:27 +0700 Subject: [PATCH 13/18] Clean some redundant codes --- inc/class-wooviet-onepay-domestic.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index 641a860..c48487a 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -49,8 +49,6 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { add_action( 'woocommerce_api_' . strtolower( __CLASS__ ), array( $this, 'handle_onepay_ipn' ) ); - // @todo: check whether or not this can be lodded in the cron job - add_action( 'wooviet_handle_onepay_querydr', array( $this, 'handle_onepay_querydr' ), 10, 1 ); } /** @@ -140,7 +138,7 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { wp_schedule_single_event( time() + 20 * 60, 'wooviet_handle_onepay_querydr', - array( $vpc_MerchTxnRef ) // @todo check this + array( $vpc_MerchTxnRef ) ); } From 6c7627549991ad304b0acea997674e5fff0aa78f Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 12:15:15 +0700 Subject: [PATCH 14/18] OnePay - Add the bank logos in the checkout page #20 --- assets/onepay_domestic.png | Bin 0 -> 21876 bytes inc/class-wooviet-onepay-domestic.php | 3 ++- woo-viet.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 assets/onepay_domestic.png diff --git a/assets/onepay_domestic.png b/assets/onepay_domestic.png new file mode 100644 index 0000000000000000000000000000000000000000..92059e6a9251d1dc0b0be7b6599644b0496c91ac GIT binary patch literal 21876 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 z


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 literal 0 HcmV?d00001 diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index c48487a..b5e1afb 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -31,7 +31,8 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { // Define user set variables. $this->title = $this->get_option( 'title' ); - $this->description = $this->get_option( 'description' ); + $this->description = $this->get_option( 'description' ) . sprintf( '
', WOO_VIET_URL . 'assets/onepay_domestic.png' ); + $this->testmode = 'yes' === $this->get_option( 'testmode', 'no' ); $this->merchant_id = $this->get_option( 'merchant_id' ); $this->access_code = $this->get_option( 'access_code' ); diff --git a/woo-viet.php b/woo-viet.php index 17d4ad4..f2bede6 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { } define( 'WOO_VIET_DIR', plugin_dir_path( __FILE__ ) ); -// define( 'WOO_VIET_URL', plugins_url( '/', __FILE__ ) ); +define( 'WOO_VIET_URL', plugins_url( '/', __FILE__ ) ); /** * Start the instance From 8df0f118694549a34ab0cab0b7c96ea98dca1b08 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 12:47:24 +0700 Subject: [PATCH 15/18] Open OnePay for VND only --- inc/class-wooviet-admin-page.php | 11 ++++++++++- woo-viet.php | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/inc/class-wooviet-admin-page.php b/inc/class-wooviet-admin-page.php index c8bd503..b022f64 100644 --- a/inc/class-wooviet-admin-page.php +++ b/inc/class-wooviet-admin-page.php @@ -101,7 +101,16 @@ class WooViet_Admin_Page {
diff --git a/woo-viet.php b/woo-viet.php index f2bede6..319fe8d 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -138,7 +138,9 @@ class WooViet { $settings = self::get_settings(); // Check if "Add the OnePay Domestic Gateway" is enabled - if ( 'yes' == $settings['add_onepay_domestic']['enabled'] ) { + if ( 'yes' == $settings['add_onepay_domestic']['enabled'] + AND 'VND' == get_woocommerce_currency() + ) { include( 'inc/class-wooviet-onepay-domestic.php' ); add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) ); From 941438dda81004b18a3eaa34e39e4ae92a159959 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 15:49:49 +0700 Subject: [PATCH 16/18] Correct the typos --- inc/onepay/domestic-settings.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/inc/onepay/domestic-settings.php b/inc/onepay/domestic-settings.php index 99dcc41..9ac09bc 100644 --- a/inc/onepay/domestic-settings.php +++ b/inc/onepay/domestic-settings.php @@ -6,6 +6,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * Settings for 1Pay Gateway. + * @since 1.3 */ return array( 'enabled' => array( @@ -52,7 +53,7 @@ return array( 'access_code' => array( 'title' => __( 'Access Code', 'woocommerce' ), 'type' => 'text', - 'description' => __( 'Get your Access Code from from OnePay.', 'woo-viet' ), + 'description' => __( 'Get your Access Code from OnePay.', 'woo-viet' ), 'default' => '', 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) @@ -60,7 +61,7 @@ return array( 'secure_secret' => array( 'title' => __( 'Secure Secret', 'woocommerce' ), 'type' => 'text', - 'description' => __( 'Get your Secure Secret from from OnePay.', 'woo-viet' ), + 'description' => __( 'Get your Secure Secret from OnePay.', 'woo-viet' ), 'default' => '', 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) @@ -68,7 +69,7 @@ return array( 'user' => array( 'title' => __( 'User for queryDR. Test value: op01', 'woocommerce' ), 'type' => 'text', - 'description' => __( 'Get your user info from from OnePay.', 'woo-viet' ), + 'description' => __( 'Get your user info from OnePay.', 'woo-viet' ), 'default' => '', 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay', 'woo-viet' ) @@ -76,7 +77,7 @@ return array( 'password' => array( 'title' => __( 'Password for queryDR. Test value: op123456', 'woocommerce' ), 'type' => 'text', - 'description' => __( 'Get your password info from from OnePay.', 'woo-viet' ), + 'description' => __( 'Get your password info from OnePay.', 'woo-viet' ), 'default' => '', 'desc_tip' => true, 'placeholder' => __( 'Required. Provided by OnePay.', 'woo-viet' ) From 5d06fda9a90e4a8fa8995017b0e896c600efdcc8 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 16:28:43 +0700 Subject: [PATCH 17/18] Update the version and readme text files for 1.3 --- readme.md | 12 ++++++++++-- readme.txt | 16 +++++++++++++--- woo-viet.php | 2 +- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 7b6175c..7e8af69 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@ |Tags| WooCommerce Vietnam, vietnam, vietnamese, vietnam provinces, paypal for vietnam dong, vnd, vietnam dong, vietnam currency, vietnam customization | | Requires at least | 4.3 | | Tested up to | 4.7 | -| Stable tag | 1.2 | +| Stable tag | 1.3 | | License | GPLv2 or later | | License URI | https://www.gnu.org/licenses/gpl-2.0.html | @@ -22,8 +22,10 @@ Xem phiên bản tiếng Việt tại đây https://vi.wordpress.org/plugins/woo * Change the VND currency symbol `đ` to anything, e.g: `VND`, `VNĐ`, `đồng`, etc. * Add provinces for Vietnam when visitors select Vietnam as a country of the shipping (billing) address. This is not available in WooCommerce by default. +* Add districts to Vietnam provinces. * Convert `000` of prices to `K` (or anything). E.g: `50000` (VND) will be `50K` (VND), or `50 thousand` (VND). * Support `VND` for [the PayPal Standard gateway](https://docs.woocommerce.com/document/paypal-standard/). Convert `VND` prices to any PayPal supported currency before sending visitors to the PayPal pages. +* Add [the OnePay domestic (local ATM cards) gateway](http://onepay.com.vn/). ## ROAD MAP @@ -72,6 +74,12 @@ Follow these steps to install and use the plugin: ## Changelog +### 1.3 - 2017.04.22 +* Add [the OnePay domestic (local ATM cards) gateway](http://onepay.com.vn/) + +### 1.2 - 2017.03.03 +* Integrate all districts to Vietnam provinces. Credits: [WC City Select by 8manos](https://github.com/8manos/wc-city-select) and [the Vietnam district data by 10h30](https://github.com/htdat/woo-viet/issues/4#issuecomment-277449462) + ### 1.1 * Replace all “WooCommerce for Vietnam” to “Woo Viet” * Replace all “woocomerce-for-vietnam” to “woo-viet” @@ -79,4 +87,4 @@ Follow these steps to install and use the plugin: ### 1.0 * First release. -* Upload to WordPress.org +* Upload to WordPress.org \ No newline at end of file diff --git a/readme.txt b/readme.txt index 46295b2..668c1c1 100644 --- a/readme.txt +++ b/readme.txt @@ -1,9 +1,9 @@ === Woo Viet - WooCommerce for Vietnam === Contributors: htdat -Tags: WooCommerce Vietnam, vietnam, vietnamese, vietnam provinces, paypal for vietnam dong, vnd, vietnam dong, vietnam currency, vietnam customization +Tags: OnePay WooCommerce, OnePay Vietnam, WooCommerce Vietnam, vietnam, vietnamese, vietnam provinces, paypal for vietnam dong, vnd, vietnam dong, vietnam currency, vietnam customization Requires at least: 4.3 -Tested up to: 4.7.2 -Stable tag: 1.2 +Tested up to: 4.7.4 +Stable tag: 1.3 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -15,6 +15,9 @@ Add features to WooCommerce stores having anything related to Vietnam: currency, Xem phiên bản tiếng Việt tại đây https://vi.wordpress.org/plugins/woo-viet/ +**NEW FEATURE**: +Add [the OnePay domestic (local ATM cards) gateway](http://onepay.com.vn/). + = FEATURES = * Change the VND currency symbol `đ` to anything, e.g: `VND`, `VNĐ`, `đồng`, etc. @@ -22,6 +25,7 @@ Xem phiên bản tiếng Việt tại đây https://vi.wordpress.org/plugins/woo * Add districts to Vietnam provinces. * Convert `000` of prices to `K` (or anything). E.g: `50000` (VND) will be `50K` (VND), or `50 thousand` (VND). * Support `VND` for [the PayPal Standard gateway](https://docs.woocommerce.com/document/paypal-standard/). Convert `VND` prices to any PayPal supported currency before sending visitors to the PayPal pages. +* Add [the OnePay domestic (local ATM cards) gateway](http://onepay.com.vn/). = ROAD MAP = @@ -70,6 +74,9 @@ Follow these steps to install and use the plugin: == Changelog == += 1.3 - 2017.04.22 = +* Add [the OnePay domestic (local ATM cards) gateway](http://onepay.com.vn/). + = 1.2 - 2017.03.03 = * Integrate all districts to Vietnam provinces. Credits: [WC City Select by 8manos](https://github.com/8manos/wc-city-select) and [the Vietnam district data by 10h30](https://github.com/htdat/woo-viet/issues/4#issuecomment-277449462) @@ -84,5 +91,8 @@ Follow these steps to install and use the plugin: == Upgrade Notice == += 1.3 = +The new version 1.2 comes with the feature "Add the OnePay domestic (local ATM cards) gateway]" + = 1.2 = The new version 1.2 comes with the feature "Add districts to Vietnam provinces". diff --git a/woo-viet.php b/woo-viet.php index 319fe8d..522435d 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -7,7 +7,7 @@ * Author URI: https://profiles.wordpress.org/htdat * Text Domain: woo-viet * Domain Path: /languages - * Version: 1.3-dev + * Version: 1.3 * License: GPLv2+ */ From 621f52167b09e8e778759d44bc566316c0e2819e Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 16:38:30 +0700 Subject: [PATCH 18/18] Update the screenshots and their descriptions --- readme.txt | 2 +- screenshot-1.png | Bin 31096 -> 44065 bytes screenshot-3.png | Bin 15930 -> 16885 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 668c1c1..8bc2146 100644 --- a/readme.txt +++ b/readme.txt @@ -69,7 +69,7 @@ Follow these steps to install and use the plugin: 1. The settings page under WooCommerce -> Woo Viet. 2. Prices are changed to "K", and the symbol is now "VND". -3. List provinces when selecting Vietnam. +3. List provinces and districts when selecting Vietnam. 4. Let clients know about the currency conversion before switching to the PayPal pages. == Changelog == diff --git a/screenshot-1.png b/screenshot-1.png index c4dfefb343df21da0b94bde1fd0f66398774f78f..26c3aa1f84f43c90f29c85665515bc88cb4227bc 100644 GIT binary patch literal 44065 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
jl{EgNLr z#i@B2L!=k6MPwNvJ1b%ZH#5-S-A&Mg=C0&WoL}K?N~w#yNWCdXj#Rz;nnc|snHIQ9 zE(TRhUzsW~CxAao(~MBH{phP0MY`20AHVb$$m$ePdncw9J+o{J`kl1(biCmTVv3Li z@iZU|>zeZ-&q9b>5YDakZ0*kl=0kktKA+pn)|xCPE{h+M`oh46bfY&!wP{M8qs>ad zNOs3I6fhF`tRSK}Q6gKOSN;5tnHMj7*x*A1t3oi4L)iJhPTP+KD-hUZ!OPXajnhdy zQ-G79T`sJvY=`ZP4kS_ugdO#Yy!OH?a6ew8dJ^Q>*t!;u8kmvV#$|{#M+lGrX26a@ zpgCK#^C-FJNHQ(_0(Tgu20pN)G$+J;Wpb(n{BPdmh-f;155)kEjyN2BmC*~Lkn@<292x6a07Iv2d5u_!evE?y)wanv3;4&LvN+gk;5rD;* zNE%_oXq@CI0|1}B4GFy}`% zucQsiFo_cUS7@9K2gvfnFJZVAP9&xT_}?=)Kq@M-n&iQa z$(FF3A?56BSu`oON^)iawqac6RHbLkD*fyrKzN(UFS6ERLjd;DQqxm?qihrPe*hGJ B>=Xb1 literal 31096 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 M1}a@8X%zT>04R}I>i_@% diff --git a/screenshot-3.png b/screenshot-3.png index 9a27bf816b6d75b3010ab84abe24285adc1149fc..c44e560cb816f442095e7c9023d10b74e495dd31 100644 GIT binary patch literal 16885 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

cUMxn;t&s$6E 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

+ + > + +
+
+ +
diff --git a/woo-viet.php b/woo-viet.php index d1b85ee..4dcca12 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -60,7 +60,11 @@ class WooViet { 'currency' => 'USD', 'rate' => '22770', ), - ); + 'add_onepay_domestic' => + array( + 'enabled' => 'yes', + ), + ); /** * The properties to manage all classes under the "inc/" folder * Example: @@ -131,14 +135,6 @@ class WooViet { */ public function main() { - // @todo: ver 1.3 check this - add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) ); - - include( 'inc/class-wooviet-onepay-domestic.php'); - $WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); - add_action('wooviet_handle_onepay_querydr', array($WooViet_OnePay_Domestic_Hook, 'handle_onepay_querydr'), 10, 1); - - if ( is_admin() ) { // Add the admin setting page include( WOO_VIET_DIR . 'inc/class-wooviet-admin-page.php' ); @@ -147,6 +143,16 @@ class WooViet { } $settings = self::get_settings(); + // Check if "Add the OnePay Domestic Gateway" is enabled + if ( 'yes' == $settings['add_onepay_domestic']['enabled'] ) { + // @todo: ver 1.3 check this + add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) ); + + include( 'inc/class-wooviet-onepay-domestic.php'); + $WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); + add_action('wooviet_handle_onepay_querydr', array($WooViet_OnePay_Domestic_Hook, 'handle_onepay_querydr'), 10, 1); + + } // Check if "Add provinces for Vietnam " is enabled. if ( 'yes' == $settings['add_province']['enabled'] ) { From 0d07ecca4c29a9087f4895ed302e3779369e5a41 Mon Sep 17 00:00:00 2001 From: htdat Date: Thu, 20 Apr 2017 17:40:14 +0700 Subject: [PATCH 06/18] Change the dev version --- woo-viet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/woo-viet.php b/woo-viet.php index 4dcca12..f5ef1a9 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -7,7 +7,7 @@ * Author URI: https://profiles.wordpress.org/htdat * Text Domain: woo-viet * Domain Path: /languages - * Version: 1.2 + * Version: 1.3-dev * License: GPLv2+ */ From 9fe23bd609f5b167f20f6b3820475c17e48bdbd6 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 09:37:05 +0700 Subject: [PATCH 07/18] Make the process data better - require $type --- inc/class-wooviet-onepay-domestic.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index 4394147..036c963 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -203,7 +203,7 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { if (isset($_POST['vpc_SecureHash'])) { - $this->process_onepay_response_data( $_POST ); + $this->process_onepay_response_data( $_POST, 'ipn' ); } } @@ -237,7 +237,7 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { parse_str( wp_remote_retrieve_body( $http_response ), $args_response ); // Process the data - $this->process_onepay_response_data($args_response); + $this->process_onepay_response_data($args_response, 'querydr'); } @@ -246,7 +246,7 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { * @param string $args the response data from OnePay * @param string $type */ - public function process_onepay_response_data ($args, $type = '' ) { + public function process_onepay_response_data ($args, $type ) { $types_accepted = array( 'return', 'ipn', From 58022a6650d040daeebe1c3ec02f78b387747114 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 09:48:29 +0700 Subject: [PATCH 08/18] Improve and reformat code for the main file --- woo-viet.php | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/woo-viet.php b/woo-viet.php index f5ef1a9..7a79b50 100644 --- a/woo-viet.php +++ b/woo-viet.php @@ -40,7 +40,7 @@ class WooViet { array( 'enabled' => 'yes', ), - 'add_city' => + 'add_city' => array( 'enabled' => 'yes', ), @@ -60,11 +60,11 @@ class WooViet { 'currency' => 'USD', 'rate' => '22770', ), - 'add_onepay_domestic' => + 'add_onepay_domestic' => array( 'enabled' => 'yes', ), - ); + ); /** * The properties to manage all classes under the "inc/" folder * Example: @@ -123,13 +123,6 @@ class WooViet { load_plugin_textdomain( 'woo-viet', false, basename( dirname( __FILE__ ) ) . '/languages/' ); } - - public function add_gateway_class( $methods ) { - $methods[] = 'WooViet_OnePay_Domestic'; - return $methods; - - } - /** * The main method to load the components */ @@ -143,14 +136,20 @@ class WooViet { } $settings = self::get_settings(); + // Check if "Add the OnePay Domestic Gateway" is enabled if ( 'yes' == $settings['add_onepay_domestic']['enabled'] ) { - // @todo: ver 1.3 check this + include( 'inc/class-wooviet-onepay-domestic.php' ); + add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) ); - include( 'inc/class-wooviet-onepay-domestic.php'); - $WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); - add_action('wooviet_handle_onepay_querydr', array($WooViet_OnePay_Domestic_Hook, 'handle_onepay_querydr'), 10, 1); + // Add the action to check the cron job for handling queryDR + // It's not possible to add in the class "WooViet_OnePay_Domestic_Hook" because it's NOT always loadded + $this->WooViet_OnePay_Domestic_Hook = new WooViet_OnePay_Domestic(); + add_action( 'wooviet_handle_onepay_querydr', array( + $this->WooViet_OnePay_Domestic_Hook, + 'handle_onepay_querydr' + ), 10, 1 ); } @@ -198,7 +197,23 @@ class WooViet { static function get_settings() { $settings = get_option( 'woo-viet', self::$default_settings ); $settings = wp_parse_args( $settings, self::$default_settings ); + return $settings; } + /** + * Add the gateways to WooCommerce + * + * @param array $methods + * + * @since 1.3 + * @return array + */ + public function add_gateway_class( $methods ) { + $methods[] = 'WooViet_OnePay_Domestic'; + + return $methods; + + } + } \ No newline at end of file From 4f73556b278a1eddc0912e9febeda4b012be37dd Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 09:58:48 +0700 Subject: [PATCH 09/18] Correct the code for IPN Use exit() instead of wp_die() --- inc/class-wooviet-onepay-domestic.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/inc/class-wooviet-onepay-domestic.php b/inc/class-wooviet-onepay-domestic.php index 036c963..cd39918 100644 --- a/inc/class-wooviet-onepay-domestic.php +++ b/inc/class-wooviet-onepay-domestic.php @@ -201,9 +201,9 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { */ public function handle_onepay_ipn() { - if (isset($_POST['vpc_SecureHash'])) { + if (isset($_REQUEST['vpc_SecureHash'])) { - $this->process_onepay_response_data( $_POST, 'ipn' ); + $this->process_onepay_response_data( $_REQUEST, 'ipn' ); } } @@ -309,7 +309,7 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { break; case 'ipn': - wp_die('responsecode=1&desc=confirm-success'); + exit( 'responsecode=1&desc=confirm-success'); break; case 'querydr': @@ -319,7 +319,8 @@ class WooViet_OnePay_Domestic extends WC_Payment_Gateway { } else { if ( 'ipn' == $type ) - wp_die('responsecode=0&desc=confirm-success'); + exit('responsecode=0&desc=confirm-success'); + } } From dc226abb88a533e48db002543f5394321dc15179 Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 10:34:02 +0700 Subject: [PATCH 10/18] Change: 1.3 - OnePay Domestic Gateway should not be active by default #18 --- inc/onepay/domestic-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/onepay/domestic-settings.php b/inc/onepay/domestic-settings.php index 522cb14..80b24ad 100644 --- a/inc/onepay/domestic-settings.php +++ b/inc/onepay/domestic-settings.php @@ -12,7 +12,7 @@ return array( 'title' => __( 'Enable/Disable', 'woo-viet' ), 'type' => 'checkbox', 'label' => __( 'OnePay Domestic Gateway (by Woo Viet)', 'woo-viet' ), - 'default' => 'yes' + 'default' => 'no' ), 'testmode' => array( 'title' => __( 'OnePay Sandbox', 'woocommerce' ), From a33745b8502c6091e063a62a5c045f14d9fc104b Mon Sep 17 00:00:00 2001 From: htdat Date: Sat, 22 Apr 2017 10:40:10 +0700 Subject: [PATCH 11/18] Reformat code by PHPStorm --- inc/class-wooviet-admin-page.php | 19 +- inc/class-wooviet-onepay-domestic.php | 449 +++++++++++++------------- inc/onepay/domestic-settings.php | 22 +- 3 files changed, 253 insertions(+), 237 deletions(-) diff --git a/inc/class-wooviet-admin-page.php b/inc/class-wooviet-admin-page.php index f81f2a6..c8bd503 100644 --- a/inc/class-wooviet-admin-page.php +++ b/inc/class-wooviet-admin-page.php @@ -92,16 +92,17 @@ class WooViet_Admin_Page { - > + >


+

> + >