diff --git a/Readme.txt b/Readme.txt index 1695554a..c2844801 100755 --- a/Readme.txt +++ b/Readme.txt @@ -4,7 +4,7 @@ Tags: billwerk+, visa, mastercard, dankort, mobilepay Requires at least: 4.0 Tested up to: 6.5.3 Requires PHP: 7.4 -Stable tag: 1.7.7.1 +Stable tag: 1.7.7.2 License: GPL License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html @@ -18,6 +18,9 @@ The Billwerk+ Pay plugin extends WooCommerce allowing you to take payments on yo See installation guide right here: https://docu.billwerk.plus/help/en/apps/woocommerce/setup-woocommerce-plugin.html == Changelog == +v 1.7.7.2 - +* [Fix] - Bug double amount calculated when using setting "skip order lines" + v 1.7.7.1 - * [Fix] - WP warning message The use statement with non-compound name WC_Reepay_Renewals has no effect. diff --git a/composer.json b/composer.json index 46f9b927..e3bd11e2 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "Get a plug-n-play payment solution for WooCommerce, that is easy to use, highly secure and is built to maximize the potential of your e-commerce.", "type": "wordpress-plugin", "license": "GPL", + "version": "1.7.7.2", "autoload": { "psr-4": { "Reepay\\Checkout\\": "includes/", diff --git a/includes/Api.php b/includes/Api.php index 5faaada4..6ffcb66c 100644 --- a/includes/Api.php +++ b/includes/Api.php @@ -722,7 +722,7 @@ public function settle( WC_Order $order, $amount = null, $items_data = false, $l } if ( ! empty( $amount ) && reepay()->get_setting( 'skip_order_lines' ) === 'yes' ) { - $request_data['amount'] = rp_prepare_amount( $amount, $order->get_currency() ); + $request_data['amount'] = $amount; } else { $request_data['order_lines'] = $items_data; } diff --git a/includes/Gateways/ReepayGateway.php b/includes/Gateways/ReepayGateway.php index 318c0afa..8226f155 100644 --- a/includes/Gateways/ReepayGateway.php +++ b/includes/Gateways/ReepayGateway.php @@ -828,7 +828,7 @@ public function process_payment( $order_id ) { ), 'order' => array( 'handle' => $order_handle, - 'amount' => 'yes' === $this->skip_order_lines ? rp_prepare_amount( $order->get_total(), $order->get_currency() ) : null, + 'amount' => 'yes' === $this->skip_order_lines ? $this->get_skip_order_lines_amount( $order ) : null, 'order_lines' => 'no' === $this->skip_order_lines ? $this->get_order_items( $order ) : null, 'currency' => $order->get_currency(), 'customer' => array( @@ -1006,7 +1006,7 @@ public function process_payment( $order_id ) { return $this->process_session_charge( $params, $order ); } else { $order_lines = 'no' === $this->skip_order_lines ? $this->get_order_items( $order ) : null; - $amount = 'yes' === $this->skip_order_lines ? $order->get_total() : null; + $amount = 'yes' === $this->skip_order_lines ? $this->get_skip_order_lines_amount( $order ) : null; // Charge payment. $result = reepay()->api( $this )->charge( $order, $token->get_token(), $amount, $order_lines ); @@ -1426,10 +1426,10 @@ public function get_order_items( WC_Order $order, bool $only_not_settled = false continue; } - $price = OrderCapture::get_item_price( $order_item, $order ); - + $price = OrderCapture::get_item_price( $order_item, $order ); $tax_percent = $price['tax_percent']; - $unit_price = round( ( $prices_incl_tax ? $price['with_tax_and_discount'] : $price['original_with_discount'] ) / $order_item->get_quantity(), 2 ); + + $unit_price = round( ( $prices_incl_tax ? $price['subtotal_with_tax'] : $price['subtotal'] ) / $order_item->get_quantity(), 2 ); if ( $only_not_settled && ! empty( $order_item->get_meta( 'settled' ) ) ) { continue; @@ -1500,13 +1500,37 @@ public function get_order_items( WC_Order $order, bool $only_not_settled = false $tax = $discount_with_tax - $discount; $tax_percent = ( $tax > 0 ) ? round( 100 / ( $discount / $tax ) ) : 0; - $items[] = array( - 'ordertext' => __( 'Discount', 'reepay-checkout-gateway' ), - 'quantity' => 1, - 'amount' => round( - 1 * rp_prepare_amount( $prices_incl_tax ? $discount_with_tax : $discount, $order->get_currency() ) ) + ( $sub_amount_discount * 100 ), - 'vat' => round( $tax_percent / 100, 2 ), - 'amount_incl_vat' => $prices_incl_tax, - ); + if ( 0 !== $sub_amount_discount && 0 !== $discount ) { + /** + * Discount for subscription + */ + if ( $prices_incl_tax || $tax_percent > 0 ) { + $simple_discount_amount = $discount_with_tax - $sub_amount_discount; + } else { + $simple_discount_amount = $discount - $sub_amount_discount; + } + } else { + /** + * Discount for simple product + */ + $simple_discount_amount = $discount; + } + + if ( $prices_incl_tax || $tax_percent > 0 ) { + $discount_amount = round( - 1 * rp_prepare_amount( $prices_incl_tax ? $discount_with_tax : $discount, $order->get_currency() ) ); + } else { + $discount_amount = round( - 1 * rp_prepare_amount( $simple_discount_amount, $order->get_currency() ) ); + } + + if ( $discount_amount < 0 ) { + $items[] = array( + 'ordertext' => __( 'Discount', 'reepay-checkout-gateway' ), + 'quantity' => 1, + 'amount' => round( $discount_amount, 2 ), + 'vat' => round( $tax_percent / 100, 2 ), + 'amount_incl_vat' => $prices_incl_tax, + ); + } } // Add "PW Gift Cards" support. @@ -1536,6 +1560,25 @@ public function get_order_items( WC_Order $order, bool $only_not_settled = false return $items; } + /** + * Get order amount from order item amount + * + * @param WC_Order $order order to get items. + */ + public function get_skip_order_lines_amount( WC_Order $order ) { + $total_amount = 0; + + $items = $this->get_order_items( $order ); + + if ( $items ) { + foreach ( $items as $item ) { + $total_amount += $item['amount']; + } + } + + return $total_amount; + } + /** * Get Language * diff --git a/includes/OrderFlow/OrderCapture.php b/includes/OrderFlow/OrderCapture.php index 8f8b6949..8d157e6d 100644 --- a/includes/OrderFlow/OrderCapture.php +++ b/includes/OrderFlow/OrderCapture.php @@ -475,9 +475,10 @@ public static function get_item_price( $order_item, WC_Order $order ): array { $discount = 0; } - $price['original'] = floatval( $order->get_line_total( $order_item, false, false ) ); - $price['with_tax'] = floatval( $order->get_line_total( $order_item, true, false ) ); - + $price['subtotal'] = floatval( $order->get_line_subtotal( $order_item, false, false ) ); + $price['subtotal_with_tax'] = floatval( $order->get_line_subtotal( $order_item, true, false ) ); + $price['original'] = floatval( $order->get_line_total( $order_item, false, false ) ); + $price['with_tax'] = floatval( $order->get_line_total( $order_item, true, false ) ); if ( WPCProductBundlesWooCommerceIntegration::is_active_plugin() ) { $price_bundle = floatval( $order_item->get_meta( '_woosb_price' ) ); if ( ! empty( $price_bundle ) ) { @@ -486,10 +487,9 @@ public static function get_item_price( $order_item, WC_Order $order ): array { $price['with_tax'] += $price_bundle; } } - - $tax = $price['with_tax'] - $price['original']; - $price['tax_percent'] = ( $tax > 0 && $price['original'] > 0 ) ? round( 100 / ( $price['original'] / $tax ) ) : 0; - + $tax = $price['with_tax'] - $price['original']; + $price_tax_percent = ( $tax > 0 && $price['original'] > 0 ) ? round( 100 / ( $price['original'] / $tax ) ) : 0; + $price['tax_percent'] = round( $price_tax_percent, 2 ); $price['original_with_discount'] = $price['original'] + $discount; $price['with_tax_and_discount'] = $price['with_tax'] + $discount; diff --git a/reepay-woocommerce-payment.php b/reepay-woocommerce-payment.php index d0a19802..d3acaabe 100755 --- a/reepay-woocommerce-payment.php +++ b/reepay-woocommerce-payment.php @@ -4,7 +4,7 @@ * Description: Get a plug-n-play payment solution for WooCommerce, that is easy to use, highly secure and is built to maximize the potential of your e-commerce. * Author: Billwerk+ * Author URI: http://billwerk.plus - * Version: 1.7.7.1 + * Version: 1.7.7.2 * Text Domain: reepay-checkout-gateway * Domain Path: /languages * WC requires at least: 3.0.0 diff --git a/tests/unit/orderFlow/OrderCaptureTest.php b/tests/unit/orderFlow/OrderCaptureTest.php index 2275f315..a53be30b 100644 --- a/tests/unit/orderFlow/OrderCaptureTest.php +++ b/tests/unit/orderFlow/OrderCaptureTest.php @@ -948,6 +948,8 @@ public function test_get_item_price_product() { 'tax_percent' => 0, 'original_with_discount' => $price * $qty, 'with_tax_and_discount' => $price * $qty, + 'subtotal' => $price * $qty, + 'subtotal_with_tax' => $price * $qty ), OrderCapture::get_item_price( WC_Order_Factory::get_order_item( $order_item_id ), $this->order_generator->order() ) ); @@ -979,6 +981,8 @@ public function test_get_item_price_product_with_discount() { 'tax_percent' => 0, 'original_with_discount' => $sale_price * $qty, 'with_tax_and_discount' => $sale_price * $qty, + 'subtotal' => $sale_price * $qty, + 'subtotal_with_tax' => $sale_price * $qty ), OrderCapture::get_item_price( WC_Order_Factory::get_order_item( $order_item_id ), $this->order_generator->order() ) ); @@ -1015,6 +1019,8 @@ public function test_get_item_price_product_with_taxes() { 'tax_percent' => round($tax_rate), 'original_with_discount' => $sale_price * $qty, 'with_tax_and_discount' => round(( $sale_price * $qty ) * ( 1 + $tax_rate / 100 ), 2), + 'subtotal' => $sale_price * $qty, + 'subtotal_with_tax' => round(( $sale_price * $qty ) * ( 1 + $tax_rate / 100 ), 2) ), OrderCapture::get_item_price( WC_Order_Factory::get_order_item( $order_item_id ), $this->order_generator->order() ) ); @@ -1039,6 +1045,8 @@ public function test_get_item_price_shipping() { 'tax_percent' => 0, 'original_with_discount' => $price, 'with_tax_and_discount' => $price, + 'subtotal' => 0, + 'subtotal_with_tax' => 0 ), OrderCapture::get_item_price( WC_Order_Factory::get_order_item( $order_item_id ), $this->order_generator->order() ) ); @@ -1063,6 +1071,8 @@ public function test_get_item_price_fee() { 'tax_percent' => 0, 'original_with_discount' => $price, 'with_tax_and_discount' => $price, + 'subtotal' => 0, + 'subtotal_with_tax' => 0 ), OrderCapture::get_item_price( WC_Order_Factory::get_order_item( $order_item_id ), $this->order_generator->order() ) );