diff --git a/payment_ubercart.info b/payment_ubercart.info
index 3cf158c..54e6aa7 100644
--- a/payment_ubercart.info
+++ b/payment_ubercart.info
@@ -7,5 +7,6 @@ dependencies[] = uc_payment
 test_dependencies[] = xtools
 package = Payment
 files[] = tests/PaymentUbercartCallablesWebTestCase.test
+files[] = tests/PaymentUbercartCheckoutWebTestCase.test
 files[] = tests/PaymentUbercartDeleteOrderWebTestCase.test
 files[] = tests/PaymentUbercartMenuRouterItemPermissionWebTestCase.test
diff --git a/payment_ubercart.module b/payment_ubercart.module
index 015e58f..b8baa36 100644
--- a/payment_ubercart.module
+++ b/payment_ubercart.module
@@ -131,79 +131,11 @@ function payment_ubercart_views_api() {
 function payment_ubercart_callback($op, &$order, array $form = NULL, array &$form_state = NULL) {
   // Checkout form display.
   if ($op == 'cart-details') {
-    // Check for an existing new payment.
-    $payment = isset($order->data['payment_pid']) ? entity_load_single('payment', $order->data['payment_pid']) : NULL;
-    $pid = $payment && payment_status_is_or_has_ancestor($payment->getStatus()->status, PAYMENT_STATUS_NEW) ? $payment->pid : 0;
-
-    // Create the payment object.
-    $pmid = (int) str_replace('payment_ubercart_', '', $order->payment_method);
-    $payment = new Payment(array(
-      'context' => 'payment_ubercart',
-      'currency_code' => $order->currency,
-      'description' => t('Order #!order_id', array(
-        '!order_id' => $order->order_id,
-      )),
-      'finish_callback' => 'payment_ubercart_finish',
-      'method' => entity_load_single('payment_method', $pmid),
-      'payment_ubercart_uc_order_id' => $order->order_id,
-      'pid' => $pid,
-    ));
-
-    // Add orders, line items, and hook_uc_order() totals to the payment as line items.
-    $order->order_total = uc_order_get_total($order);
-    $balance = uc_payment_balance($order);
-    if ($order->order_total == $balance) {
-      foreach ($order->products as $product) {
-        $payment->setLineItem(new PaymentLineItem(array(
-          'amount' => $product->price,
-          'description' => $product->title,
-          'quantity' => $product->qty,
-          'name' => 'payment_ubercart_product_' . $product->nid,
-        )));
-      }
-      if (is_array($order->line_items)) {
-        foreach ($order->line_items as $line_item) {
-          if (_uc_line_item_data($line_item['type'], 'calculated') == TRUE) {
-            $payment->setLineItem(new PaymentLineItem(array(
-              'amount' => $line_item['amount'],
-              'description' => $line_item['title'],
-              'quantity' => 1,
-              'name' => 'payment_ubercart_line_item_' . $line_item['line_item_id'],
-            )));
-          }
-        }
-      }
-      $hook_order_total = 0;
-      foreach (module_implements('uc_order') as $module) {
-        $function = $module . '_uc_order';
-        // $order must be passed by reference.
-        if ($value = $function('total', $order, NULL) && is_numeric($value)) {
-          $hook_order_total += $value;
-        }
-      }
-      if ($hook_order_total) {
-        $payment->setLineItem(new PaymentLineItem(array(
-          'amount' => $hook_order_total,
-          'description' => 'Other',
-          'quantity' => 1,
-          'name' => 'payment_ubercart_hook_uc_order_total_' , $order->order_id,
-        )));
-      }
-    }
-    else {
-      $payment->setLineItem(new PaymentLineItem(array(
-        'amount' => $balance,
-        'description' => 'Order !order_id',
-        'description_arguments' => array(
-          '!order_id' => $order->order_id,
-        ),
-        'quantity' => 1,
-        'name' => 'payment_ubercart_order_balance_' , $order->order_id,
-      )));
-    }
+    $payment = payment_ubercart_payment_create($order);
 
     // Build the form.
-    $form = payment_form_embedded($form_state, $payment, array($pmid));
+    $form_state['payment'] = $payment;
+    $form = payment_form_embedded($form_state, $payment, array($payment->method->pmid));
     unset($form['elements']['payment_method']['#title']);
     unset($form['elements']['payment_line_items']);
     unset($form['elements']['payment_status']);
@@ -212,8 +144,8 @@ function payment_ubercart_callback($op, &$order, array $form = NULL, array &$for
   // Checkout form submission.
   elseif ($op == 'cart-process') {
     $payment = $form_state['payment'];
-    $order_id_save = (bool) $payment->pid;
     entity_save('payment', $payment);
+    $order_id_save = (bool) $payment->pid;
     if ($order_id_save) {
       payment_ubercart_order_id_save($payment);
     }
@@ -227,10 +159,11 @@ function payment_ubercart_callback($op, &$order, array $form = NULL, array &$for
  * @see payment_ubercart_uc_payment_redirect()
  */
 function payment_ubercart_form_redirect(array $form, array &$form_state, $uc_order) {
+  print_r($form_state);
   $form['payment_ubercart_submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit order'),
-    '#submit' => array('uc_cart_checkout_review_form_submit', 'payment_ubercart_form_redirect_submit'),
+    '#submit' => array('payment_ubercart_form_redirect_submit'),
   );
 
   return $form;
@@ -334,4 +267,85 @@ function payment_ubercart_form_configuration(array $form, array &$form_state) {
   );
 
   return system_settings_form($form);
-}
\ No newline at end of file
+}
+
+/**
+ * Creates a payment for an order.
+ *
+ * @param object $order
+ *
+ * @return Payment
+ */
+function payment_ubercart_payment_create($order) {
+  // Check for an existing payment;
+  $payment = isset($order->data['payment_pid']) ? entity_load_single('payment', $order->data['payment_pid']) : NULL;
+  $pid = $payment && payment_status_is_or_has_ancestor($payment->getStatus()->status, PAYMENT_STATUS_NEW) ? $payment->pid : 0;
+
+  $pmid = (int) str_replace('payment_ubercart_', '', $order->payment_method);
+  $payment = new Payment(array(
+    'context' => 'payment_ubercart',
+    'currency_code' => $order->currency,
+    'description' => t('Order #!order_id', array(
+      '!order_id' => $order->order_id,
+    )),
+    'finish_callback' => 'payment_ubercart_finish',
+    'method' => entity_load_single('payment_method', $pmid),
+    'payment_ubercart_uc_order_id' => $order->order_id,
+    'pid' => $pid,
+  ));
+
+  // Add orders, line items, and hook_uc_order() totals to the payment as line items.
+  $order->order_total = uc_order_get_total($order);
+  $balance = uc_payment_balance($order);
+  if ($order->order_total == $balance) {
+    foreach ($order->products as $product) {
+      $payment->setLineItem(new PaymentLineItem(array(
+        'amount' => $product->price,
+        'description' => $product->title,
+        'quantity' => $product->qty,
+        'name' => 'payment_ubercart_product_' . $product->nid,
+      )));
+    }
+    if (is_array($order->line_items)) {
+      foreach ($order->line_items as $line_item) {
+        if (_uc_line_item_data($line_item['type'], 'calculated') == TRUE) {
+          $payment->setLineItem(new PaymentLineItem(array(
+            'amount' => $line_item['amount'],
+            'description' => $line_item['title'],
+            'quantity' => 1,
+            'name' => 'payment_ubercart_line_item_' . $line_item['line_item_id'],
+          )));
+        }
+      }
+    }
+    $hook_order_total = 0;
+    foreach (module_implements('uc_order') as $module) {
+      $function = $module . '_uc_order';
+      // $order must be passed by reference.
+      if ($value = $function('total', $order, NULL) && is_numeric($value)) {
+        $hook_order_total += $value;
+      }
+    }
+    if ($hook_order_total) {
+      $payment->setLineItem(new PaymentLineItem(array(
+        'amount' => $hook_order_total,
+        'description' => 'Other',
+        'quantity' => 1,
+        'name' => 'payment_ubercart_hook_uc_order_total_' , $order->order_id,
+      )));
+    }
+  }
+  else {
+    $payment->setLineItem(new PaymentLineItem(array(
+      'amount' => $balance,
+      'description' => 'Order !order_id',
+      'description_arguments' => array(
+        '!order_id' => $order->order_id,
+      ),
+      'quantity' => 1,
+      'name' => 'payment_ubercart_order_balance_' , $order->order_id,
+    )));
+  }
+
+  return $payment;
+}
diff --git a/tests/PaymentUbercartCheckoutWebTestCase.test b/tests/PaymentUbercartCheckoutWebTestCase.test
new file mode 100644
index 0000000..09a50ac
--- /dev/null
+++ b/tests/PaymentUbercartCheckoutWebTestCase.test
@@ -0,0 +1,54 @@
+<?php
+
+class PaymentUbercartCheckoutWebTestCase extends PaymentWebTestCase {
+
+  static function getInfo() {
+    return array(
+      'name' => 'Checkout',
+      'group' => 'Payment for Ubercart',
+      'dependencies' => array('payment_ubercart'),
+    );
+  }
+
+  function setUp(array $modules = array()) {
+    parent::setUp($modules + array('paymentmethodbasic', 'payment_ubercart', 'uc_cart'));
+  }
+
+  function testCheckout() {
+    // Create payment method.
+    $payment_method = $this->paymentMethodCreate(0, payment_method_controller_load('PaymentMethodBasicController'));
+    entity_save('payment_method', $payment_method);
+
+    // Create a user.
+    $user = $this->drupalCreateUser(array('create product content', 'create orders'));
+    $this->drupalLogin($user);
+
+    // Set up the store.
+    $this->drupalPost('node/add/product', array(
+      'title' => 'foo',
+      'model' => 'bar',
+      'sell_price' => '12.34',
+    ), t('Save'));
+
+    // Perform the checkout.
+    $this->drupalPost(NULL, array(), t('Add to cart'));
+    $this->drupalPost(NULL, array(), t('Checkout'));
+    $values = array();
+    foreach (array('delivery', 'billing') as $type) {
+      $values['panes[' . $type . '][' . $type . '_first_name]'] = 'foo';
+      $values['panes[' . $type . '][' . $type . '_last_name]'] = 'foo';
+      $values['panes[' . $type . '][' . $type . '_street1]'] = 'foo';
+      $values['panes[' . $type . '][' . $type . '_city]'] = 'foo';
+      $values['panes[' . $type . '][' . $type . '_zone]'] = 1;
+      $values['panes[' . $type . '][' . $type . '_postal_code]'] = 'foo';
+    }
+    $this->drupalPost(NULL, $values, t('Review order'));
+    $this->drupalPost('cart/checkout/review', array(), t('Submit order'));
+    $pids = payment_ubercart_pids_load(1);
+    $payment = entity_load_single('payment', reset($pids));
+    $this->assertTrue((bool) $payment);
+    if ($payment) {
+      $this->assertEqual($payment->getStatus()->status, PAYMENT_STATUS_SUCCESS);
+    }
+  }
+}
\ No newline at end of file
