TransWikia.com

Allow customer to change the order status in WooCommerce My account

Stack Overflow Asked on December 23, 2021

Looking to create a custom order process that looks like this:

  • Customer adds item to cart
  • During Checkout Process customer uploads design to order
  • On Checkout payment is verified, but not captured
  • After design is finalized by the company, they upload the proof for customer review
  • the customer reviews proof on their dashboard, and clicks a button that processes the order and captures payment
  • I have figured out everything i need to make this happen except for how to allow the customer to change the status of their order in the dashboard. I do not need them to edit the order, just approve it for payment capture.

    I think there should be an easy way to do this with custom PHP code in conjunction with a plugin like Woocommerce Status Control, but I can’t seem to find a solution anywhere.

    2 Answers

    I know I might be a bit late. But here I am answering this question in case anyone still needs it.

    The below code will add a Mark As Completed button in the My Account Order page action list. Please be informed that it checks if the order status is set to Delivered by the admin and then it shows the button to the customers.

    I have developed a plugin for this as well and it's available on WordPress repository. You may check it out in case you need it. Order Approval by Customer for WooCommerce.

    /*================================
        Add Delivered Order Status
    ==================================*/
    
    add_action( 'init', 'msoa_register_delivered_order_status' );
    function msoa_register_delivered_order_status() {
        register_post_status( 'wc-delivered', array(
            'label'                     => 'Session Completed',
            'public'                    => true,
            'show_in_admin_status_list' => true,
            'show_in_admin_all_list'    => true,
            'exclude_from_search'       => false,
            'label_count'               => _n_noop( 'Delivered <span class="count">(%s)</span>', 'Delivered <span class="count">(%s)</span>' )
        ) );
    }
    
    add_filter( 'wc_order_statuses', 'msoa_add_delivered_status_to_order_statuses' );
    function msoa_add_delivered_status_to_order_statuses( $order_statuses ) {
    
        $new_order_statuses = array();
    
        foreach ( $order_statuses as $key => $status ) {
    
            $new_order_statuses[ $key ] = $status;
    
            if ( 'wc-processing' === $key ) {
                $new_order_statuses['wc-delivered'] = __( 'Delivered', 'order-approval' );
            }
        }
    
        return $new_order_statuses;
    }
    
    add_filter( 'woocommerce_my_account_my_orders_actions', 'msoa_mark_as_received', 10, 2 );
    function msoa_mark_as_received( $actions, $order ) {
        $order_id = $order->id;
    
        if ( ! is_object( $order ) ) {
            $order_id = absint( $order );
            $order    = wc_get_order( $order_id );
        }
        
        // check if order status delivered and form not submitted
    
        if ( ( $order->has_status( 'delivered' ) ) && ( !isset( $_POST['mark_as_received'] ) ) ) {
            $check_received = ( $order->has_status( 'delivered' ) ) ? "true" : "false";
            ?>
            <div class="ms-mark-as-received">
                <form method="post">
                    <input type="hidden" name="mark_as_received" value="<?php echo esc_attr( $check_received ); ?>">
                    <input type="hidden" name="order_id" value="<?php echo esc_attr($order_id);?>">
                    <?php wp_nonce_field( 'so_38792085_nonce_action', '_so_38792085_nonce_field' ); ?> 
                    <input class="int-button-small" type="submit" value="<?php echo esc_attr_e( 'Mark as Received', 'order-approval' ); ?>" data-toggle="tooltip" title="<?php echo esc_attr_e( 'Click to mark the order as complete if you have received the product', 'order-approval' ); ?>">
                </form>
            </div>
            <?php
        }
    
        /*
        //refresh page if form submitted
    
        * fix status not updating
        */
        if( isset( $_POST['mark_as_received'] ) ) { 
            echo "<meta http-equiv='refresh' content='0'>";
        }
    
        // not a "mark as received" form submission
        if ( ! isset( $_POST['mark_as_received'] ) ){
            return $actions;
        }
    
        // basic security check
        if ( ! isset( $_POST['_so_38792085_nonce_field'] ) || ! wp_verify_nonce( $_POST['_so_38792085_nonce_field'], 'so_38792085_nonce_action' ) ) {   
            return $actions;
        } 
    
        // make sure order id is submitted
        if ( ! isset( $_POST['order_id'] ) ){
            $order_id = intval( $_POST['order_id'] );
            $order = wc_get_order( $order_id );
            $order->update_status( "completed" );
            return $actions;
        }  
        if ( isset( $_POST['mark_as_received'] ) == true ) {
            $order_id = intval( $_POST['order_id'] );
            $order = wc_get_order( $order_id );
            $order->update_status( "completed" );
        }
    
        $actions = array(
            'pay'    => array(
                'url'  => $order->get_checkout_payment_url(),
                'name' => __( 'Pay', 'woocommerce' ),
            ),
            'view'   => array(
                'url'  => $order->get_view_order_url(),
                'name' => __( 'View', 'woocommerce' ),
            ),
            'cancel' => array(
                'url'  => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ),
                'name' => __( 'Cancel', 'woocommerce' ),
            ),
        );
    
        if ( ! $order->needs_payment() ) {
            unset( $actions['pay'] );
        }
    
        if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ), true ) ) {
            unset( $actions['cancel'] );
        }
    
        return $actions;
    
    }
    

    Answered by M.S Shohan on December 23, 2021

    New improved answer: Allow customer to change order status in WooCommerce

    You can use the following code that will:

    • Replace the button text "view" by "approve" on My account > Orders
    • Display a custom button to approve the order on My account > Order view (single order)
    • Display a custom success message once customer has approved an order

    This will only happen on customer orders with a specific status. So you will have to define:

    • The order status that require an approval from customer.
    • The order status that reflect an approved order by the customer (on the 3 functions)
    • The button text for order approval
    • The text that will be displayed once customer has approved the order

    The code:

    // My account > Orders (list): Rename "view" action button text when order needs to be approved
    add_filter( 'woocommerce_my_account_my_orders_actions', 'change_my_account_my_orders_view_text_button', 10, 2 );
    function change_my_account_my_orders_view_text_button( $actions, $order ) {
        $required_order_status = 'processing'; // Order status that requires to be approved
        
        if( $order->has_status($required_order_status) ) {
            $actions['view']['name'] = __("Approve", "woocommerce"); // Change button text
        }
        return $actions;
    }
    
    // My account > View Order: Add an approval button on the order
    add_action( 'woocommerce_order_details_after_order_table', 'approve_order_button_process' );
    function approve_order_button_process( $order ){
        // Avoiding displaying buttons on email notification
        if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) ) return;
    
        $approved_button_text  = __("Approve this order", "woocommerce");
        $required_order_status = 'processing'; // Order status that requires to be approved
        $approved_order_status = 'completed'; // Approved order status
    
        // On submit change order status
        if( isset($_POST["approve_order"]) && $_POST["approve_order"] == $approved_button_text
        && $order->has_status( $required_order_status ) ) {
            $order->update_status( $approved_order_status ); // Change order status
        }
    
        // Display a form with a button for order approval
        if( $order->has_status($required_order_status) ) {
            echo '<form class="cart" method="post" enctype="multipart/form-data" style="margin-top:12px;">
            <input type="submit" class="button" name="approve_order" value="Approve this order" />
            </form>';
        }
    }
    
    // My account > View Order: Add a custom notice when order is approved
    add_action( 'woocommerce_order_details_before_order_table', 'approved_order_message' );
    function approved_order_message( $order ){
        // Avoiding displaying buttons on email notification
        if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) ) return;
    
        $approved_order_status = 'completed'; // Approved order status
    
        if( $order->has_status( $approved_order_status ) ) {
            wc_print_notice(  __("This order is approved", "woocommerce"), 'success' ); // Message
        }
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.


    On My account > Orders (list):

    enter image description here

    On My account > Order view (when an order required to be approved):

    enter image description here

    On My account > Order view (when customer has approved the order):

    enter image description here


    For order statuses, you can create custom order statuses with code or with plugins.

    Answered by LoicTheAztec on December 23, 2021

    Add your own answers!

    Ask a Question

    Get help from others!

    © 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP