如何通过 WooCommerce 中管理员端的更改订单设置支付网关
Posted
技术标签:
【中文标题】如何通过 WooCommerce 中管理员端的更改订单设置支付网关【英文标题】:How to set Payment Gateway by change order from admin side in WooCommerce 【发布时间】:2017-04-19 12:25:47 【问题描述】:请帮忙!我正在尝试通过更改管理员的订单详细信息来定义支付网关。
作为默认选项,我想使用“bacs”支付网关。客户下订单,然后我想更改订单并将付款方式转到自定义“payment2”网关。
为此,我制作了带有复选框的元框,它应该打开/关闭“payment2”方法并取消设置默认的“bacs”。复选框工作正常。
但是,我无法让它工作。首先,我无法获得带有复选框值的帖子元。请检查以下代码:
function show_payment2_payment_gateway( $available_gateways )
$use_payment2 = get_post_meta( $post->ID, 'use_payment2', true );
if($use_payment2 == "yes")
unset( $available_gateways['bacs'] );
else
unset( $available_gateways['payment2'] );
return $available_gateways;
add_filter( 'woocommerce_available_payment_gateways', 'show_payment2_payment_gateway', 10, 1 );
更新
这是我的后端复选框代码。正如我所说,它运行良好并将元值保存为“是”
//
//Adding Meta container admin shop_order pages
//
add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
function mv_add_meta_boxes()
global $woocommerce, $order, $post;
add_meta_box( 'mv_other_fields', __('PAYMENT2','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
//
//adding Meta field in the meta container admin shop_order pages
//
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
function mv_add_other_fields_for_packaging()
global $woocommerce, $order, $post;
$meta_field_data = get_post_meta( $post->ID, 'use_payment2', true );
$meta_field_data_checked = $meta_field_data["use_payment2"][0];
if($meta_field_data == "yes") $meta_field_data_checked = 'checked="checked"';
echo '
<label for="use_epay">TURN PAYMENT2 ON?</label>
<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">
<input type="checkbox" name="use_payment2" value="yes" '.$meta_field_data_checked.'>';
//
//Save the data of the Meta field
//
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
function mv_save_wc_order_other_fields( $post_id )
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) )
return $post_id;
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) )
return $post_id;
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] )
if ( ! current_user_can( 'edit_page', $post_id ) )
return $post_id;
else
if ( ! current_user_can( 'edit_post', $post_id ) )
return $post_id;
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
update_post_meta( $post_id, 'use_payment2', $_POST[ 'use_payment2' ] );
更新
这是后端(自定义复选框元框)的工作代码。它保存复选框值并在订单详细信息中更改付款方式:
//
//Adding Meta container admin shop_order pages
//
add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
function mv_add_meta_boxes()
global $woocommerce, $order, $post;
add_meta_box( 'mv_other_fields', __('PAYMENT2','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
//
//adding Meta field in the meta container admin shop_order pages
//
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
function mv_add_other_fields_for_packaging()
global $woocommerce, $order, $post;
$meta_field_data = get_post_meta( $post->ID, 'use_payment2', true );
echo '<label for="use_payment2">USE PAYMENT2?</label>
<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">';
if($meta_field_data == "yes")
$meta_field_data_checked = 'checked="checked"';
echo'<input type="checkbox" name="use_payment2" value="yes" '.$meta_field_data_checked.'>';
else
echo'<input type="checkbox" name="use_payment2" value="yes">';
//Save the data of the Meta field
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
function mv_save_wc_order_other_fields( $post_id )
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) )
return $post_id;
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) )
return $post_id;
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] )
if ( ! current_user_can( 'edit_page', $post_id ) )
return $post_id;
else
if ( ! current_user_can( 'edit_post', $post_id ) )
return $post_id;
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
$use_payment2 = sanitize_text_field($_POST[ 'use_payment2' ]);
update_post_meta( $post_id, 'use_payment2', $use_payment2 );
if($_POST[ 'use_payment2' ] == 'yes')
update_post_meta( $post_id, '_payment_method', 'payment2' );
elseif (get_post_meta( $post_id, '_payment_method', true ) != 'bacs')
update_post_meta( $post_id, '_payment_method', 'bacs' );
但是,我如何在前端使用复选框状态?我仍然无法使用此代码获取复选框值:
function show_payment2_payment_gateway( $available_gateways )
global $woocommerce, $order, $post;
$payment_method = get_post_meta( $post_id, 'use_payment2', true );
if(isset($payment_method) == 'yes')
unset( $available_gateways['bacs'] );
else
unset( $available_gateways['payment2'] );
return $available_gateways;
add_filter( 'woocommerce_available_payment_gateways', 'show_payment2_payment_gateway', 10, 1 );
现在,即使选中或未选中复选框,它也始终显示 Payment2 选项。
【问题讨论】:
【参考方案1】:与您的 cmets 相关的更新 2 (以及您的问题更新)
您使用的钩子是前端钩子(不是管理员),所以它不起作用。
要实现想要的功能,您需要在后端(管理员)编辑订单页面中更新订单时替换函数内的一些代码,这些代码将保存您的自定义复选框值。
所以你的代码现在是这样的:
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
function mv_save_wc_order_other_fields( $post_id )
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) )
return $post_id;
// Passing the value to a variable
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] )
if ( ! current_user_can( 'edit_page', $post_id ) )
return $post_id;
else
if ( ! current_user_can( 'edit_post', $post_id ) )
return $post_id;
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
$use_payment2 = sanitize_text_field($_POST[ 'use_payment2' ]);
update_post_meta( $post_id, 'use_payment2', $use_payment2 );
// Updating securely the data with your conditions
if($use_payment2 == 'yes')
update_post_meta( $post_id, '_payment_method', 'payment2' );
else
update_post_meta( $post_id, '_payment_method', 'bacs' );
现在应该可以正常工作了……
代码进入您的活动子主题(或主题)的 function.php 文件中。或者也可以在任何插件 php 文件中。
由于此代码来自my answers 之一,因此您没有义务保留与问题用户名相关的以"mv_"
开头的相同函数。例如,您可以将其更改为 "dan_"
……
参考:WooCommerce : Add custom Metabox to admin order page
【讨论】:
我已经用我的复选框的后端函数更新了代码。请检查一下好吗? 对不起,它不起作用。现在我的复选框不保存状态值,只显示选中状态 谢谢你,我做了一些编辑,现在它在后端工作得很好。但是,我仍然无法让它在前端工作。请检查我更新的代码好吗? 您好,非常感谢您的帮助。但是,我发现了另一种使用端点“订单支付”的简单方法。代码检查是否是 woocommerce 端点并显示已定义的支付网关。 @danibeiss 您应该在问题的最后进行更新……这可能对人们有用,不是吗?【参考方案2】:在 WooCommerce 中列出默认支付网关的函数是 core_gateways()。此函数与名为 woocommerce_payment_gateways 的过滤器挂钩。因此,第一步是删除该过滤器并添加我们自己的过滤器。我只会在主题文件夹中的 functions.php 文件中工作(记得吗?永远不要修改核心文件)。为此,我们将使用 remove_filter() 和 add_filter() 函数:
remove_filter( 'woocommerce_payment_gateways', 'core_gateways' );
add_filter( 'woocommerce_payment_gateways', 'my_core_gateways' );
现在我们已经删除了过滤器,您可以看到在 add_filter() 函数中我们有一个名为 my_core_gateways 的回调。此回调是将替换默认 core_gateways() 函数的函数的名称。此功能是列出 WooCommerce 默认支付网关的功能。我将更改该函数的内容并替换对 WC_Gateway_BACS 类的调用。该类是银行转账默认类。这是该新功能的代码:
/**
* core_gateways function modified.
*
* @access public
* @param mixed $methods
* @return void
*/
function my_core_gateways( $methods )
$methods[] = 'WC_Gateway_BACS_custom';
$methods[] = 'WC_Gateway_Cheque';
$methods[] = 'WC_Gateway_COD';
$methods[] = 'WC_Gateway_Mijireh';
$methods[] = 'WC_Gateway_Paypal';
return $methods;
如您所见,我所做的唯一更改是将 WC_Gateway_BACS 替换为 WC_Gateway_BACS_custom。
你还在我身边吗?好吧,总而言之,我需要删除调用默认支付网关的过滤器,并使用自定义函数。在这个自定义函数中,我替换了对 BACS 类的调用,现在我需要创建这个新的 BACS 类。为此,请使用该代码:
class WC_Gateway_BACS_custom extends WC_Gateway_BACS
/**
* Process the payment and return the result
*
* @access public
* @param int $order_id
* @return array
*/
function process_payment( $order_id )
global $woocommerce;
$order = new WC_Order( $order_id );
// Mark as processing (that's what we want to change!)
$order->update_status('processing', __( 'Awaiting BACS payment', 'woocommerce' ));
// Reduce stock levels
$order->reduce_order_stock();
// Remove cart
$woocommerce->cart->empty_cart();
// Return thankyou redirect
return array(
'result' => 'success',
'redirect' => add_query_arg('key', $order->order_key, add_query_arg('order', $order->id, get_permalink(woocommerce_get_page_id('thanks'))))
);
在这个 sn-p 中,我只是将默认状态从“等待”更改为“处理中”……。魔法出现了!现在,使用 BACS 支付网关支付的每个订单都将被标记为处理中,而不是暂停。
【讨论】:
【参考方案3】:经过几天的头痛后,我找到了一种简单的方法,即仅在向客户发送链接时才显示定义的支付网关。
现在客户可以使用默认的“bacs”方式下订单,管理员可以在付款前检查。然后管理员将订单状态更改为等待付款并将链接发送给客户。当客户打开链接时,我的自定义支付网关就会激活。
我决定使用 woocommerce 端点来检查它是否是“订单支付”页面。我使用了以下代码:
function show_payment2_payment_gateway( $available_gateways )
global $woocommerce, $order, $post;
if (is_wc_endpoint_url( 'order-pay' ))
unset( $available_gateways['bacs'] );
else
unset( $available_gateways['payment2'] );
return $available_gateways;
add_filter( 'woocommerce_available_payment_gateways', 'show_payment2_payment_gateway', 10, 1 );
现在它完全按照我之前的要求工作了。我希望这会有用。感谢@LoicTheAztec 的帮助!
【讨论】:
以上是关于如何通过 WooCommerce 中管理员端的更改订单设置支付网关的主要内容,如果未能解决你的问题,请参考以下文章