[WooCommerce] 開通消費者端取消訂單功能的方法

本篇文章更新時間:2020/04/23
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~


時常發現消費者下單後反悔或是下錯單的時候,都會透過聯絡功能來信表示希望取消某筆訂單。

這樣的操作如果覺得麻煩,希望把功能開放給消費者的話可以將下方程式置入(子)主題 functions.php 中使用,或是安裝 WC Cancel Order 外掛來處理。

function mxp_wc_order_cancelled_request() {
    if (!is_user_logged_in()) {
        wp_send_json_error(array('err' => "你想幹嘛?", 'code' => 403));
    }

    $args = array(
        'order_id' => FILTER_SANITIZE_STRING,
        '_wpnonce' => FILTER_SANITIZE_STRING,
        'reason'   => FILTER_SANITIZE_STRING,
    );

    $all_inputs = filter_input_array(INPUT_GET, $args);
    $order_id   = isset($all_inputs['order_id']) && (int) $all_inputs['order_id'] ? (int) $all_inputs['order_id'] : '';
    $note       = $all_inputs['reason'];
    if (!wp_verify_nonce($all_inputs['_wpnonce'], 'mxp-wc-check-referer')) {
        wp_send_json_error(array('err' => "驗證失敗", 'code' => 403));
    }

    if (!$order_id) {
        wp_send_json_error(array('err' => "輸入資料有誤", 'code' => 500));
    }
    $uid = wp_get_current_user();
    if ($uid->exists()) {
        $uid = $uid->ID;
    } else {
        $uid = null;
    }
    if (empty($uid)) {
        wp_send_json_error(array('err' => "使用者不存在", 'code' => 500));
    }
    $order = wc_get_order($order_id);
    if (!is_object($order)) {
        wp_send_json_error(array('err' => "訂單不存在", 'code' => 500));
    }
    if ($order->get_user_id() != $uid) {
        wp_send_json_error(array('err' => "訂單不正確", 'code' => 500));
    }
    $order->update_status('cancelled');
    $mailer = WC()->mailer();
    $mails  = $mailer->get_emails();
    if (!empty($mails)) {
        foreach ($mails as $mail) {
            if ($mail->id == 'cancelled_order') {
                $mail->trigger($order_id);
            }
        }
    }
    if (!empty($note)) {
        $order->add_order_note("客戶取消訂單備註:" . esc_html($note));
    }
    wp_send_json_success(array('msg' => "訂單取消成功", 'code' => 200));
}
add_action('wp_ajax_mxp_wc_order_cancelled_request', 'mxp_wc_order_cancelled_request');

function mxp_view_order_cancelled_btn($order_id) {
    $order = wc_get_order($order_id);
    //金流走「銀行轉帳」且「未付款」狀態為「保留」的條件下才顯示「取消訂單」
    if ($order->has_status(array('on-hold')) && $order->get_payment_method() == "bacs") {
        $url = wp_nonce_url(admin_url('admin-ajax.php?action=mxp_wc_order_cancelled_request&order_id=' . $order_id), 'mxp-wc-check-referer');
        echo '<a href="#" data-url="' . esc_url($url) . '" data-order="' . $order_id . '" id="mxp_cancelled_btn" class="button">取消訂單</a>';
    }
    ?>
<script>
(function($){
    $(document).ready(function() {
        $('#mxp_cancelled_btn').click(function(){
            if (!confirm("確認取消訂單嗎?")){
                return;
            }
            var reason = prompt("請輸入取消的原因", "");
            if (reason==""){
                alert("請輸入取消原因!");
                return;
            }
            var url = $(this).data('url');
            var req = $.ajax({
              type: "GET",
              url: url,
              data:{reason:reason}
            });
            req.done(function( resp, textStatus, jqXHR ) {
              if (resp.success){
                alert(resp.data.msg);
                location.reload();
              } else {
                alert(resp.data.err);
              }
            });
            req.fail(function( jqXHR, textStatus, errorThrown) {
              alert( "請求發生錯誤: " + textStatus );
            });
        });
    });
})(jQuery)
</script>
<?php
}
add_action('woocommerce_view_order', 'mxp_view_order_cancelled_btn', 10, 1);

透過開發的話使用彈性大,這個做法與外掛的設計有些不同。外掛多包了一層「請求取消」的狀態,所以不會直接針對訂單操作取消,還是由管理人員來確認後操作。可以說是把原本大家都會透過聯絡表單的作法包裝過,滿完整的!

而我開發的版本僅是在「我的帳號」的「訂單」中檢視訂單內頁下方多了一個「取消訂單」按鈕,點擊後經過確認就直接取消了~ (畢竟消費者都這麼確認要取消了,還等管理員來多處理一次做什麼呢?)


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[//////////____30%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *