diff --git a/payment/uc_payment/uc_payment.module b/payment/uc_payment/uc_payment.module
index 8ac96b1..9ce6c91 100644
--- a/payment/uc_payment/uc_payment.module
+++ b/payment/uc_payment/uc_payment.module
@@ -509,12 +509,9 @@ function uc_payment_enter($order_id, $method, $amount, $uid = 0, $data = NULL, $
     ->execute();
 
   $order = uc_order_load($order_id, TRUE);
-  $account = user_load($uid);
 
   // Ensure user has an account before payment is made.
-  if (module_exists('uc_cart')) {
-    uc_cart_complete_sale($order);
-  }
+  $account = uc_cart_get_order_user($order);
 
   module_invoke_all('uc_payment_entered', $order, $method, $amount, $account, $data, $comment);
   rules_invoke_event('uc_payment_entered', $order, $account);
diff --git a/uc_cart/tests/uc_cart.test b/uc_cart/tests/uc_cart.test
index b1cf88a..319f8e3 100644
--- a/uc_cart/tests/uc_cart.test
+++ b/uc_cart/tests/uc_cart.test
@@ -437,6 +437,7 @@ class UbercartCartCheckoutTestCase extends UbercartTestHelper {
       'products' => array($item),
     ));
     uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);
+    uc_cart_complete_sale($order);
 
     // Find the order uid.
     $uid = db_query("SELECT uid FROM {uc_orders} ORDER BY order_id DESC")->fetchField();
@@ -457,6 +458,7 @@ class UbercartCartCheckoutTestCase extends UbercartTestHelper {
       'products' => array($item),
     ));
     uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);
+    uc_cart_complete_sale($order);
     $account = user_load($this->customer->uid);
     $this->assertTrue(isset($account->roles[$rid]), 'Existing user was granted role.');
     $order = uc_order_load($order->order_id);
diff --git a/uc_cart/uc_cart.module b/uc_cart/uc_cart.module
index 12ea799..49b7c42 100644
--- a/uc_cart/uc_cart.module
+++ b/uc_cart/uc_cart.module
@@ -859,12 +859,13 @@ function uc_cart_complete_sale($order, $login = FALSE) {
 
   // Ensure that user creation and triggers are only run once.
   if (empty($order->data['complete_sale'])) {
-    uc_cart_complete_sale_account($order);
+    $account = uc_cart_get_order_user($order);
+    $order->data['complete_sale'] = $order->data['checkout_sale'];
 
-    // Store account data.
+    // Remove temp data used during checkout.
+    unset($order->data['new_user']['password'], $order->data['checkout_sale']);
     db_update('uc_orders')
       ->fields(array(
-        'uid' => $order->uid,
         'data' => serialize($order->data),
       ))
       ->condition('order_id', $order->order_id)
@@ -879,8 +880,13 @@ function uc_cart_complete_sale($order, $login = FALSE) {
       }
     }
 
+    // Send the customer their account details if enabled.
+    if (variable_get('uc_new_customer_email', TRUE) && $order->data['complete_sale'] == 'new_user') {
+      $type = variable_get('uc_new_customer_status_active', TRUE) ? 'register_no_approval_required' : 'register_pending_approval';
+      drupal_mail('user', $type, $order->primary_email, uc_store_mail_recipient_language($order->primary_email), array('account' => $account), uc_store_email_from());
+    }
+  
     // Invoke the checkout complete trigger and hook.
-    $account = user_load($order->uid);
     module_invoke_all('uc_checkout_complete', $order, $account);
     rules_invoke_event('uc_checkout_complete', $order);
   }
@@ -920,64 +926,81 @@ function uc_cart_complete_sale($order, $login = FALSE) {
 }
 
 /**
- * Link a completed sale to a user.
+ * Returns the user account linked to an order, creating it if needed.
  *
- * @param $order
- *   The order object that has just been completed.
+ * @param object $order
+ *  An order object.
+ *
+ * @return object $account
+ *  The loaded or new account.
  */
-function uc_cart_complete_sale_account($order) {
+function uc_cart_get_order_user($order) {
+  $account = FALSE;
+
   // Order already has a user ID, so the user was logged in during checkout.
-  if ($order->uid) {
-    $order->data['complete_sale'] = 'logged_in';
-    return;
-  }
+  if ($order->uid && $account = user_load($order->uid)) {
+    $checkout_sale = 'logged_in';
+  };
 
-  $result = db_query("SELECT uid FROM {users} WHERE mail LIKE :email", array(':email' => $order->primary_email));
+  // Do nothing if the order has already gone through checkout.
+  if (!empty($order->data['complete_sale'])) {
+    return $account;
+  };
 
-  // Email address matches an existing account.
-  if ($account = $result->fetchObject()) {
-    $order->uid = $account->uid;
-    $order->data['complete_sale'] = 'existing_user';
-    return;
-  }
+  // Check if email address matches an existing account.
+  $result = db_query("SELECT uid FROM {users} WHERE mail LIKE :email", array(':email' => $order->primary_email));
+  if (!$account && $uid = $result->fetchField()) {
+    $account = user_load($uid);
+    $order->uid = $uid;
+    $checkout_sale = 'existing_user';
+  };
+
+  // No user exists, so set up a new user.
+  if (!$account) {
+    $fields = array(
+      'name' => uc_store_email_to_username($order->primary_email),
+      'mail' => $order->primary_email,
+      'init' => $order->primary_email,
+      'pass' => user_password(),
+      'roles' => array(),
+      'status' => variable_get('uc_new_customer_status_active', TRUE) ? 1 : 0,
+    );
 
-  // Set up a new user.
-  $fields = array(
-    'name' => uc_store_email_to_username($order->primary_email),
-    'mail' => $order->primary_email,
-    'init' => $order->primary_email,
-    'pass' => user_password(),
-    'roles' => array(),
-    'status' => variable_get('uc_new_customer_status_active', TRUE) ? 1 : 0,
-  );
+    // Override the username, if specified.
+    if (isset($order->data['new_user']['name'])) {
+      $fields['name'] = $order->data['new_user']['name'];
+    }
 
-  // Override the username, if specified.
-  if (isset($order->data['new_user']['name'])) {
-    $fields['name'] = $order->data['new_user']['name'];
-  }
+    // Create the account.
+    $account = user_save('', $fields);
 
-  // Create the account.
-  $account = user_save('', $fields);
+    // Override the password, if specified.
+    if (isset($order->data['new_user']['hash'])) {
+      db_query("UPDATE {users} SET pass = :hash WHERE uid = :uid", array(':hash' => $order->data['new_user']['hash'], ':uid' => $account->uid));
+      $order->data['new_user']['password'] = $order->password = $account->password = t('Your password');
+    }
+    else {
+      $order->data['new_user']['password'] = $order->password = $account->password = $fields['pass'];
+    }
 
-  // Override the password, if specified.
-  if (isset($order->data['new_user']['hash'])) {
-    db_query("UPDATE {users} SET pass = :hash WHERE uid = :uid", array(':hash' => $order->data['new_user']['hash'], ':uid' => $account->uid));
-    $account->password = t('Your password');
-  }
-  else {
-    $account->password = $fields['pass'];
-    $order->password = $fields['pass'];
+    $order->uid = $account->uid;
+    $order->data['new_user']['name'] = $fields['name'];
+    $checkout_sale = 'new_user';
   }
 
-  // Send the customer their account details if enabled.
-  if (variable_get('uc_new_customer_email', TRUE)) {
-    $type = variable_get('uc_new_customer_status_active', TRUE) ? 'register_no_approval_required' : 'register_pending_approval';
-    drupal_mail('user', $type, $order->primary_email, uc_store_mail_recipient_language($order->primary_email), array('account' => $account), uc_store_email_from());
-  }
+  // Only set this once as this function can be called many times.
+  if (empty($order->data['checkout_sale'])) {
+    $order->data['checkout_sale'] = $checkout_sale;
+  };
+
+  if (!empty($order->data['new_user']['password'])) {
+    $order->password = $account->password = $order->data['new_user']['password'];
+  };
+  
+  // Store temp checkout data.
+  db_query("UPDATE {uc_orders} SET uid = :uid, data = :order_data WHERE order_id = :order_id", array(':uid' => $order->uid, ':order_data' => serialize($order->data), ':order_id' => $order->order_id));
 
-  $order->uid = $account->uid;
-  $order->data['new_user']['name'] = $fields['name'];
-  $order->data['complete_sale'] =  'new_user';
+  return $account;
 }
 
 /**
