Senden und erstellen Sie eine Bestellung an der Kasse über Ajax in Woocommerce 3

Lesezeit: 6 Minuten

Benutzeravatar von Tahi Reu
Tahi Reu

Ich habe dem Checkout-Formular eine Schaltfläche hinzugefügt:

<input type="submit" id="ajax-order-btn" class="button" value="Place Order via AJAX" />

und fügte ein AJAX-Snippet hinzu functions.php Datei:

add_action('wp_head', 'ajax_call_place_order');
function ajax_call_place_order() {
    ?>
    <script type="text/javascript" >
        jQuery(document).ready(function($) {
            $(document).on("click", "#ajax-order-btn" ,function(e) {
                e.preventDefault();

                var data = {
                    action: 'ajax_order',
                };

                $.post('<?php echo esc_url( home_url() ); ?>/wp-admin/admin-ajax.php', data);
            });
        });
    </script>
    <?php
}

Und dies ist der AJAX-Rückruf, mit dem eine Bestellung programmgesteuert erstellt wird:

add_action('wp_ajax_ajax_order', 'ajax_order_callback_wp');
add_action( 'wp_ajax_nopriv_ajax_order', 'ajax_order_callback_wp' );
function ajax_order_callback_wp() {

    $address = array(
        'first_name' => 'John',
        'last_name'  => 'Doe',
        'company'    => 'Speed Society',
        'email'      => '[email protected]',
        'phone'      => '760-555-1212',
        'address_1'  => '123 Main st.',
        'address_2'  => '104',
        'city'       => 'San Diego',
        'state'      => 'Ca',
        'postcode'   => '92121',
        'country'    => 'US'
    );


    $order = wc_create_order();

    $order->add_product( get_product('275962'), 1); // This is an existing SIMPLE product
    $order->set_address( $address, 'billing' );
    $order->calculate_totals();
    $order->update_status("Completed", 'Imported order', TRUE);
}

Das Problem ist, dass ich keine Möglichkeit finde, aktuelle Bestelldaten abzurufen und diese Daten beim programmgesteuerten Erstellen von Bestellungen anstelle aktueller festcodierter Daten zu verwenden. Ich muss genau dieselbe Bestellung aufgeben wie die aktuelle auf der Checkout-Seite.

Ich habe es versucht mit WC_Checkoutund Methoden create_order() und get_checkout_fields()aber kein Erfolg.

Benutzeravatar von LoicTheAztec
LoicTheAztec

Für die Erstellung von PHP-Bestellungen verwende ich einen benutzerdefinierten Klon von WC_Checkout create_order() Methode, die perfekt funktioniert. Alle übermittelten Daten werden automatisch in die Bestellung eingetragen.

Für benutzerdefinierte Bestellmetadaten und benutzerdefinierte Bestellartikel-Metadaten können Sie alle Woocommerce-Standard-Hooks wie folgt verwenden:

  • woocommerce_checkout_create_order
  • woocommerce_checkout_update_order_meta
  • woocommerce_checkout_create_order_line_item
  • usw …

Ich habe auch einige notwendige Änderungen im jQuery-Code vorgenommen, damit es gut funktioniert, und die erforderlichen formatierten Daten über Ajax* (das sich jetzt in der Fußzeile befindet)* an PHP gesendet.

Der vollständige Code, der eine Bestellung über Ajax erstellt:

add_action('wp_footer', 'checkout_billing_email_js_ajax' );
function checkout_billing_email_js_ajax() {
    // Only on Checkout
    if( is_checkout() && ! is_wc_endpoint_url() ) :
    ?>
    <script type="text/javascript">
    jQuery(function($){
        if (typeof wc_checkout_params === 'undefined') 
            return false;

        $(document.body).on("click", "#ajax-order-btn" ,function(evt) {
            evt.preventDefault();

            $.ajax({
                type:    'POST',
                url: wc_checkout_params.ajax_url,
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                enctype: 'multipart/form-data',
                data: {
                    'action': 'ajax_order',
                    'fields': $('form.checkout').serializeArray(),
                    'user_id': <?php echo get_current_user_id(); ?>,
                },
                success: function (result) {
                    console.log(result); // For testing (to be removed)
                },
                error:   function(error) {
                    console.log(error); // For testing (to be removed)
                }
            });
        });
    });
    </script>
    <?php
    endif;
}

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     = [];

        // 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.0
         */
        do_action( 'woocommerce_checkout_create_order', $order, $data );

        // Save the order.
        $order_id = $order->save();

        do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );

        echo 'New order created with order ID: #'.$order_id.'.' ;
    }
    die();
}

Der Code wird in die function.php-Datei Ihres aktiven untergeordneten Designs (oder aktiven Designs) eingefügt. Getestet und funktioniert.

Benutzeravatar von mujuonly
mujunur

Machen Sie Ihre JS-Funktion so, dass sie auch die Checkout-Felddaten postet und die Daten erfasst $_POST

 jQuery(document).ready(function($) {
        $(document).on("click", "#ajax-order-btn" ,function(e) {
            e.preventDefault();
            var post_data: $( 'form.checkout' ).serialize()
            var data = {
                action: 'ajax_order',
                post_data : post_data
            };

            $.post('<?php echo esc_url( home_url() ); ?>/wp-admin/admin-ajax.php', data);
        });
    });

  • Danke für die schnelle Antwort. Ich bin mir nicht sicher, ob ich Ihre Antwort richtig verstanden habe, aber ich denke nicht, dass dies eine Lösung ist, da der Kunde neue Felder hinzufügen oder aktuelle Feldnamen bearbeiten kann und ich auch Produkte und Variationen sowie andere Daten benötige.

    – Tahi Reu

    29. März 2019 um 19:10 Uhr

  • Ich habe gerade den Titel und den damit verbundenen Teil “das Problem” bearbeitet.

    – Tahi Reu

    29. März 2019 um 19:15 Uhr

  • Es ist keine Lösung, weil ich nicht weiß, wie die Felder in Zukunft genau heißen werden. Und es gibt keine anderen Bestelldaten weiter – Produkte, Variationen, Preise …

    – Tahi Reu

    30. März 2019 um 8:38 Uhr

1387080cookie-checkSenden und erstellen Sie eine Bestellung an der Kasse über Ajax in Woocommerce 3

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy