Để thực hiện được chức năng này ta cần phải lưu ý các chức năng sau:

  1. Form input cho Thông tin người nhận.
  2. Form input cho Thông tin shipping.
  3. Thông tin thanh toán

Để cho thuận tiện chúng ta sẽ lấy các field input này vào trong From rồi Validate.

$("#btnMuaHang").click(function(){
    if(validate_info() && $("#btnMuaHang").is(":visible")){
        $("#frmOrder input[name=action]").val('ajax_order');
        $(this).html('<i class="fa fa-check" aria-hidden="true"></i> Đang đặt hàng...')
        orderComplete($("#frmOrder").serializeArray());
    }else{
        alert("Vui lòng nhập đầy đủ thông tin!");
    }
});

function validate_info() {
    var valid = true;
    $(".customer input[type=text], .customer select").each(function () {
        if ($(this).val().length === 0) {
            $(this).parent().addClass('has-error');
            valid = false;
        } else {
            $(this).parent().removeClass('has-error');
        }
    });
    if ($('#ship').is(":checked")) {
        $(".shiping input[type=text], .shiping select").each(function () {
            if ($(this).val().length === 0) {
                $(this).parent().addClass('has-error');
                valid = false;
            } else {
                $(this).parent().removeClass('has-error');
            }
        });
    } else {
        $(".shiping input[type=text], .shiping select").each(function () {
            $(this).parent().removeClass('has-error');
        });
    }
    return valid;
}

Tiếp theo sử dụng Ajax để thực thi hành động của nút trong trang check out

function orderComplete(data) {
    $.ajax({
        type: 'POST',
        dataType: 'json',
        url: '/wp-admin/admin-ajax.php',
        data: {
            'action': 'ajax_order',
            'fields': data,
            'user_id': user_id,
        },
        success: function (t) {
            $('#btnMuaHang').html('<i class="fa fa-check" aria-hidden="true"></i> Hoàn tất đơn hàng')
            window.location = 'https://domain.vn/thank-you/?order_id='+ t.order_id;
            Cookies.set("order_id", t.order_id);
        },
        error: function (t, a, e) {
            $('#btnMuaHang').html('<i class="fa fa-check" aria-hidden="true"></i> Hoàn tất đơn hàng')
            alert(t); console.log(e);
        },
        complete: function () {
            // displayAjaxLoading(!1)
        }
    });
};

Sau khi đưa các thông tin phù hợp vào đoạn jQuery ở trên ta tiếp tục viết action vào function.php để thực hiện hành động.

add_action('wp_ajax_ajax_order', 'submited_ajax_order_data');
add_action('wp_ajax_nopriv_ajax_order', 'submited_ajax_order_data');
function submited_ajax_order_data()
{
    if (isset($_POST['fields']) && !empty($_POST['fields'])) {

        $order = new WC_Order();
        $cart = WC()->cart;
        $checkout = WC()->checkout;
        $data = [];
        $fields = $_POST['fields'];

        // Loop through posted data array transmitted via jQuery
        foreach ($_POST['fields'] as $values) {
            // Set each key / value pairs in an array
            $data[$values['name']] = $values['value'];
        }

        $cart_hash = md5(json_encode(wc_clean($cart->get_cart_for_session())) . $cart->total);
        $available_gateways = WC()->payment_gateways->get_available_payment_gateways();

        // Loop through the data array
        foreach ($data as $key => $value) {
            // Use WC_Order setter methods if they exist
            if (is_callable(array($order, "set_{$key}"))) {
                $order->{"set_{$key}"}($value);

                // Store custom fields prefixed with wither shipping_ or billing_
            } elseif ((0 === stripos($key, 'billing_') || 0 === stripos($key, 'shipping_'))
                && !in_array($key, array('shipping_method', 'shipping_total', 'shipping_tax'))) {
                $order->update_meta_data('_' . $key, $value);
            }
        }

        $order->set_created_via('checkout');
        $order->set_cart_hash($cart_hash);
        $order->set_customer_id(apply_filters('woocommerce_checkout_customer_id', isset($_POST['user_id']) ? $_POST['user_id'] : ''));
        $order->set_currency(get_woocommerce_currency());
        $order->set_prices_include_tax('yes' === get_option('woocommerce_prices_include_tax'));
        $order->set_customer_ip_address(WC_Geolocation::get_ip_address());
        $order->set_customer_user_agent(wc_get_user_agent());
        $order->set_customer_note(isset($data['order_comments']) ? $data['order_comments'] : '');
        $order->set_payment_method(isset($available_gateways[$data['payment_method']]) ? $available_gateways[$data['payment_method']] : $data['payment_method']);
        $order->set_shipping_total($cart->get_shipping_total());
        $order->set_discount_total($cart->get_discount_total());
        $order->set_discount_tax($cart->get_discount_tax());
        $order->set_cart_tax($cart->get_cart_contents_tax() + $cart->get_fee_tax());
        $order->set_shipping_tax($cart->get_shipping_tax());
        $order->set_total($cart->get_total('edit'));

        $checkout->create_order_line_items($order, $cart);
        $checkout->create_order_fee_lines($order, $cart);
        $checkout->create_order_shipping_lines($order, WC()->session->get('chosen_shipping_methods'), WC()->shipping->get_packages());
        $checkout->create_order_tax_lines($order, $cart);
        $checkout->create_order_coupon_lines($order, $cart);

        /**
         * Action hook to adjust order before save.
         * @since 3.0.0wc_get_payment_gateway_by_order
         */
        do_action('woocommerce_checkout_create_order', $order, $data);

        // Save the order.
        $order_id = $order->save();
        $log = array(
            '$fields' => $fields,
            '$data' => $data,
            '$order' => $order,
            'order_id' => $order_id,
        );
        do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );
        echo wp_send_json($log);
    }
    die();
}

 

Ở đây ta có các lưu ý: Truyền dữ liệu giỏ hàng vào order. Đưa các thông tin đặt hàng vào biến order và phương thức thanh toán. Sau đó ta dùng action woocommerce_checkout_create_order để tạo order. Khi tạo order thành công chúng ta lấy order_id để tạo dữ liệu đơn hàng gửi đến người dùng qua trang thank you page.

Cuối cùng bắt dữ liệu trả về để có thể redirect trang qua trang thank you page. Trường hợp bị lỗi bạn có thể show thông tin lỗi để người dùng có thể thao tác lại

 

Chúc các bạn thành công!