【问题标题】:How to set Payment Gateway by change order from admin side in WooCommerce如何通过 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 选项。

【问题讨论】:

    标签: php wordpress woocommerce payment-gateway orders


    【解决方案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 的帮助!

      【讨论】:

        猜你喜欢
        • 2016-12-09
        • 2021-07-21
        • 2018-01-11
        • 2019-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-21
        • 2023-03-25
        相关资源
        最近更新 更多