I'm currently working on a WooCommerce project, and I'm trying to implement a feature where an order note is added when a user changes the payment method during the order editing process in the WooCommerce admin panel. However, I'm facing an issue in capturing the new payment method.
Here's an example:
Here's the code I'm using:
add_action('woocommerce_admin_order_data_after_billing_address', 'order_update_note');
function order_update_note()
{
global $post;
$order_id = get_the_ID();
$order = wc_get_order($order_id);
$current_user = wp_get_current_user();
$user_now = $current_user->display_name;
$current_payment_method = $order->get_payment_method();
?>
<script>
jQuery(document).ready(function($) {
$('.save_order').on('click', function() {
var orderid = <?php echo $order_id; ?>;
var user_now = '<?php echo $user_now; ?>';
var payment_method = $('#order_data .wc-order-data-row .order_data_column .order_data_column-inner select[name="_payment_method"]').val();
console.log(orderid);
console.log(user_now);
console.log(payment_method);
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'update_order_add_note',
orderid: orderid,
user_now: user_now,
payment_method: payment_method
},
success: function( response ) {
console.log( 'Custom field updated successfully.' );
},
error: function( response ) {
console.log( 'Failed to Submit Expense.' );
}
});
});
});
</script>
<?php
}
add_action('wp_ajax_update_order_add_note', 'update_order_add_note');
add_action('wp_ajax_nopriv_update_order_add_note', 'update_order_add_note');
function update_order_add_note()
{
$orderid = $_POST['orderid'];
$user_now = $_POST['user_now'];
$order = wc_get_order($orderid);
$payment_method = $_POST['payment_method'];
$current_payment_method = $order->get_payment_method();
if ($payment_method !== $current_payment_method) {
$note = "Order details updated by ".$user_now . " Payment method changed from ".$current_payment_method." to ".$payment_method."\n";
$order->add_order_note($note);
$order->save();
wp_send_json_success();
} else {
wp_send_json_error();
}
}
Here's a breakdown of my code:
I have added a custom JavaScript function that runs when the "Save Order" button is clicked in the WooCommerce order edit screen. This function captures the order ID, the user making the change, and the payment method selected by the user.
On the PHP side, I have set up an AJAX callback function that receives the data sent by the JavaScript function. In this callback function, I attempt to capture the new payment method and compare it with the existing payment method for the order.
The issue is that I'm not successfully fetching the new payment method. The variable $payment_method
I would greatly appreciate any insights or suggestions on how to correctly capture the new payment method when it's changed by the user during the order editing process
updated
You can use the following different and most effective way:
// When order is created after checkout, add a custom field
add_action( 'woocommerce_checkout_order_created', 'save_payment_method_origin', 20 );
function save_payment_method_origin( $order) {
if( $payment_method = $order->get_payment_method() ) {
$order->add_meta_data('_payment_origin', $payment_method );
$order->save();
}
}
// Add 2 hidden fields on admin single order
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'admin_order_custom_hidden_input_fields' );
function admin_order_custom_hidden_input_fields( $order ) {
global $current_user;
echo '<input type="hidden" name="user_name" value="'.$current_user->display_name.'" />
<input type="hidden" name="user_id" value="'.$current_user->ID.'" />';
}
// Adding an order note when payment method is changed
add_action( 'woocommerce_process_shop_order_meta', 'admin_order_payment_method_change' );
function admin_order_payment_method_change( $order_id ) {
$order = wc_get_order( $order_id );
$payment_method = $order->get_payment_method();
$payment_origin = $order->get_meta('_payment_origin');
if ( ! empty($payment_origin) && $payment_method != $payment_origin
&& isset($_POST['user_name']) && isset($_POST['user_id']) ) {
$order->update_meta_data('_payment_origin', $payment_method);
$order->add_order_note( sprintf( __('Payment method changed from %s to %s by %s (Id %d)'),
$payment_origin, $payment_method, esc_attr($_POST['user_name']), intval($_POST['user_id']) ) . "\n" );
$order->save();
} elseif ( empty($payment_origin) && ! empty($payment_method) ) {
$order->update_meta_data('_payment_origin', $payment_method);
$order->save();
}
}
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.