注意:链接答案中的代码仅更改购物车和结帐中显示的总金额,但不会真正更改。
这个答案也改变了显示的结帐总额。我们需要在订单创建过程中挂接另一个函数来更新总金额。
对于 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 外部文件 (named: 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+ 上经过测试并且可以正常工作。