Woocommerce:使用ajax支付一半(50%)货到付款

时间:2017-10-13 10:27:29

标签: php jquery ajax wordpress woocommerce

我正在尝试制作一个ajax功能,让用户支付总金额的一半,定制货到付款方式。当用户选择是或否单选按钮时,总金额会相应更改。

这个:Link是我想要遵循的一个很好的例子,但我需要将其作为ajax调用。

以下是我在付款冻结之前添加新字段的方式:

add_action("woocommerce_review_order_before_payment", "new_buttons");
function new_buttons(){
 echo '<div id="cash-on-delivery-wrap" class="cash-on-delivery-wrap">';
 echo '<h5>Cash on delivery: </h5><div style="clear:both"></div>';
 echo '<h6>Pay half 50%</h6><div style="clear:both"></div>';
 echo '<div class="cod_button_wrap">';
 echo '<label><input type=radio value="no" name="new-cod" checked/>No</label>';
 echo '<label><input type=radio value="yes" name="new-cod" />Yes</label>';
 echo '</div>';
 echo '</div>';
}

这是JS:

jQuery(document).ready(function(){
  jQuery("form.checkout").on("change", "#cash-on-delivery-wrap input", 
   function(){
     var data = {
        action: 'change_cod',
        security: wc_checkout_params.update_order_review_nonce,
        post_data: jQuery( 'form.checkout' ).serialize()
     };

     jQuery.post( ajaxurl, data, function( response )
     {
        jQuery( 'body' ).trigger( 'update_checkout' );
     });
   });
});

这是功能:

function custom_cart_total() {
 $current_state = $_POST['post_data'];
 if ( is_admin() && ! defined( 'DOING_AJAX' ) )
 return;
 if($current_state=='yes'){
    WC()->cart->total *= 0.50;
 }else{
    WC()->cart->total;
 }
 exit;
}
add_action( 'wp_ajax_nopriv_change_cod', 'custom_cart_total' );
add_action( 'wp_ajax_change_cod', 'custom_cart_total' ); 

似乎无法使其发挥作用,我在这里缺少什么。

1 个答案:

答案 0 :(得分:1)

  

注意:链接答案中的代码仅在购物车和结帐中更改显示的总金额,但不会更改为真实。

     

此答案也会更改显示的结帐总额。我们需要在订单创建过程中附加另一个功能,以更新总金额。

对于Wordpress Ajax,您需要在外部JS文件中注册脚本,该文件将在js子文件夹中的活动主题文件夹中上传。假设此外部文件名为 pay_half.js

1)这是将执行该注册并将启用WordPress Ajax功能的函数:

add_action( 'wp_enqueue_scripts', 'ajax_change_shipping' );
function ajax_change_shipping() {
    // Only on front-end and checkout page
    if( is_admin() || ! is_checkout() ) return;

    // Get the Path to the active theme or child theme or plugin folder
    # $path = plugin_dir_url( __FILE__ ); // A plugin
    # $path = get_template_directory_uri(); // A Normal theme
    $path = get_stylesheet_directory_uri(); // A child theme

    // Define the subfolder name
    $subfolder = 'js';

    // Define the file name
    $filename = 'pay_half.js';

    // Reference name of the script (should be unique)
    $handle = 'pay-half';

    // Set the ajaxurl parameter used in your script
    $data = array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
    );

    // The variable name whichwill contain the data
    $name = 'pay_half';

    // Registering the javascript file and enqueues it.
    wp_enqueue_script( $handle, $path."/$subfolder/$filename", array( 'jquery' ), '1.0', true );

    // Localizing the registered script (Here using Ajax)
    wp_localize_script( $handle, $name, $data );
}

代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。

2)现在Javascript / jQuery外部文件(名为:pay_half.js

jQuery(document).ready(function ($) {
    var selectHalf = '#cash-on-delivery-wrap input[type="radio"]',
        paymentMethod = 'input[name^="payment_method"]',
        codWrap = $('.cash-on-delivery-wrap'),
        cartGTotal = $('input#cart_gtotal').val(),
        codPartial;

    // Detecting payment method on load to show/hide cod custom options
    if( $(paymentMethod+':checked').val() == 'cod' )
        codWrap.show("fast");
    else
        codWrap.hide("fast");

    // Live detecting choosen payment method to show/hide cod custom options
    $( 'form.checkout' ).on( 'change', 'input[name^="payment_method"]', function() {
        if ( $(paymentMethod+':checked').val() == 'cod' ) {
            codWrap.show("fast");
        } else {
            codWrap.hide("fast");
            $('#cash-on-delivery-wrap input#cod-options_no').prop('checked', true);
        }
        $(document.body).trigger("update_checkout");
        // console.log($(paymentMethod+':checked').val());
    });

    // The "Cod" custom options (ajax)
    $(selectHalf).click(function(){
        if($(selectHalf+':checked' ).val() == 'yes' ) codPartial = 'yes';
        else codPartial = 'no';

        $.ajax({ // This does the ajax request
            url: pay_half.ajaxurl,
            type : 'post',
            data: {
                'action':'cod_partial_payment', // Name of the php function
                'cod_partial' : codPartial       // Passing this variable to the PHP function
            },
            success:function(data) {
                // Displaying the price (Ajax)
                $( 'table.shop_table > tfoot > tr.order-total > td > strong > span' ).html(data.price_html);
                if(codPartial == 'yes')
                    $('input#cart_remaining').val(data.price_remaining);
                else
                    $('input#cart_remaining').val(0);
                $(document.body).trigger("wc_fragment_refresh");
                console.log(data);
            },
            error: function(error){
                console.log(error);
            }
        });
    });
});

3)显示自定义字段(已修改)

我添加了2个隐藏字段,其中包含总金额和剩余金额。

add_action( 'woocommerce_review_order_before_payment', 'cod_payment_options', 10 );
function cod_payment_options(){
    echo '<style>.cod-button-options label{display:inline-block; margin:0 6px;}</style>
    <div id="cash-on-delivery-wrap" class="cash-on-delivery-wrap">
        <h3>' . __( 'Cash on delivery option' ) . '</h3>';

    woocommerce_form_field( 'cod-options', array(
        'type'      => 'radio',
        'class'     => array('form-row-wide', 'cod-button-options'),
        'label'     => __( '<b>Pay half (50%): </b>' ),
        'required' => false,
        'options' => array(
            'no'  => __( 'No' ),
            'yes' => __( 'Yes' ),
        )
    ), 'no' );

    // Some additional hidden fields
    echo '<input type="hidden" id="cart_gtotal" name="cart_gtotal" value="'. WC()->cart->total .'">
        <input type="hidden" id="cart_remaining" name="cart_remaining" value="0" />
        </div>';
}

代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。

4)驱动的php函数(Wordpress Ajax):

add_action( 'wp_ajax_nopriv_cod_partial_payment', 'cod_partial_payment' );
add_action( 'wp_ajax_cod_partial_payment', 'cod_partial_payment' );
function cod_partial_payment() {
    if( ! isset($_POST['cod_partial']) ) return;

    $current_state = $_POST['cod_partial'];
    $remaining = 0;

    if( $current_state == 'yes' ){
        WC()->cart->total /= 2;
    }
    WC()->session->set( 'total', WC()->cart->total );

    $response = array(
        'price_html'        => wc_price( WC()->cart->total ),
        'price_remaining'   => WC()->cart->total,
    );

    header( 'Content-Type: application/json' );
    echo json_encode( $response );

    die(); // Always (to avoid an error 500)
}

代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。

5)所有其他php功能(更新订单金额,保存元数据,显示消息):

// Replacing the total amount when COD option is enabled
add_action( 'woocommerce_checkout_create_order', 'cod_options_change_order_total_ammount', 10, 2 );
function cod_options_change_order_total_ammount( $order, $data ) {
    if ( ! empty( $_POST['cod-options'] ) && $_POST['cod-options'] == 'yes' ) {
        $remaining = sanitize_text_field( $_POST['cart_remaining'] );
        $total = WC()->cart->total - floatval($remaining);
        WC()->session->set( 'total', $total );
        $order->set_total( $total );
    }
}


// Updating order meta data for Cod selected option
add_action( 'woocommerce_checkout_update_order_meta', 'cod_options_update_order_meta', 10, 1 );
function cod_options_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['cod-options'] ) && $_POST['cod-options'] == 'yes' ) {
        update_post_meta( $order_id, '_cod_remaining_amount', sanitize_text_field( $_POST['cart_remaining'] ) );
        update_post_meta( $order_id, '_cod_partial_paid_amount', sanitize_text_field( $_POST['cart_gtotal'] - $_POST['cart_remaining'] ) );
    }
    update_post_meta( $order_id, '_cod_partial_payment_option', sanitize_text_field( $_POST['cod-options'] ) );
}

// Displaying the remaining amount to pay in a custom message on Order received page (thank you)
add_action( 'woocommerce_thankyou_cod', 'cod_options_woocommerce_thankyou', 10, 1 );
function cod_options_woocommerce_thankyou( $order_id ) {
    if( get_post_meta( $order_id, '_cod_partial_payment_option', true ) == 'yes' ){
        $ra = '<span style="color:#96588a;">'.wc_price( get_post_meta( $order_id, '_cod_remaining_amount', true )).'</span>';
        ?>
            <ul class="woocommerce-order-overview woocommerce-thankyou-cod-options order_details">
                <li class="woocommerce-order-overview__remaining_total order">
                <strong><?php echo __("There is a remaining amount of $ra to pay on this order."); ?></strong>
                </li>
            </ul>
        <?php
    }
}

代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。

此代码在Woocommerce 3+上进行测试并正常运行。