diff --git a/twocheckout-convert-plus-v2.3.1.zip b/twocheckout-convert-plus-v2.3.1.zip new file mode 100644 index 0000000..0ea91d9 Binary files /dev/null and b/twocheckout-convert-plus-v2.3.1.zip differ diff --git a/twocheckout-convert-plus/wc-twocheckout-convert-plus.php b/twocheckout-convert-plus/wc-twocheckout-convert-plus.php index 7574012..39907d2 100644 --- a/twocheckout-convert-plus/wc-twocheckout-convert-plus.php +++ b/twocheckout-convert-plus/wc-twocheckout-convert-plus.php @@ -3,7 +3,7 @@ Plugin Name: 2Checkout Convert Plus Payment Gateway Plugin URI: Description: Allows you to use 2Checkout payment gateway with the WooCommerce plugin. - Version: 2.3.0 + Version: 2.3.1 Author: 2Checkout Author URI: https://www.2checkout.com */ diff --git a/twocheckout-inline-v2.3.1.zip b/twocheckout-inline-v2.3.1.zip new file mode 100644 index 0000000..158bed5 Binary files /dev/null and b/twocheckout-inline-v2.3.1.zip differ diff --git a/twocheckout-inline/src/Twocheckout/class-two-checkout-ipn-helper.php b/twocheckout-inline/src/Twocheckout/class-two-checkout-ipn-helper.php index e89d0f1..581d7bf 100644 --- a/twocheckout-inline/src/Twocheckout/class-two-checkout-ipn-helper.php +++ b/twocheckout-inline/src/Twocheckout/class-two-checkout-ipn-helper.php @@ -131,7 +131,7 @@ protected function _is_order_refunded() { /** * @return string */ - private function _calculate_ipn_response() { + private function _calculate_ipn_response($algo='sha3-256') { $result_response = ''; $ipn_params_response = []; // we're assuming that these always exist, if they don't then the problem is on avangate side @@ -144,11 +144,19 @@ private function _calculate_ipn_response() { $result_response .= $this->array_expand( (array) $val ); } - return sprintf( - '%s|%s', - $ipn_params_response['DATE'], - $this->generate_hash( $this->secret_key, $result_response ) - ); + if ('md5' === $algo) + return sprintf( + '%s|%s', + $ipn_params_response['DATE'], + $this->generate_hash($this->secret_key, $result_response, $algo) + ); + else + return sprintf( + '%s', + $algo, + $ipn_params_response['DATE'], + $this->generate_hash($this->secret_key, $result_response, $algo) + ); } /** @@ -214,7 +222,7 @@ public function is_ipn_response_valid() { $receivedHash = $this->request_params['SIGNATURE_SHA3_256']; if(!$receivedHash){ - $receivedAlgo='sha2-256'; + $receivedAlgo='sha256'; $receivedHash = $this->request_params['SIGNATURE_SHA2_256']; } @@ -276,6 +284,7 @@ public function generate_hash($key, $data, $algo = 'sha3-256') { * @return string */ public function process_ipn() { + $hash = $this->extractHashFromRequest(); try { if ( ! isset( $this->request_params['REFNO'] ) && empty( $this->request_params['REFNO'] ) ) { self::log( 'Cannot identify order: "%s".', $this->request_params['REFNOEXT'] ); @@ -294,7 +303,7 @@ public function process_ipn() { } catch ( Exception $ex ) { self::log( 'Exception processing IPN: ' . $ex->getMessage() ); } - echo $this->_calculate_ipn_response(); + echo $this->_calculate_ipn_response($hash['algo']); exit(); } @@ -326,4 +335,25 @@ private function array_expand( $array ) { return $retval; } + + /** + * @return array [hash, algo] + */ + protected function extractHashFromRequest():array { + $receivedAlgo = 'sha3-256'; + $receivedHash = $this->request_params['SIGNATURE_SHA3_256']; + + if (!$receivedHash) { + $receivedAlgo = 'sha256'; + $receivedHash = $this->request_params['SIGNATURE_SHA2_256']; + } + + if (!$receivedHash) { + $receivedAlgo = 'md5'; + $receivedHash = $this->request_params['HASH']; + } + + return ['hash' => $receivedHash, 'algo' => $receivedAlgo]; + } + } diff --git a/twocheckout-inline/wc-twocheckout-inline.php b/twocheckout-inline/wc-twocheckout-inline.php index 455d62f..029bcc9 100644 --- a/twocheckout-inline/wc-twocheckout-inline.php +++ b/twocheckout-inline/wc-twocheckout-inline.php @@ -3,7 +3,7 @@ Plugin Name: 2Checkout Inline Payment Gateway Plugin URI: Description: Allows you to use 2Checkout payment gateway with the WooCommerce plugin. - Version: 2.3.0 + Version: 2.3.1 Author: 2Checkout Author URI: https://www.2checkout.com */ @@ -129,7 +129,7 @@ function enqueue_style() { //enqueue a script function enqueue_script() { wp_enqueue_script( 'twocheckout_inline_script', - '/wp-content/plugins/twocheckout-inline/assets/js/twocheckout_inline.js' ); + '/wp-content/plugins/twocheckout-inline/assets/js/twocheckout_inline.js', ['jquery'] ); } /** @@ -548,7 +548,11 @@ public function check_ipn_response_inline() { if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) { return; } + $params = $_POST; + if(empty($params)) + $params=json_decode(file_get_contents('php://input'),true); + unset( $params['wc-api'] ); if ( isset( $params['REFNOEXT'] ) && ! empty( $params['REFNOEXT'] ) ) { $order = wc_get_order( $params['REFNOEXT'] ); diff --git a/twocheckout-v2.3.1.zip b/twocheckout-v2.3.1.zip new file mode 100644 index 0000000..f8d8d59 Binary files /dev/null and b/twocheckout-v2.3.1.zip differ diff --git a/twocheckout/src/Twocheckout/TwoCheckoutIpnHelperApi.php b/twocheckout/src/Twocheckout/TwoCheckoutIpnHelperApi.php index 21bff25..0945738 100644 --- a/twocheckout/src/Twocheckout/TwoCheckoutIpnHelperApi.php +++ b/twocheckout/src/Twocheckout/TwoCheckoutIpnHelperApi.php @@ -171,28 +171,36 @@ public function processorder_status(string $order_status,string $refNo) { } } - /** - * Validate Ipn request - * @return bool - */ - public function is_ipn_response_valid() { - $result = ''; - - $receivedAlgo='sha3-256'; + /** + * @return array [hash, algo] + */ + protected function extractHashFromRequest():array { + $receivedAlgo = 'sha3-256'; $receivedHash = $this->request_params['SIGNATURE_SHA3_256']; - if(!$receivedHash){ - $receivedAlgo='sha256'; + if (!$receivedHash) { + $receivedAlgo = 'sha256'; $receivedHash = $this->request_params['SIGNATURE_SHA2_256']; } - if(!$receivedHash){ - $receivedAlgo='md5'; + if (!$receivedHash) { + $receivedAlgo = 'md5'; $receivedHash = $this->request_params['HASH']; } - foreach ( $this->request_params as $key => $val ) { + return ['hash' => $receivedHash, 'algo' => $receivedAlgo]; + } + + /** + * Validate Ipn request + * @return bool + */ + public function is_ipn_response_valid() { + $result = ''; + + $hash = $this->extractHashFromRequest(); + foreach ( $this->request_params as $key => $val ) { if ( !in_array($key ,["HASH", "SIGNATURE_SHA2_256", "SIGNATURE_SHA3_256"]) ) { if ( is_array( $val ) ) { $result .= $this->array_expand( $val ); @@ -204,8 +212,8 @@ public function is_ipn_response_valid() { } if ( isset( $this->request_params['REFNO'] ) && ! empty( $this->request_params['REFNO'] ) ) { - $calc_hash = $this->generate_hash( $this->secret_key, $result, $receivedAlgo ); - if ( $receivedHash === $calc_hash ) { + $calc_hash = $this->generate_hash( $this->secret_key, $result, $hash['algo'] ); + if ( $hash['hash'] === $calc_hash ) { return true; } } @@ -258,6 +266,8 @@ public static function log( $message ) { * @return string */ public function process_ipn() { + $hash = $this->extractHashFromRequest(); + try { if ( ! isset( $this->request_params['REFNO'] ) && empty( $this->request_params['REFNO'] ) ) { self::log( 'Cannot identify order: "%s".', $this->request_params['REFNOEXT'] ); @@ -276,7 +286,7 @@ public function process_ipn() { } catch ( Exception $ex ) { self::log( 'Exception processing IPN: ' . $ex->getMessage() ); } - echo $this->_calculate_ipn_response(); + echo $this->_calculate_ipn_response($hash['algo']); exit(); } @@ -305,26 +315,34 @@ protected function _process_fraud() { } } - /** - * @return string - */ - private function _calculate_ipn_response() { - $result_response = ''; - $ipn_params_response = []; - // we're assuming that these always exist, if they don't then the problem is on avangate side - $ipn_params_response['IPN_PID'][0] = $this->request_params['IPN_PID'][0]; - $ipn_params_response['IPN_PNAME'][0] = $this->request_params['IPN_PNAME'][0]; - $ipn_params_response['IPN_DATE'] = $this->request_params['IPN_DATE']; - $ipn_params_response['DATE'] = date( 'YmdHis' ); - - foreach ( $ipn_params_response as $key => $val ) { - $result_response .= $this->array_expand( (array) $val ); - } + /** + * @return string + */ + private function _calculate_ipn_response($algo='sha3-256') { + $resultResponse = ''; + $ipn_params_response = []; + // we're assuming that these always exist, if they don't then the problem is on avangate side + $ipn_params_response['IPN_PID'][0] = $this->request_params['IPN_PID'][0]; + $ipn_params_response['IPN_PNAME'][0] = $this->request_params['IPN_PNAME'][0]; + $ipn_params_response['IPN_DATE'] = $this->request_params['IPN_DATE']; + $ipn_params_response['DATE'] = date( 'YmdHis' ); + + foreach ( $ipn_params_response as $key => $val ) { + $resultResponse .= $this->array_expand( (array) $val ); + } - return sprintf( - '%s|%s', - $ipn_params_response['DATE'], - $this->generate_hash( $this->secret_key, $result_response ) - ); - } + if ('md5' === $algo) + return sprintf( + '%s|%s', + $ipn_params_response['DATE'], + $this->generate_hash($this->secret_key, $resultResponse, $algo) + ); + else + return sprintf( + '%s', + $algo, + $ipn_params_response['DATE'], + $this->generate_hash($this->secret_key, $resultResponse, $algo) + ); + } } diff --git a/twocheckout/wc-twocheckout.php b/twocheckout/wc-twocheckout.php index 36e0abe..0553645 100644 --- a/twocheckout/wc-twocheckout.php +++ b/twocheckout/wc-twocheckout.php @@ -3,7 +3,7 @@ Plugin Name: 2Checkout Payment Gateway Plugin URI: Description: Allows you to use 2Checkout payment gateway with the WooCommerce plugin. - Version: 2.3.0 + Version: 2.3.1 Author: 2Checkout Author URI: https://www.2checkout.com */ @@ -141,8 +141,8 @@ public function init_form_fields() { */ public function payment_fields() { - wp_enqueue_script( '2payjs', 'https://2pay-js.2checkout.com/v1/2pay.js' ); - wp_enqueue_script( 'twocheckout_script', '/wp-content/plugins/twocheckout/assets/js/twocheckout.js' ); + wp_enqueue_script( '2payjs', 'https://2pay-js.2checkout.com/v1/2pay.js', ['jquery'] ); + wp_enqueue_script( 'twocheckout_script', '/wp-content/plugins/twocheckout/assets/js/twocheckout.js', ['jquery'] ); wp_enqueue_style( 'twocheckout_style', '/wp-content/plugins/twocheckout/assets/css/twocheckout.css' ); $twocheckout_is_checkout = ( is_checkout() && empty( $_GET['pay_for_order'] ) ) ? 'yes' : 'no'; require_once plugin_dir_path( __FILE__ ) . 'templates/payment-fields.php'; @@ -602,9 +602,13 @@ public function check_ipn_response_api() { return; } $params = $_POST; + if(empty($params)) + $params=json_decode(file_get_contents('php://input'),true); + unset( $params['wc-api'] ); if ( isset( $params['REFNOEXT'] ) && ! empty( $params['REFNOEXT'] ) ) { $order = wc_get_order( $params['REFNOEXT'] ); + if ( $order && $order->get_payment_method() == 'twocheckout' ) { try { $ipn_helper = new Two_Checkout_Ipn_Helper_Api( $params, $this->secret_key, $this->complete_order_on_payment, $this->debug, $order ); @@ -612,6 +616,7 @@ public function check_ipn_response_api() { $this->log( 'Unable to find order with RefNo: ' . $params['REFNOEXT'] ); throw new Exception( 'An error occurred!' ); } + if ( ! $ipn_helper->is_ipn_response_valid() ) { self::log( sprintf( 'SHA3 hash mismatch for 2Checkout IPN with date: "%s" . ', $params['IPN_DATE'] ) );