From 0dd89a0e7ff2e897bb3a97d6da2c05eb9b9abdbf Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 09:09:25 -0500 Subject: [PATCH 1/8] Harden plugin against SQL injection --- zgopmtgwy.php | 94 +++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/zgopmtgwy.php b/zgopmtgwy.php index d1d5d75..6a6326e 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -238,31 +238,33 @@ function zgopmt_init() { // // Save ZGo Order ID and Cart order // - $sql = "replace into zgo_payments (" . - "pmt_orderid," . - "pmt_wc_order," . - "pmt_wc_custname," . - "pmt_accepted," . - "pmt_confirmed," . - "pmt_amount," . - "pmt_rate," . - "pmt_zec," . - "pmt_wc_paid) values ('" . - $zgoOrderid . "','" . - $order_id . "','" . - $order->get_billing_first_name() . " " . - $order->get_billing_last_name() . "','" . - date('Y-m-d H:i:s') . "','',". - $order->get_total() . - ",0,0,0)"; - $wpdb->query($sql); + $sql3 = $wpdb->prepare('replace into zgo_payments (pmt_orderid, pmt_wc_order, pmt_wc_custname, pmt_accepted, pmt_confirmed, pmt_amount, pmt_rate, pmt_zec, pmt_wc_paid) values (%s, %s, %s, %s, %s, %f, 0, 0, 0);', + $zgoOrderid, $order_id, $order-get_billing_last_name(), date('Y-m-d H:i:s'), '', $order->get_total()) + //$sql = "replace into zgo_payments (" . + //"pmt_orderid," . + //"pmt_wc_order," . + //"pmt_wc_custname," . + //"pmt_accepted," . + //"pmt_confirmed," . + //"pmt_amount," . + //"pmt_rate," . + //"pmt_zec," . + //"pmt_wc_paid) values ('" . + //$zgoOrderid . "','" . + //$order_id . "','" . + //$order->get_billing_first_name() . " " . + //$order->get_billing_last_name() . "','" . + //date('Y-m-d H:i:s') . "','',". + //$order->get_total() . + //",0,0,0)"; + $wpdb->query($sql3); // Remove cart. WC()->cart->empty_cart(); return array( - 'result' => 'success', - 'redirect' => 'https://app.zgo.cash/invoice/' . $zgoOrderid, + 'result' => 'success', + 'redirect' => 'https://app.zgo.cash/invoice/' . $zgoOrderid, ); break; case 202: @@ -290,40 +292,42 @@ function zgopmt_init() { $rate = $_GET['rate']; $order = wc_get_order( $orderid ); - $sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; + $sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s;', $orderid); + //$sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; $result = $wpdb->get_row($sql,OBJECT); if ( ! is_null($result) ) { - if ( ( $token == $this->zgotoken ) - && ( $result->pmt_orderid == $zgoOrderid ) - && ( $result->pmt_wc_paid == '0' ) ) { + if ( ( hash('sha256', $token) == hash('sha256', $this->zgotoken) ) + && ( $result->pmt_orderid == $zgoOrderid ) + && ( $result->pmt_wc_paid == '0' ) ) { switch ( $order->get_status() ) { - case 'pending': - case 'failed': - $order->payment_complete(); - $order->reduce_order_stock(); - // - // Mark order as completed in ZGo DB - // - $sql = "update zgo_payments set " . - "pmt_confirmed='" . date('Y-m-d H:i:s') . - "', pmt_rate=" . $rate . - ", pmt_zec=" . $totalzec . - ", pmt_wc_paid=1 " . - " where pmt_wc_order='" . $orderid . "';"; - $wpdb->query($sql); + case 'pending': + case 'failed': + $order->payment_complete(); + $order->reduce_order_stock(); + // + // Mark order as completed in ZGo DB + // + //$sql = "update zgo_payments set " . + //"pmt_confirmed='" . date('Y-m-d H:i:s') . + //"', pmt_rate=" . $rate . + //", pmt_zec=" . $totalzec . + //", pmt_wc_paid=1 " . + //" where pmt_wc_order='" . $orderid . "';"; + $sql2 = $wpdb->prepare('update zgo_payments set pmt_confirmed = %s, pmt_rate = %f, pmt_zec = %f, pmt_wc_paid = 1 where pmt_wc_order = %s;', date('Y-m-d H:i:s'), $rate, $totalzec, $orderid ); + $wpdb->query($sql2); - update_option('webhook_debug', $_GET); - break; - default: -// $this->console_log('Order ' . $orderid . ' already paid or cancelled...'); - break; + update_option('webhook_debug', $_GET); + break; + default: + // $this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + break; } } else { -// $this->console_log('Invalid parameters...'); + // $this->console_log('Invalid parameters...'); } } else { -// $this->console_log('Database error...'); + // $this->console_log('Database error...'); } } From 08690a29a5d13e6564b929cf3580ffede5c999cc Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 09:29:08 -0500 Subject: [PATCH 2/8] Remove XSS vulnerabilities --- assets/php/zpmt-stats-page.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/php/zpmt-stats-page.php b/assets/php/zpmt-stats-page.php index 08c94c8..da96779 100644 --- a/assets/php/zpmt-stats-page.php +++ b/assets/php/zpmt-stats-page.php @@ -35,23 +35,23 @@ class zpmt_stats_page { $wpdb->query($sql); if ( ! $this->pmtLstRdy() ) { - // - // Calculate first time pagination paramters - // - $this->_limit = 10; + // + // Calculate first time pagination paramters + // + $this->_limit = 10; $this->_page = 1; $this->_offset = 0; $this->_npages = intdiv($this->_nrows,$this->_limit); if ( $this->_nrows > ($this->_npages*$this->_limit) ) { - $this->_npages++; - } + $this->_npages++; + } - $sql = 'insert into zgo_pmtlst (pg_ix,pg_page,pg_npages,pg_offset,pg_limit) values (1,' . - $this->_page . ',' . - $this->_npages . ',' . - $this->_offset . ',' . - $this->_limit .')'; - $wpdb->query($sql); + $sql = 'insert into zgo_pmtlst (pg_ix,pg_page,pg_npages,pg_offset,pg_limit) values (1,' . + $this->_page . ',' . + $this->_npages . ',' . + $this->_offset . ',' . + $this->_limit .')'; + $wpdb->query($sql); } else { // Load last state $params = $this->pmtLstParams(); @@ -232,9 +232,9 @@ class zpmt_stats_page { font-weight: 600;">'; } $line++; - print '' . $row->pmt_orderid . ""; + print '' . htmlentities($row->pmt_orderid, ENT_QUOTES) . ""; print "" . $row->pmt_wc_order . ""; - print "" . $row->pmt_wc_custname . ""; + print "" . htmlentities($row->pmt_wc_custname, ENT_QUOTES) . ""; print ''. $row->pmt_accepted . ""; print ''.$row->pmt_confirmed .""; print ''. number_format($row->pmt_amount,2) . ""; From 2e8aaa1f1a25a54708639e4b17e24f7f43f95fe7 Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 10:23:52 -0500 Subject: [PATCH 3/8] Fix code for deployment --- zgopmtgwy.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zgopmtgwy.php b/zgopmtgwy.php index 6a6326e..e8fec89 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -190,8 +190,8 @@ function zgopmt_init() { $oid = json_decode($body); $isvalid = $oid->{'authorized'}; break; - case 202:git - $body = wp_remote_retrieve_body($response ); + case 202: + $body = wp_remote_retrieve_body($response ); $oid = json_decode($body); break; default: @@ -239,7 +239,7 @@ function zgopmt_init() { // Save ZGo Order ID and Cart order // $sql3 = $wpdb->prepare('replace into zgo_payments (pmt_orderid, pmt_wc_order, pmt_wc_custname, pmt_accepted, pmt_confirmed, pmt_amount, pmt_rate, pmt_zec, pmt_wc_paid) values (%s, %s, %s, %s, %s, %f, 0, 0, 0);', - $zgoOrderid, $order_id, $order-get_billing_last_name(), date('Y-m-d H:i:s'), '', $order->get_total()) + $zgoOrderid, $order_id, $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(), date('Y-m-d H:i:s'), '', $order->get_total()); //$sql = "replace into zgo_payments (" . //"pmt_orderid," . //"pmt_wc_order," . From 244a2cc80e0236fdde0146210a7d0f3e4b651c6f Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 10:46:13 -0500 Subject: [PATCH 4/8] Prepare for test server --- zgopmtgwy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zgopmtgwy.php b/zgopmtgwy.php index e8fec89..4a70020 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -174,7 +174,7 @@ function zgopmt_init() { if ( isset($this->zgoownerid) && ($this->zgoownerid !== '') ) { - $url = 'https://api.zgo.cash//auth?ownerid=' . + $url = 'https://test.zgo.cash/auth?ownerid=' . $this->zgoownerid . '&token=' . $this->zgotoken . '&siteurl=' . $this->base64url_encode($this->siteURL); From 1768f700bbc69c6d7f96e02f1241570be8350afe Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 11:08:17 -0500 Subject: [PATCH 5/8] Update ZGo API call to new security parameters --- zgopmtgwy.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/zgopmtgwy.php b/zgopmtgwy.php index 4a70020..1d2a39f 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -213,7 +213,7 @@ function zgopmt_init() { $wc_order_key = $order->get_order_key(); - $url = 'https://api.zgo.cash/woopayment' . + $url = 'https://test.zgo.cash/woopayment' . '?ownerid=' . $this->zgoownerid . '&token=' . $this->zgotoken . '&order_id=' . $order_id . @@ -235,6 +235,7 @@ function zgopmt_init() { $body = wp_remote_retrieve_body( $response ); $oid = json_decode($body); $zgoOrderid = $oid->{'order'}; + $zgoOrderToken = $oid->{'token'}; // // Save ZGo Order ID and Cart order // @@ -264,7 +265,7 @@ function zgopmt_init() { return array( 'result' => 'success', - 'redirect' => 'https://app.zgo.cash/invoice/' . $zgoOrderid, + 'redirect' => 'https://dev.zgo.cash/invoice/' . $zgoOrderid . '?token=' . $zgoOrderToken, ); break; case 202: From 46fc016dc7208ab19e2f9c7efd7454d99d218e99 Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 11:49:12 -0500 Subject: [PATCH 6/8] Format code --- zgopmtgwy.php | 388 +++++++++++++++++++++++++------------------------- 1 file changed, 194 insertions(+), 194 deletions(-) diff --git a/zgopmtgwy.php b/zgopmtgwy.php index 1d2a39f..7f55f0b 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -1,35 +1,35 @@ query($sql); + $wpdb->query($sql); $iconurl = plugin_dir_url( __FILE__ ) . - 'assets/img/zgo-icon-full_6pct.png'; + 'assets/img/zgo-icon-full_6pct.png'; $this->siteURL = get_site_url(); @@ -72,9 +72,9 @@ function zgopmt_init() { $this->icon = $iconurl; $this->has_fields = false; $this->method_title = __('ZGo Payment', - $this->domain); + $this->domain); $this->method_description = __('ZGo Payment - Accept payments using Zcash.', $this->domain); - // Load the settings. + // Load the settings. $this->init_form_fields(); $this->init_settings(); @@ -86,206 +86,206 @@ function zgopmt_init() { // Actions add_action('woocommerce_update_options_payment_gateways_' . - $this->id, - array( $this, 'process_admin_options' ) ); + $this->id, + array( $this, 'process_admin_options' ) ); - add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) ); + add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) ); if ( ! $this->is_valid_for_use() ) $this->enabled = false; /** - * Add the webhook for payment confirmation from ZGo - */ + * Add the webhook for payment confirmation from ZGo + */ add_action( 'woocommerce_api_zpmtcallback', array($this,'zconfirm')); - } + } public function init_form_fields() { $this->form_fields = apply_filters( - 'woo_zgopmtsrv_fields', array( - 'enabled' => array( - 'title' => __('Enable/Disable', - $this->domain ), - 'type' => 'checkbox', - 'label' => __('Enable payments with Zcash', $this->domain ), - 'default' => 'yes' - ), - 'title' => array( - 'title' => __( 'ZGo Payment Service title', - $this->domain ), - 'type' => 'text', - 'default' => __( 'ZGo Payment Gateway', - $this->domain ), - 'desc_tip' => true, - 'description' => __( 'Add a new title for the ZGo Payment Service that your customers will see when they are in the checkout page', - $this->domain ), - ), - 'description' => array( - 'title' => __( 'ZGo Payment Service Confirmation', - $this->domain ), - 'type' => 'textarea', - 'default' => __( 'Pay with Zcash, ZGo will report your payment as soon as it gets confirmed. Normally it takes about 5 minutes.
Read more...', - $this->domain ), - 'desc_tip' => true, - 'description' => __('Payment confirmation description that the customer will see on your checkout.', - $this->domain ), - ), - 'instructions' => array( - 'title' => __('Instructions', - $this->domain ), - 'type' => 'textarea', - 'default' => __('Default instrctions', - $this->domain ), - 'desc_tip' => true, - 'description' => __('Instruction that will be added to the Thank You page and order email', - $this->domain ), - ), - 'zgoownerid' => array( - 'title' => __( 'ZGo OwnerId', - $this->domain ), - 'type' => 'text', - 'default' => __( 'Replace this text with your ZGo Owner ID ', - $this->domain ), - 'desc_tip' => true, - 'description' => __( 'Type or paste your ZGo Account Owner Id (Found in your ZGo Shop Settings)', - $this->domain ), - ), - 'zgotoken' => array( - 'title' => __( 'ZGo Token', - $this->domain ), - 'type' => 'text', - 'default' => __( 'Replace this text with your ZGo Token', - $this->domain ), - 'desc_tip' => true, - 'description' => __( 'Type or paste your ZGo Token (Found in your ZGo Shop Settings)', - $this->domain ), - ), - ) + 'woo_zgopmtsrv_fields', array( + 'enabled' => array( + 'title' => __('Enable/Disable', + $this->domain ), + 'type' => 'checkbox', + 'label' => __('Enable payments with Zcash', $this->domain ), + 'default' => 'yes' + ), + 'title' => array( + 'title' => __( 'ZGo Payment Service title', + $this->domain ), + 'type' => 'text', + 'default' => __( 'ZGo Payment Gateway', + $this->domain ), + 'desc_tip' => true, + 'description' => __( 'Add a new title for the ZGo Payment Service that your customers will see when they are in the checkout page', + $this->domain ), + ), + 'description' => array( + 'title' => __( 'ZGo Payment Service Confirmation', + $this->domain ), + 'type' => 'textarea', + 'default' => __( 'Pay with Zcash, ZGo will report your payment as soon as it gets confirmed. Normally it takes about 5 minutes.
Read more...', + $this->domain ), + 'desc_tip' => true, + 'description' => __('Payment confirmation description that the customer will see on your checkout.', + $this->domain ), + ), + 'instructions' => array( + 'title' => __('Instructions', + $this->domain ), + 'type' => 'textarea', + 'default' => __('Default instrctions', + $this->domain ), + 'desc_tip' => true, + 'description' => __('Instruction that will be added to the Thank You page and order email', + $this->domain ), + ), + 'zgoownerid' => array( + 'title' => __( 'ZGo OwnerId', + $this->domain ), + 'type' => 'text', + 'default' => __( 'Replace this text with your ZGo Owner ID ', + $this->domain ), + 'desc_tip' => true, + 'description' => __( 'Type or paste your ZGo Account Owner Id (Found in your ZGo Shop Settings)', + $this->domain ), + ), + 'zgotoken' => array( + 'title' => __( 'ZGo Token', + $this->domain ), + 'type' => 'text', + 'default' => __( 'Replace this text with your ZGo Token', + $this->domain ), + 'desc_tip' => true, + 'description' => __( 'Type or paste your ZGo Token (Found in your ZGo Shop Settings)', + $this->domain ), + ), + ) ); } /* - * Check if configuration is valid - */ - public function is_valid_for_use() { - - $isvalid = false; + * Check if configuration is valid + */ + public function is_valid_for_use() { - if ( isset($this->zgoownerid) && - ($this->zgoownerid !== '') ) { + $isvalid = false; + + if ( isset($this->zgoownerid) && + ($this->zgoownerid !== '') ) { $url = 'https://test.zgo.cash/auth?ownerid=' . - $this->zgoownerid . '&token=' . - $this->zgotoken . '&siteurl=' . - $this->base64url_encode($this->siteURL); + $this->zgoownerid . '&token=' . + $this->zgotoken . '&siteurl=' . + $this->base64url_encode($this->siteURL); - $response = wp_remote_get($url); - - $httpcode = wp_remote_retrieve_response_code( $response ); + $response = wp_remote_get($url); - switch ( $httpcode ) { + $httpcode = wp_remote_retrieve_response_code( $response ); + + switch ( $httpcode ) { case 200: $body = wp_remote_retrieve_body( $response ); $oid = json_decode($body); - $isvalid = $oid->{'authorized'}; - break; - case 202: - $body = wp_remote_retrieve_body($response ); + $isvalid = $oid->{'authorized'}; + break; + case 202: + $body = wp_remote_retrieve_body($response ); $oid = json_decode($body); - break; + break; default: - break; - } - } + break; + } + } return $isvalid; } /* - * Process Payment - */ + * Process Payment + */ public function process_payment( $order_id ) { global $wpdb; $order = wc_get_order( $order_id ); -// $wc_order = wc_get_product($order_id); + // $wc_order = wc_get_product($order_id); $wc_order_key = $order->get_order_key(); $url = 'https://test.zgo.cash/woopayment' . '?ownerid=' . $this->zgoownerid . '&token=' . $this->zgotoken . - '&order_id=' . $order_id . + '&order_id=' . $order_id . '¤cy=' . strtolower($order->get_currency()) . '&amount=' . $order->get_total() . '&date=' . date_format($order->get_date_created(),'Y-m-d') . - '&siteurl=' . $this->base64url_encode($this->siteURL) . - '&orderkey=' . $wc_order_key; + '&siteurl=' . $this->base64url_encode($this->siteURL) . + '&orderkey=' . $wc_order_key; - //'&orderkey=' . ; + //'&orderkey=' . ; $response = wp_remote_get($url); $httpcode = wp_remote_retrieve_response_code( $response ); switch ( $httpcode ) { - case 200: - wc_add_notice( 'Order on hold, please wait for confirmation'); - $order->update_status('on_hold',__('Awaiting payment confirmation','woocommerce')); - $body = wp_remote_retrieve_body( $response ); - $oid = json_decode($body); - $zgoOrderid = $oid->{'order'}; - $zgoOrderToken = $oid->{'token'}; - // - // Save ZGo Order ID and Cart order - // - $sql3 = $wpdb->prepare('replace into zgo_payments (pmt_orderid, pmt_wc_order, pmt_wc_custname, pmt_accepted, pmt_confirmed, pmt_amount, pmt_rate, pmt_zec, pmt_wc_paid) values (%s, %s, %s, %s, %s, %f, 0, 0, 0);', - $zgoOrderid, $order_id, $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(), date('Y-m-d H:i:s'), '', $order->get_total()); - //$sql = "replace into zgo_payments (" . - //"pmt_orderid," . - //"pmt_wc_order," . - //"pmt_wc_custname," . - //"pmt_accepted," . - //"pmt_confirmed," . - //"pmt_amount," . - //"pmt_rate," . - //"pmt_zec," . - //"pmt_wc_paid) values ('" . - //$zgoOrderid . "','" . - //$order_id . "','" . - //$order->get_billing_first_name() . " " . - //$order->get_billing_last_name() . "','" . - //date('Y-m-d H:i:s') . "','',". - //$order->get_total() . - //",0,0,0)"; - $wpdb->query($sql3); + case 200: + wc_add_notice( 'Order on hold, please wait for confirmation'); + $order->update_status('on_hold',__('Awaiting payment confirmation','woocommerce')); + $body = wp_remote_retrieve_body( $response ); + $oid = json_decode($body); + $zgoOrderid = $oid->{'order'}; + $zgoOrderToken = $oid->{'token'}; + // + // Save ZGo Order ID and Cart order + // + $sql3 = $wpdb->prepare('replace into zgo_payments (pmt_orderid, pmt_wc_order, pmt_wc_custname, pmt_accepted, pmt_confirmed, pmt_amount, pmt_rate, pmt_zec, pmt_wc_paid) values (%s, %s, %s, %s, %s, %f, 0, 0, 0);', + $zgoOrderid, $order_id, $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(), date('Y-m-d H:i:s'), '', $order->get_total()); + //$sql = "replace into zgo_payments (" . + //"pmt_orderid," . + //"pmt_wc_order," . + //"pmt_wc_custname," . + //"pmt_accepted," . + //"pmt_confirmed," . + //"pmt_amount," . + //"pmt_rate," . + //"pmt_zec," . + //"pmt_wc_paid) values ('" . + //$zgoOrderid . "','" . + //$order_id . "','" . + //$order->get_billing_first_name() . " " . + //$order->get_billing_last_name() . "','" . + //date('Y-m-d H:i:s') . "','',". + //$order->get_total() . + //",0,0,0)"; + $wpdb->query($sql3); - // Remove cart. - WC()->cart->empty_cart(); + // Remove cart. + WC()->cart->empty_cart(); - return array( - 'result' => 'success', - 'redirect' => 'https://dev.zgo.cash/invoice/' . $zgoOrderid . '?token=' . $zgoOrderToken, - ); - break; - case 202: - $body = wp_remote_retrieve_body( $response ); - $msg = json_decode($body); - $order->update_status('failed',__('Order ' . $order_id . ' -> ZGo Order Generation Error : ' . $msg->{'message'},'woocommerce')); + return array( + 'result' => 'success', + 'redirect' => 'https://dev.zgo.cash/invoice/' . $zgoOrderid . '?token=' . $zgoOrderToken, + ); + break; + case 202: + $body = wp_remote_retrieve_body( $response ); + $msg = json_decode($body); + $order->update_status('failed',__('Order ' . $order_id . ' -> ZGo Order Generation Error : ' . $msg->{'message'},'woocommerce')); - break; - default: - return; + break; + default: + return; } } /** - * Confirm payment and complete order - */ + * Confirm payment and complete order + */ public function zconfirm() { - global $wpdb; - + global $wpdb; + $token = $_GET['token']; $zgoOrderid = $_GET['orderid']; $orderid = $_GET['wc_orderid']; @@ -310,11 +310,11 @@ function zgopmt_init() { // Mark order as completed in ZGo DB // //$sql = "update zgo_payments set " . - //"pmt_confirmed='" . date('Y-m-d H:i:s') . - //"', pmt_rate=" . $rate . - //", pmt_zec=" . $totalzec . - //", pmt_wc_paid=1 " . - //" where pmt_wc_order='" . $orderid . "';"; + //"pmt_confirmed='" . date('Y-m-d H:i:s') . + //"', pmt_rate=" . $rate . + //", pmt_zec=" . $totalzec . + //", pmt_wc_paid=1 " . + //" where pmt_wc_order='" . $orderid . "';"; $sql2 = $wpdb->prepare('update zgo_payments set pmt_confirmed = %s, pmt_rate = %f, pmt_zec = %f, pmt_wc_paid = 1 where pmt_wc_order = %s;', date('Y-m-d H:i:s'), $rate, $totalzec, $orderid ); $wpdb->query($sql2); @@ -333,33 +333,33 @@ function zgopmt_init() { } public function thankyou_page () { - if ( $description = $this->get_description() ) { - echo wpautop( wptexturize( $description ) ); - } + if ( $description = $this->get_description() ) { + echo wpautop( wptexturize( $description ) ); + } } public function console_log($data) { $file = plugin_dir_path( __DIR__ ) . '/zgopmtgwy/assets/log/console.log'; file_put_contents($file, $data . chr(0x0D) . chr(0x0A), FILE_TEXT | FILE_APPEND | LOCK_EX ); - + } public function base64url_encode($data) { - $edata = str_replace('=','',strtr(base64_encode($data), '+/', '-_')); - return $edata; + $edata = str_replace('=','',strtr(base64_encode($data), '+/', '-_')); + return $edata; } - } + } add_filter( 'woocommerce_payment_gateways', - 'add_custom_gateway_class' ); + 'add_custom_gateway_class' ); function add_custom_gateway_class( $methods ) { if ( ! in_array('WC_ZGopmt_Gateway', $methods) ) { - $methods[] = 'WC_ZGopmt_Gateway'; - } - return $methods; + $methods[] = 'WC_ZGopmt_Gateway'; + } + return $methods; } } @@ -371,8 +371,8 @@ foreach ( glob( plugin_dir_path( __FILE__ ) . 'assets/php/*.php' ) as $file ) { add_action( 'plugins_loaded', 'zgopmtlist_plugin' ); function zgopmtlist_plugin() { - $path = plugin_dir_path( __FILE__ ); - $plugin = new zpmt_stats( new zpmt_stats_page($path) ); - $plugin->init(); + $path = plugin_dir_path( __FILE__ ); + $plugin = new zpmt_stats( new zpmt_stats_page($path) ); + $plugin->init(); } From 53466a6788d942bde65ccfac7dbf9c97df73336a Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 23 Jun 2023 13:06:40 -0500 Subject: [PATCH 7/8] Debug callback --- zgopmtgwy.php | 80 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/zgopmtgwy.php b/zgopmtgwy.php index 7f55f0b..5db4282 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -93,6 +93,7 @@ function zgopmt_init() { if ( ! $this->is_valid_for_use() ) $this->enabled = false; + /** * Add the webhook for payment confirmation from ZGo */ @@ -293,12 +294,12 @@ function zgopmt_init() { $rate = $_GET['rate']; $order = wc_get_order( $orderid ); - $sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s;', $orderid); + $sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); //$sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; $result = $wpdb->get_row($sql,OBJECT); if ( ! is_null($result) ) { - if ( ( hash('sha256', $token) == hash('sha256', $this->zgotoken) ) + if ( ($token == $this->zgotoken ) && ( $result->pmt_orderid == $zgoOrderid ) && ( $result->pmt_wc_paid == '0' ) ) { switch ( $order->get_status() ) { @@ -321,14 +322,17 @@ function zgopmt_init() { update_option('webhook_debug', $_GET); break; default: - // $this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + //$this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + return array("message" => 'Order ' . $orderid . ' already paid or cancelled...'); break; } } else { - // $this->console_log('Invalid parameters...'); + //$this->console_log('Invalid parameters...'); + return array("message" => 'Invalid parameters...'); } } else { - // $this->console_log('Database error...'); + //$this->console_log('Database error...'); + return array("message" => 'Database error...'); } } @@ -351,6 +355,8 @@ function zgopmt_init() { return $edata; } + + } add_filter( 'woocommerce_payment_gateways', @@ -376,3 +382,67 @@ function zgopmtlist_plugin() { $plugin->init(); } + +function get_custom($data) { + global $wpdb; + + //$token = $_GET['token']; + //$zgoOrderid = $_GET['orderid']; + //$orderid = $_GET['wc_orderid']; + //$totalzec = $_GET['totalzec']; + //$rate = $_GET['rate']; + $token = $data->token; + $zgoOrderid = $data->orderid; + $orderid = $data->wc_orderid; + $totalzec = $data->totalzec; + $rate = $data->rate; + $order = wc_get_order( $orderid ); + + //$sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); + $sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; + $result = $wpdb->get_row($sql,OBJECT); + if ( ! is_null($result) ) { + + if ( ($token == $this->zgotoken ) + && ( $result->pmt_orderid == $zgoOrderid ) + && ( $result->pmt_wc_paid == '0' ) ) { + switch ( $order->get_status() ) { + case 'pending': + case 'failed': + $order->payment_complete(); + $order->reduce_order_stock(); + // + // Mark order as completed in ZGo DB + // + //$sql = "update zgo_payments set " . + //"pmt_confirmed='" . date('Y-m-d H:i:s') . + //"', pmt_rate=" . $rate . + //", pmt_zec=" . $totalzec . + //", pmt_wc_paid=1 " . + //" where pmt_wc_order='" . $orderid . "';"; + $sql2 = $wpdb->prepare('update zgo_payments set pmt_confirmed = %s, pmt_rate = %f, pmt_zec = %f, pmt_wc_paid = 1 where pmt_wc_order = %s;', date('Y-m-d H:i:s'), $rate, $totalzec, $orderid ); + $wpdb->query($sql2); + + //update_option('webhook_debug', $_GET); + break; + default: + //$this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + return array("message" => 'Order ' . $orderid . ' already paid or cancelled...'); + break; + } + } else { + //$this->console_log('Invalid parameters...'); + return array("message" => 'Invalid parameters...'); + } + } else { + //$this->console_log('Database error...'); + return array("message" => 'Database error...'); + } + //return array( 'custom' => 'Data', "request" => $data->get_params() ); +} + +add_action( 'rest_api_init', function () { + register_rest_route( 'wc/v3', 'custom', array( + 'methods' => 'GET', + 'callback' => 'get_custom')); +}); From 3dd59c757ffcfaa5368e4446afe7c8b2e7d61afe Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Mon, 26 Jun 2023 09:14:32 -0500 Subject: [PATCH 8/8] Implement new API callback --- CHANGELOG.md | 6 ++ zgopmtgwy.php | 188 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 132 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cc7452..29a1f6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +- Security hardening changes to plugin queries. +- Re-design of ZGo API callback to support WooCommerce 7.8.0 + ## [1.0.0-beta.1] - 2023-01-11 - Adjust production server integration diff --git a/zgopmtgwy.php b/zgopmtgwy.php index 5db4282..34f4389 100644 --- a/zgopmtgwy.php +++ b/zgopmtgwy.php @@ -3,11 +3,11 @@ * Plugin Name: ZGo Payment Gateway * Plugin URI: https://vergara.tech' * Description: ZGo latest payment processing solution for Woocommerce. Accept payments using Zcash. - * Version: 1.0.0 beta + * Version: 1.0.0 * Requires at least: 5.2 * Requires PHP: 7.2 * Author: Vergara Tech LLC - * Author URI: https://vergara.tech + * Author URI: https://zgo.cash/ * License: GPL v2 or later * License URI: https://www.gnu.org/licenses/gpl-2.0.html **/ @@ -97,7 +97,13 @@ function zgopmt_init() { /** * Add the webhook for payment confirmation from ZGo */ - add_action( 'woocommerce_api_zpmtcallback', array($this,'zconfirm')); + //add_action( 'woocommerce_api_zpmtcallback', array($this,'zconfirm')); + } + + public function register_routes() { + register_rest_route( 'wc/v3', 'zgocallback', array( + 'methods' => 'GET', + 'callback' => array($this,'zgoapicallback'))); } public function init_form_fields() { @@ -283,58 +289,58 @@ function zgopmt_init() { /** * Confirm payment and complete order */ - public function zconfirm() { + //public function zconfirm() { - global $wpdb; + //global $wpdb; - $token = $_GET['token']; - $zgoOrderid = $_GET['orderid']; - $orderid = $_GET['wc_orderid']; - $totalzec = $_GET['totalzec']; - $rate = $_GET['rate']; - $order = wc_get_order( $orderid ); + //$token = $_GET['token']; + //$zgoOrderid = $_GET['orderid']; + //$orderid = $_GET['wc_orderid']; + //$totalzec = $_GET['totalzec']; + //$rate = $_GET['rate']; + //$order = wc_get_order( $orderid ); - $sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); - //$sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; - $result = $wpdb->get_row($sql,OBJECT); - if ( ! is_null($result) ) { + //$sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); + ////$sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; + //$result = $wpdb->get_row($sql,OBJECT); + //if ( ! is_null($result) ) { - if ( ($token == $this->zgotoken ) - && ( $result->pmt_orderid == $zgoOrderid ) - && ( $result->pmt_wc_paid == '0' ) ) { - switch ( $order->get_status() ) { - case 'pending': - case 'failed': - $order->payment_complete(); - $order->reduce_order_stock(); - // - // Mark order as completed in ZGo DB - // - //$sql = "update zgo_payments set " . - //"pmt_confirmed='" . date('Y-m-d H:i:s') . - //"', pmt_rate=" . $rate . - //", pmt_zec=" . $totalzec . - //", pmt_wc_paid=1 " . - //" where pmt_wc_order='" . $orderid . "';"; - $sql2 = $wpdb->prepare('update zgo_payments set pmt_confirmed = %s, pmt_rate = %f, pmt_zec = %f, pmt_wc_paid = 1 where pmt_wc_order = %s;', date('Y-m-d H:i:s'), $rate, $totalzec, $orderid ); - $wpdb->query($sql2); + //if ( ($token == $this->zgotoken ) + //&& ( $result->pmt_orderid == $zgoOrderid ) + //&& ( $result->pmt_wc_paid == '0' ) ) { + //switch ( $order->get_status() ) { + //case 'pending': + //case 'failed': + //$order->payment_complete(); + //$order->reduce_order_stock(); + //// + //// Mark order as completed in ZGo DB + //// + ////$sql = "update zgo_payments set " . + ////"pmt_confirmed='" . date('Y-m-d H:i:s') . + ////"', pmt_rate=" . $rate . + ////", pmt_zec=" . $totalzec . + ////", pmt_wc_paid=1 " . + ////" where pmt_wc_order='" . $orderid . "';"; + //$sql2 = $wpdb->prepare('update zgo_payments set pmt_confirmed = %s, pmt_rate = %f, pmt_zec = %f, pmt_wc_paid = 1 where pmt_wc_order = %s;', date('Y-m-d H:i:s'), $rate, $totalzec, $orderid ); + //$wpdb->query($sql2); - update_option('webhook_debug', $_GET); - break; - default: - //$this->console_log('Order ' . $orderid . ' already paid or cancelled...'); - return array("message" => 'Order ' . $orderid . ' already paid or cancelled...'); - break; - } - } else { - //$this->console_log('Invalid parameters...'); - return array("message" => 'Invalid parameters...'); - } - } else { - //$this->console_log('Database error...'); - return array("message" => 'Database error...'); - } - } + //update_option('webhook_debug', $_GET); + //break; + //default: + ////$this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + //return array("message" => 'Order ' . $orderid . ' already paid or cancelled...'); + //break; + //} + //} else { + ////$this->console_log('Invalid parameters...'); + //return array("message" => 'Invalid parameters...'); + //} + //} else { + ////$this->console_log('Database error...'); + //return array("message" => 'Database error...'); + //} + //} public function thankyou_page () { if ( $description = $this->get_description() ) { @@ -355,6 +361,64 @@ function zgopmt_init() { return $edata; } + public function zgoapicallback($request) { + global $wpdb; + + //$token = $_GET['token']; + //$zgoOrderid = $_GET['orderid']; + //$orderid = $_GET['wc_orderid']; + //$totalzec = $_GET['totalzec']; + //$rate = $_GET['rate']; + $token = $request->get_param('token'); + $zgoOrderid = $request->get_param('orderid'); + $orderid = $request->get_param('wc_orderid'); + $totalzec = $request->get_param('totalzec'); + $rate = $request->get_param('rate'); + $order = wc_get_order( $orderid ); + + $sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); + //$sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; + $result = $wpdb->get_row($sql,OBJECT); + if ( ! is_null($result) ) { + + if ( (hash('sha256',$token) == hash('sha256',$this->zgotoken) ) + && ( $result->pmt_orderid == $zgoOrderid ) + && ( $result->pmt_wc_paid == '0' ) ) { + switch ( $order->get_status() ) { + case 'pending': + case 'failed': + $order->payment_complete(); + $order->reduce_order_stock(); + // + // Mark order as completed in ZGo DB + // + //$sql = "update zgo_payments set " . + //"pmt_confirmed='" . date('Y-m-d H:i:s') . + //"', pmt_rate=" . $rate . + //", pmt_zec=" . $totalzec . + //", pmt_wc_paid=1 " . + //" where pmt_wc_order='" . $orderid . "';"; + $sql2 = $wpdb->prepare('update zgo_payments set pmt_confirmed = %s, pmt_rate = %f, pmt_zec = %f, pmt_wc_paid = 1 where pmt_wc_order = %s;', date('Y-m-d H:i:s'), $rate, $totalzec, $orderid ); + $wpdb->query($sql2); + + //update_option('webhook_debug', $_GET); + return array('message' => 'Order '. $orderid . ' mark as paid correctly.'); + break; + default: + //$this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + return array("message" => 'Order ' . $orderid . ' already paid or cancelled...'); + break; + } + } else { + //$this->console_log('Invalid parameters...'); + return array("message" => 'Invalid parameters...'); + } + } else { + //$this->console_log('Database error...'); + return array("message" => 'Database error...'); + } + //return array( 'custom' => 'Data', "request" => $data->get_params() ); + } } @@ -391,15 +455,15 @@ function get_custom($data) { //$orderid = $_GET['wc_orderid']; //$totalzec = $_GET['totalzec']; //$rate = $_GET['rate']; - $token = $data->token; - $zgoOrderid = $data->orderid; - $orderid = $data->wc_orderid; - $totalzec = $data->totalzec; - $rate = $data->rate; + $token = $data->get_param('token'); + $zgoOrderid = $data->get_param('orderid'); + $orderid = $data->get_param('wc_orderid'); + $totalzec = $data->get_param('totalzec'); + $rate = $data->get_param('rate'); $order = wc_get_order( $orderid ); - //$sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); - $sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; + $sql = $wpdb->prepare('select * from zgo_payments where pmt_wc_order = %s ;', $orderid); + //$sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; $result = $wpdb->get_row($sql,OBJECT); if ( ! is_null($result) ) { @@ -441,8 +505,8 @@ function get_custom($data) { //return array( 'custom' => 'Data', "request" => $data->get_params() ); } -add_action( 'rest_api_init', function () { - register_rest_route( 'wc/v3', 'custom', array( - 'methods' => 'GET', - 'callback' => 'get_custom')); -}); +function plugin_register_rest_apis() { + $zgoPlugin = new WC_ZGopmt_Gateway(); + $zgoPlugin->register_routes(); +} +add_action( 'rest_api_init', 'plugin_register_rest_apis');