Ubercart 3: Skip review, single page checkout I am using Drupal 7.12 and Ubercart 3.0. I created a custom module in order to enable a single page checkout by skipping the checkout review page.

The Code

/**
 * Implementation of hook_form_submit().
 * 
 * Change Ubercart review pages to instant order submissions.
 */
function uc_onepagecheckout_form_submit($form, &amp;$form_state) {
    // check for order submit
    if(isset($form_state['storage']['order'])) {
        $order_id = $form_state['storage']['order']-&gt;order_id;
        $reviewRequested = $_SESSION['uc_checkout'][$order_id]['do_review'];
    }

    // If the normal submit handler set do_review then call the review
    // form submit function.
    if ($reviewRequested &amp;&amp; $form_state['redirect'] == 'cart/checkout/review') {
        // Clear the previous redirect because we're going to override it anyway.
        unset($form_state['redirect']);

        // Cause the review form to be loaded because some modules may
        // do some of their processing here.
        uc_cart_checkout_review();

        $order = uc_order_load($_SESSION['cart_order']);
        if ($order-&gt;payment_method == 'paypal_wps') {
            $wps_form = uc_paypal_wps_form($form, $form_state, $order);
            $wps_url = $wps_form['#action'] . '?';
            foreach (element_children($wps_form) as $key) {
                $wps_url .= urlencode($key) . '=' . urlencode($wps_form[$key]['#value']) . '&amp;';
            }      
            $wps_url = trim($wps_url, '&amp;');
            drupal_goto($wps_url);
        }
        else {
            // Now submit the form.  Obviously the $form_state isn't actually
            // correct... hopefully nothing will care.
            uc_cart_checkout_review_form_submit($form, $form_state);

            // And check for an error.
            if ($form_state['redirect'] == 'cart/checkout/review') {
                // There's an error, so pretend the user clicked back.
                uc_cart_checkout_review_form_back($form, $form_state);
            }
        }

        // Ultimately the $form_state changes made by functions above are used.
    }
    elseif ($form_state['redirect'] != 'cart/checkout') {
        // Log any unexpected URLs in 'redirect'.
        watchdog('uc_cart', 'Checkout returned unexpected destination url: %url',
            array('%url' =&gt; $form_state['redirect']), WATCHDOG_DEBUG);
    }
}

/**
 * Implementation of hook_form_alter().
 *
 * Changes text on review order button to submit order and adds our custom submit function.
 * Adds a "Skip checkout review" option to checkout settings form.
 */
function uc_onepagecheckout_form_alter(&amp;$form, $form_state, $form_id) {
    switch ($form_id) {
        case 'uc_cart_checkout_form':
            // Change the submit button label.
            $form['actions']['continue']['#value'] = variable_get('uc_checkout_submit_button', t('Submit order'));

            // Add our submit handler.
            $form['#submit'][] = 'uc_onepagecheckout_form_submit';
            // And add our JavaScript file to handle this submit button.
            drupal_add_js(drupal_get_path('module', 'uc_optional_checkout_review') .'/uc_onepagecheckout_checkout_form.js');
            // Add the uc_cart css, since it contains the throbber styles that we are using in the JavaScript.
            drupal_add_css(drupal_get_path('module', 'uc_cart') .'/uc_cart.css');

            break;
    }
}


This code is based on this module: Ubercart Optional Checkout Review

The Problem

Submitted orders are getting stuck in the "in_checkout" state instead of having the "pending" state. Also, no emails are sent to the customers. Probably, the invocation of uc_cart_checkout_review_form_submit($form, $form_state) does not work properly.

Can you help me to solve this issue?
I found it myself. The problem was a non-intended change in the ubercart core file uc_cart.pages.inc, so that the function uc_cart_checkout_complete() instantly returned without completing the order. This should not occur in normal cases, so that the code in my question should work.