如何通过 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 中管理员端的更改订单设置支付网关的主要内容,如果未能解决你的问题,请参考以下文章

列出 Woocommerce 中所有启用的付款方式

WooCommerce 复合产品:如何使用 URL 参数更改组件的默认产品选项?

在 WooCommerce 管理员订单仪表板中更新客户密码

通过单击变体图像 Woocommerce 更改产品变体

通过 WooCommerce 3+ 中的挂钩更改产品价格

如何从 WooCommerce 订单中更改 Paypal 项目名称?