| @@ -163,23 +163,53 @@ | ||
| 163 | 163 | * @return void |
| 164 | 164 | * @since 2.0.5 |
| 165 | 165 | */ |
| 166 | 166 | public function add_offer_product_to_cart(){ |
| 167 | - $product_id = isset( $_POST['product_id'] ) ? intval( $_POST['product_id'] ) : 0; | |
| 168 | - $quantity = isset( $_POST['quantity'] ) ? intval( $_POST['quantity'] ) : 0; | |
| 169 | - $variation_id = isset( $_POST['variation_id'] ) ? intval( $_POST['variation_id'] ) : 0; | |
| 170 | - $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0; | |
| 171 | - if( isset( $_POST['is_variable'], $_POST['attr'] ) && $_POST['is_variable'] == 'true' ){ | |
| 172 | - $payload = [ | |
| 173 | - 'product_id' => $product_id, | |
| 174 | - 'data' => $_POST['attr'], | |
| 175 | - ]; | |
| 176 | - $variation_id = $this->wpfnl_get_variation_id($payload); | |
| 167 | + $nonce = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : ''; | |
| 168 | + | |
| 169 | + if ( ! wp_verify_nonce( $nonce, 'wpfnl_offer_nonce' ) ) { | |
| 170 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 177 | 171 | } |
| 178 | 172 | |
| 173 | + $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0; | |
| 179 | 174 | |
| 180 | - $total = $this->get_discounted_price( $step_id, $product_id, $quantity ); | |
| 181 | - $total = floatval($total)/intval($quantity); | |
| 175 | + // Which product is sold, and how many, come from the step configuration. | |
| 176 | + // Bail before touching the cart; the old code emptied it first and | |
| 177 | + // validated nothing. | |
| 178 | + $offer_item = Wpfnl_functions::resolve_offer_cart_item( $step_id ); | |
| 179 | + | |
| 180 | + if ( is_wp_error( $offer_item ) ) { | |
| 181 | + wp_send_json_error( array( 'message' => $offer_item->get_error_message() ), 400 ); | |
| 182 | + } | |
| 183 | + | |
| 184 | + // The request's only choice is which variation of that product to buy. | |
| 185 | + // Match against the configured parent, never a requested one: WC_Product | |
| 186 | + // throws on an id that is not a product. | |
| 187 | + if ( isset( $_POST['is_variable'], $_POST['attr'] ) && 'true' == $_POST['is_variable'] && is_array( $_POST['attr'] ) ) { | |
| 188 | + $variation_id = $this->wpfnl_get_variation_id( | |
| 189 | + [ | |
| 190 | + 'product_id' => $offer_item['product_id'], | |
| 191 | + 'data' => wc_clean( wp_unslash( $_POST['attr'] ) ), | |
| 192 | + ] | |
| 193 | + ); | |
| 194 | + | |
| 195 | + $offer_item = Wpfnl_functions::resolve_offer_cart_item( $step_id, $variation_id ); | |
| 196 | + | |
| 197 | + if ( is_wp_error( $offer_item ) ) { | |
| 198 | + wp_send_json_error( array( 'message' => $offer_item->get_error_message() ), 400 ); | |
| 199 | + } | |
| 200 | + } | |
| 201 | + | |
| 202 | + $product_id = $offer_item['product_id']; | |
| 203 | + $variation_id = $offer_item['variation_id']; | |
| 204 | + $quantity = $offer_item['quantity']; | |
| 205 | + | |
| 206 | + // Price the item that is actually added to the cart. Pricing the parent | |
| 207 | + // of a variable product yields its cheapest variation's price. | |
| 208 | + $priced_id = $variation_id ? $variation_id : $product_id; | |
| 209 | + | |
| 210 | + $total = $this->get_discounted_price( $step_id, $priced_id, $quantity ); | |
| 211 | + $total = floatval( $total ) / $quantity; | |
| 182 | 212 | $custom_data = [ |
| 183 | 213 | 'custom_price' => $total, |
| 184 | 214 | ]; |
| 185 | 215 | |
| @@ -216,8 +246,13 @@ | ||
| 216 | 246 | |
| 217 | 247 | $type = get_post_meta($step_id, '_step_type', true); |
| 218 | 248 | $discount_data = get_post_meta($step_id, '_wpfnl_'.$type.'_discount', true); |
| 219 | 249 | $product = wc_get_product( $product_id ); |
| 250 | + | |
| 251 | + if ( ! $product ) { | |
| 252 | + return 0; | |
| 253 | + } | |
| 254 | + | |
| 220 | 255 | $total = isset($discount_data['discountApplyTo']) && 'regular' === $discount_data['discountApplyTo'] ? $product->get_regular_price() : $product->get_sale_price(); |
| 221 | 256 | $total = !$total ? $product->get_price() : $total; |
| 222 | 257 | $total = floatval($total) * intval($quantity); |
| 223 | 258 | if( $discount_instance->maybe_time_bound_discount( $step_id ) && !$discount_instance->maybe_validate_discount_time( $step_id ) ) { |
| @@ -772,13 +807,10 @@ | ||
| 772 | 807 | public function process_upsell_accepted_action() { |
| 773 | 808 | |
| 774 | 809 | $nonce = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : ''; |
| 775 | 810 | |
| 776 | - if ( $nonce && ! wp_verify_nonce( $nonce, 'wpfnl_upsell_accepted_nonce' ) ) { | |
| 777 | - return array( | |
| 778 | - 'status' => 'success', | |
| 779 | - 'message' => __( 'Unauthorized request', 'wpfnl-pro' ) | |
| 780 | - ); | |
| 811 | + if ( ! wp_verify_nonce( $nonce, 'wpfnl_upsell_accepted_nonce' ) ) { | |
| 812 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 781 | 813 | } |
| 782 | 814 | |
| 783 | 815 | |
| 784 | 816 | |
| @@ -807,16 +839,10 @@ | ||
| 807 | 839 | } |
| 808 | 840 | |
| 809 | 841 | $order = wc_get_order($order_id); |
| 810 | 842 | |
| 811 | - $wpfnl_functions_instance = new Wpfnl_functions(); | |
| 812 | - if( method_exists($wpfnl_functions_instance,'is_valid_order_owner')){ | |
| 813 | - if (!Wpfnl_functions::is_valid_order_owner($order, $order_key)) { | |
| 814 | - wp_send_json([ | |
| 815 | - 'status' => 'error', | |
| 816 | - 'message' => __( 'Unauthorized request', 'wpfnl-pro' ), | |
| 817 | - ]); | |
| 818 | - } | |
| 843 | + if ( ! Wpfnl_functions::is_valid_order_owner( $order, $order_key ) ) { | |
| 844 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 819 | 845 | } |
| 820 | 846 | |
| 821 | 847 | if ( $order_id && $product_id ) { |
| 822 | 848 | $data = array( |
| @@ -848,13 +874,10 @@ | ||
| 848 | 874 | */ |
| 849 | 875 | public function process_downsell_accepted_action() { |
| 850 | 876 | |
| 851 | 877 | $nonce = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : ''; |
| 852 | - if ( $nonce && ! wp_verify_nonce( $nonce, 'wpfnl_downsell_accepted_nonce' ) ) { | |
| 853 | - return array( | |
| 854 | - 'status' => 'success', | |
| 855 | - 'message' => __( 'Unauthorized request', 'wpfnl-pro' ) | |
| 856 | - ); | |
| 878 | + if ( ! wp_verify_nonce( $nonce, 'wpfnl_downsell_accepted_nonce' ) ) { | |
| 879 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 857 | 880 | } |
| 858 | 881 | |
| 859 | 882 | $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0; |
| 860 | 883 | $funnel_id = isset( $_POST['funnel_id'] ) ? intval( $_POST['funnel_id'] ) : 0; |
| @@ -882,16 +905,10 @@ | ||
| 882 | 905 | } |
| 883 | 906 | |
| 884 | 907 | $order = wc_get_order($order_id); |
| 885 | 908 | |
| 886 | - $wpfnl_functions_instance = new Wpfnl_functions(); | |
| 887 | - if( method_exists($wpfnl_functions_instance,'is_valid_order_owner')){ | |
| 888 | - if (!Wpfnl_functions::is_valid_order_owner($order, $order_key)) { | |
| 889 | - wp_send_json([ | |
| 890 | - 'status' => 'error', | |
| 891 | - 'message' => __( 'Unauthorized request', 'wpfnl-pro' ), | |
| 892 | - ]); | |
| 893 | - } | |
| 909 | + if ( ! Wpfnl_functions::is_valid_order_owner( $order, $order_key ) ) { | |
| 910 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 894 | 911 | } |
| 895 | 912 | |
| 896 | 913 | $all_products = []; |
| 897 | 914 | $product_data = array(); |
| @@ -927,12 +944,9 @@ | ||
| 927 | 944 | */ |
| 928 | 945 | public function process_upsell_rejected_action() { |
| 929 | 946 | $nonce = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : ''; |
| 930 | 947 | if ( ! wp_verify_nonce( $nonce, 'wpfnl_upsell_rejected_nonce' ) ) { |
| 931 | - return array( | |
| 932 | - 'status' => 'success', | |
| 933 | - 'message' => __( 'Unauthorized request', 'wpfnl-pro' ) | |
| 934 | - ); | |
| 948 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 935 | 949 | } |
| 936 | 950 | |
| 937 | 951 | $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0; |
| 938 | 952 | $funnel_id = isset( $_POST['funnel_id'] ) ? intval( $_POST['funnel_id'] ) : 0; |
| @@ -965,8 +979,14 @@ | ||
| 965 | 979 | 'message' => __( 'Order does not exist', 'wpfnl-pro' ), |
| 966 | 980 | ); |
| 967 | 981 | |
| 968 | 982 | if ( $order_id ) { |
| 983 | + $order = wc_get_order( $order_id ); | |
| 984 | + | |
| 985 | + if ( ! Wpfnl_functions::is_valid_order_owner( $order, $order_key ) ) { | |
| 986 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 987 | + } | |
| 988 | + | |
| 969 | 989 | $data = array( |
| 970 | 990 | 'order_id' => $order_id, |
| 971 | 991 | 'product_id' => $product_id, |
| 972 | 992 | 'quantity' => $quantity, |
| @@ -995,12 +1015,9 @@ | ||
| 995 | 1015 | */ |
| 996 | 1016 | public function process_downsell_rejected_action() { |
| 997 | 1017 | $nonce = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : ''; |
| 998 | 1018 | if ( ! wp_verify_nonce( $nonce, 'wpfnl_downsell_rejected_nonce' ) ) { |
| 999 | - return array( | |
| 1000 | - 'status' => 'success', | |
| 1001 | - 'message' => __( 'Unauthorized request', 'wpfnl-pro' ) | |
| 1002 | - ); | |
| 1019 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 1003 | 1020 | } |
| 1004 | 1021 | $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0; |
| 1005 | 1022 | $funnel_id = isset( $_POST['funnel_id'] ) ? intval( $_POST['funnel_id'] ) : 0; |
| 1006 | 1023 | $order_id = isset( $_POST['order_id'] ) ? intval( $_POST['order_id'] ) : 0; |
| @@ -1032,8 +1049,14 @@ | ||
| 1032 | 1049 | 'message' => __( 'Order does not exist', 'wpfnl-pro' ), |
| 1033 | 1050 | ); |
| 1034 | 1051 | |
| 1035 | 1052 | if ( $order_id ) { |
| 1053 | + $order = wc_get_order( $order_id ); | |
| 1054 | + | |
| 1055 | + if ( ! Wpfnl_functions::is_valid_order_owner( $order, $order_key ) ) { | |
| 1056 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 1057 | + } | |
| 1058 | + | |
| 1036 | 1059 | $data = array( |
| 1037 | 1060 | 'order_id' => $order_id, |
| 1038 | 1061 | 'product_id' => $product_id, |
| 1039 | 1062 | 'quantity' => $quantity, |
| @@ -1060,16 +1083,27 @@ | ||
| 1060 | 1083 | * @since 1.0.0 |
| 1061 | 1084 | */ |
| 1062 | 1085 | public function wpfnl_after_process_with_auth_ajax() |
| 1063 | 1086 | { |
| 1064 | - $step_id = $_POST['step_id']; | |
| 1065 | - $order_id = $_POST['order_id']; | |
| 1066 | - $order_key = $_POST['order_key']; | |
| 1087 | + $nonce = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : ''; | |
| 1088 | + | |
| 1089 | + if ( ! wp_verify_nonce( $nonce, 'wpfnl_offer_nonce' ) ) { | |
| 1090 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 1091 | + } | |
| 1092 | + | |
| 1093 | + $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0; | |
| 1094 | + $order_id = isset( $_POST['order_id'] ) ? intval( $_POST['order_id'] ) : 0; | |
| 1095 | + $order_key = isset( $_POST['order_key'] ) ? sanitize_text_field( wp_unslash( $_POST['order_key'] ) ) : ''; | |
| 1096 | + | |
| 1097 | + if ( ! Wpfnl_functions::is_valid_order_owner( wc_get_order( $order_id ), $order_key ) ) { | |
| 1098 | + wp_send_json_error( array( 'message' => __( 'Unauthorized request', 'wpfnl' ) ), 403 ); | |
| 1099 | + } | |
| 1100 | + | |
| 1067 | 1101 | $step_type = get_post_meta($step_id, '_step_type', true); |
| 1068 | 1102 | $intent_id = ''; |
| 1069 | 1103 | |
| 1070 | 1104 | if (isset($_POST['intent_id'])) { |
| 1071 | - $intent_id = $_POST['intent_id']; | |
| 1105 | + $intent_id = sanitize_text_field( wp_unslash( $_POST['intent_id'] ) ); | |
| 1072 | 1106 | } |
| 1073 | 1107 | |
| 1074 | 1108 | $extra_data = []; |
| 1075 | 1109 | $extra_data['step_id'] = $step_id; |
| @@ -1079,9 +1113,9 @@ | ||
| 1079 | 1113 | $extra_data['intent_id'] = $intent_id; |
| 1080 | 1114 | |
| 1081 | 1115 | $step_meta = get_post_meta($step_id, '_wpfnl_'.$step_type.'_products', true); |
| 1082 | 1116 | |
| 1083 | - if ($step_meta[0]) { | |
| 1117 | + if ( ! empty( $step_meta[0] ) ) { | |
| 1084 | 1118 | $step_meta = $step_meta[0]; |
| 1085 | 1119 | } else { |
| 1086 | 1120 | wp_send_json([ |
| 1087 | 1121 | 'status' => 'error', |
| @@ -1183,19 +1217,23 @@ | ||
| 1183 | 1217 | } |
| 1184 | 1218 | |
| 1185 | 1219 | $offer_product_id = isset( $offer_product[ 'id' ] ) ? $offer_product[ 'id' ] : 0; |
| 1186 | 1220 | $offer_total_price = isset( $offer_product[ 'total' ] ) ? $offer_product[ 'total' ] : 0; |
| 1187 | - $shipping = $this->calculate_offer_product_shipping_price( $order, $offer_product_id, $offer_total_price ); | |
| 1221 | + $offer_qty = isset( $offer_product[ 'qty' ] ) ? $offer_product[ 'qty' ] : 1; | |
| 1222 | + $shipping = $this->calculate_offer_product_shipping_price( $order, $offer_product_id, $offer_total_price, $offer_qty ); | |
| 1188 | 1223 | $shipping_price = isset( $shipping[ 'total' ] ) ? $shipping[ 'total' ] : 0; |
| 1189 | 1224 | $shipping_tax = isset( $shipping[ 'total_tax' ] ) ? $shipping[ 'total_tax' ] : 0; |
| 1190 | 1225 | $shipping_price = $shipping_price + $shipping_tax; |
| 1191 | 1226 | |
| 1227 | + /** | |
| 1228 | + * Charge the derived shipping alongside the offer product. The same | |
| 1229 | + * $shipping array is handed to after_offer_charged() below, which | |
| 1230 | + * records it as a shipping line, so the amount charged and the | |
| 1231 | + * amount recorded on the order stay in lockstep. | |
| 1232 | + */ | |
| 1192 | 1233 | $offer_product[ 'price' ] = $offer_total_price + $shipping_price; |
| 1193 | 1234 | $offer_product[ 'total' ] = $offer_total_price + $shipping_price; |
| 1194 | 1235 | |
| 1195 | - $offer_product[ 'price' ] = $offer_total_price; | |
| 1196 | - $offer_product[ 'total' ] = $offer_total_price; | |
| 1197 | - | |
| 1198 | 1236 | // Handle chained products if pro plugin is active |
| 1199 | 1237 | $total_chained_product_price = 0; |
| 1200 | 1238 | if( class_exists( '\WPFunnelsPro\Compatibility\ChainedProduct' ) && Wpfnl_functions::is_wc_active() ){ |
| 1201 | 1239 | $chained_product_class_instance = new \WPFunnelsPro\Compatibility\ChainedProduct(); |
| @@ -1385,9 +1423,13 @@ | ||
| 1385 | 1423 | * @param $step_id |
| 1386 | 1424 | * @param $funnel_id |
| 1387 | 1425 | * @return string |
| 1388 | 1426 | */ |
| 1389 | - public function get_next_step_url( \WC_Order $order , $step_id, $funnel_id ) { | |
| 1427 | + public function get_next_step_url( $order , $step_id, $funnel_id ) { | |
| 1428 | + if ( ! is_a( $order, 'WC_Order' ) ) { | |
| 1429 | + return false; | |
| 1430 | + } | |
| 1431 | + | |
| 1390 | 1432 | $next_step = Wpfnl_functions::get_next_conditional_step( $funnel_id, $step_id, $order, $this->offerStatus ); |
| 1391 | 1433 | $next_step = apply_filters( 'wpfunnels/next_step_data', $next_step ); |
| 1392 | 1434 | $next_step_id = isset($next_step['step_id']) ? $next_step['step_id'] : ''; |
| 1393 | 1435 | |
| @@ -1574,80 +1616,19 @@ | ||
| 1574 | 1616 | |
| 1575 | 1617 | /** |
| 1576 | 1618 | * @desc calculate shipping cost for offer steps (upsell/downsell) |
| 1577 | 1619 | * |
| 1620 | + * Delegates to the shared helper so the free and pro copies of this handler | |
| 1621 | + * cannot drift apart. | |
| 1622 | + * | |
| 1578 | 1623 | * @param \WC_Order $order |
| 1579 | 1624 | * @param $product_id |
| 1580 | 1625 | * @param $total_price |
| 1581 | - * @return int|mixed|void | |
| 1626 | + * @param int $qty | |
| 1627 | + * @return array | |
| 1582 | 1628 | */ |
| 1583 | - private function calculate_offer_product_shipping_price( \WC_Order $order, $product_id, $total_price ) { | |
| 1584 | - if( !$product_id ) { | |
| 1585 | - return; | |
| 1586 | - } | |
| 1587 | - if( !WC()->shipping()->get_shipping_classes() ) { | |
| 1588 | - return; | |
| 1589 | - } | |
| 1590 | - | |
| 1591 | - $product = wc_get_product( $product_id ); | |
| 1592 | - if( $product && $product->is_virtual() ) { | |
| 1593 | - return; | |
| 1594 | - } | |
| 1595 | - | |
| 1596 | - $shipping = []; | |
| 1597 | - $shipping_methods = $order->get_shipping_methods(); | |
| 1598 | - $offer_settings = Wpfnl_functions::get_offer_settings(); | |
| 1599 | - $offer_orders_option = isset( $offer_settings[ 'offer_orders' ] ) ? $offer_settings[ 'offer_orders' ] : ''; | |
| 1600 | - | |
| 1601 | - if( !empty( $shipping_methods ) ) { | |
| 1602 | - foreach( $shipping_methods as $key => $method ) { | |
| 1603 | - if( $method ){ | |
| 1604 | - $shipping = [ | |
| 1605 | - 'name' => $method->get_name(), | |
| 1606 | - 'method_title' => $method->get_method_title(), | |
| 1607 | - 'method_id' => $method->get_method_id(), | |
| 1608 | - 'instance_id' => $method->get_instance_id(), | |
| 1609 | - 'total' => $method->get_total(), | |
| 1610 | - 'total_tax' => $method->get_total_tax(), | |
| 1611 | - 'taxes' => $method->get_taxes(), | |
| 1612 | - 'tax_percentage' => ( $method->get_total() != 0 ) || ( $method->get_total() != 0.00 ) ? ( $method->get_total_tax() * 100 ) / $method->get_total() : 0, | |
| 1613 | - ]; | |
| 1614 | - } | |
| 1615 | - | |
| 1616 | - } | |
| 1617 | - } | |
| 1618 | - | |
| 1619 | - if( 'main-order' === $offer_orders_option ) { | |
| 1620 | - $wc_shipping_zones = \WC_Shipping_Zones::get_zones(); | |
| 1621 | - | |
| 1622 | - if( !empty( $wc_shipping_zones ) && isset( $shipping[ 'method_id' ] ) && 'flat_rate' === $shipping[ 'method_id' ] ) { | |
| 1623 | - foreach( $wc_shipping_zones as $zone ) { | |
| 1624 | - if( isset( $zone[ 'shipping_methods' ] ) && !empty( $zone[ 'shipping_methods' ] ) ) { | |
| 1625 | - foreach( $zone[ 'shipping_methods' ] as $method ) { | |
| 1626 | - if( 'WC_Shipping_Flat_Rate' === get_class( $method ) ) { | |
| 1627 | - if( isset( $method->instance_id ) && isset( $shipping[ 'instance_id' ] ) ) { | |
| 1628 | - if( $method->instance_id == $shipping[ 'instance_id' ] ) { | |
| 1629 | - $product_shipping_class_id = $product->get_shipping_class_id(); | |
| 1630 | - $instance_settings = isset( $method->instance_settings ) ? $method->instance_settings : []; | |
| 1631 | - $shipping_cost = isset( $instance_settings[ 'class_cost_' . $product_shipping_class_id ] ) ? $instance_settings[ 'class_cost_' . $product_shipping_class_id ] : $instance_settings[ 'no_class_cost' ]; | |
| 1632 | - $shipping_cost = $shipping_cost ? $shipping_cost : 0; | |
| 1633 | - $tax_percentage = isset( $shipping[ 'tax_percentage' ] ) ? $shipping[ 'tax_percentage' ] : 0; | |
| 1634 | - $total_tax = ( $shipping_cost * $tax_percentage ) / 100; | |
| 1635 | - $shipping[ 'total' ] = $shipping_cost; | |
| 1636 | - $shipping[ 'total_tax' ] = $total_tax; | |
| 1637 | - $shipping[ 'taxes' ] = [ | |
| 1638 | - 'total' => [ $total_tax ] | |
| 1639 | - ]; | |
| 1640 | - } | |
| 1641 | - } | |
| 1642 | - } | |
| 1643 | - } | |
| 1644 | - } | |
| 1645 | - } | |
| 1646 | - } | |
| 1647 | - } | |
| 1648 | - unset( $shipping[ 'tax_percentage' ] ); | |
| 1649 | - return $shipping; | |
| 1629 | + private function calculate_offer_product_shipping_price( \WC_Order $order, $product_id, $total_price, $qty = 1 ) { | |
| 1630 | + return Wpfnl_functions::get_offer_shipping( $order, $product_id, $total_price, $qty ); | |
| 1650 | 1631 | } |
| 1651 | 1632 | |
| 1652 | 1633 | /** |
| 1653 | 1634 | * Check if current step is upsell or downsell |
| @@ -1843,8 +1824,17 @@ | ||
| 1843 | 1824 | $step_type = get_post_meta( $step_id, '_step_type', true ); |
| 1844 | 1825 | wc_add_order_item_meta( $item_id, "_wpfunnels_{$step_type}", 'yes' ); |
| 1845 | 1826 | wc_add_order_item_meta( $item_id, '_wpfunnels_step_id', $offer_product['step_id'] ); |
| 1846 | 1827 | $order->update_meta_data( '_wpfunnels_offer_' . $step_id, $step_id ); |
| 1828 | + | |
| 1829 | + // Record any shipping derived for this offer so the amount charged | |
| 1830 | + // and the amount recorded on the order stay in lockstep. | |
| 1831 | + if ( ! empty( $shipping_data ) ) { | |
| 1832 | + $offer_name = isset( $offer_product['name'] ) ? $offer_product['name'] : ''; | |
| 1833 | + $offer_qty = isset( $offer_product['qty'] ) ? $offer_product['qty'] : 1; | |
| 1834 | + $order = Wpfnl_functions::add_offer_shipping_to_order( $order, $shipping_data, $offer_name, $offer_qty ); | |
| 1835 | + } | |
| 1836 | + | |
| 1847 | 1837 | $order->calculate_totals(); |
| 1848 | 1838 | $order->save(); |
| 1849 | 1839 | |
| 1850 | 1840 | $result = array( |