diff -up uc_paypal_old/uc_paypal.install uc_paypal_new/uc_paypal.install
--- uc_paypal_old/uc_paypal.install	2009-08-17 15:27:56.000000000 -0600
+++ uc_paypal_new/uc_paypal.install	2010-04-10 00:09:32.000000000 -0600
@@ -4,7 +4,8 @@
 /**
  * @file
  * Installation file for PayPal, primarily for the logging of IPNs.
-
+ */
+ 
 /**
  * Implementation of hook_requirements().
  */
@@ -110,6 +111,7 @@ function uc_paypal_install() {
 
   $t = get_t();
   db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('paypal_pending', '%s', 'payment_received', 7, 1);", $t('PayPal pending'));
+  db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('paypal_received', '%s', 'paypal_received', 7, 1);", $t('PayPal paid but not complete'));
 }
 
 /**
@@ -118,6 +120,7 @@ function uc_paypal_install() {
 function uc_paypal_uninstall() {
   drupal_uninstall_schema('uc_paypal');
   db_query("DELETE FROM {variable} WHERE name LIKE 'uc_paypal_%%'");
+  db_query("DELETE FROM {uc_order_statuses} WHERE order_status_id LIKE 'paypal_%%'");
 }
 
 function uc_paypal_update_1() {
diff -up uc_paypal_old/uc_paypal.module uc_paypal_new/uc_paypal.module
--- uc_paypal_old/uc_paypal.module	2009-11-18 14:08:06.000000000 -0700
+++ uc_paypal_new/uc_paypal.module	2010-04-10 00:32:59.000000000 -0600
@@ -73,6 +73,13 @@ function uc_paypal_menu() {
     'type' => MENU_CALLBACK,
     'file' => 'uc_paypal.pages.inc',
   );
+  $items['uc_paypal/wps/manual_complete/%'] = array(
+    'title' => 'PayPal manual complete',
+    'page callback' => 'uc_paypal_not_complete_pane',
+    'page arguments' => array(2,3),
+    'access arguments' => array('edit orders'),
+    'type' => MENU_CALLBACK,
+  );
 
   return $items;
 }
@@ -83,6 +90,60 @@ function uc_paypal_ipn_access() {
 }
 
 /**
+ * Implementation of hook_order_state().
+ */
+
+function uc_paypal_order_state() {
+  $states[] = array(
+    'id' => 'paypal_received',
+    'title' => t('PayPal received but not complete.'),
+    'weight' => 10,
+    'scope' => 'general',
+  );
+  
+  return $states;
+}
+
+/**
+ * Implementation of hook_order_pane().
+ */
+
+function uc_paypal_order_pane() {
+  $panes[] = array(
+    'id' => 'PayPal Recieved but NOT Complete',
+    'callback' => 'uc_paypal_not_complete_pane',
+    'title' => t('Not complete!'),
+    'desc' => t('PayPal Payment recieved but order not complete.  This can happen if the user does not return to the checkout complete page after their PayPal transaction is successful.  This pane provides a notice and link to complete the transaction.'),
+    'class' => 'abs-left',
+    'weight' => 7,
+    'show' => array('view', 'edit', 'admin'),
+  );
+  return $panes;
+}
+
+function uc_paypal_not_complete_pane($op, $arg1) {
+  switch ($op) {
+    case 'view':
+      if (uc_order_status_data($arg1->order_status, 'state') == 'paypal_received') {
+        $output = "<p>Occasionally, users will close their browsers after their PayPal transaction is complete, without returning to the 'checkout complete' page on this site.  If this happens your site will not mark the order as complete or send out order notifications/receipts.  The payment should still be logged with an IPN message in the comments.  If so, and the balance on this order is $0, you can <a href='/uc_paypal/wps/manual_complete/" . $arg1->order_id . "'>Click here to complete the order manually</a>.</p>";
+      }
+      return $output;
+    case 'manual_complete':
+      //trigger complete sale stuff here
+      $order = uc_order_load($arg1);
+      if (uc_order_status_data($order->order_status, 'state') == 'paypal_received') {
+        if (uc_cart_complete_sale($order)){
+          uc_order_update_status($order->order_id, uc_order_state_default('payment_received'));
+          global $user;
+          uc_order_comment_save($order->order_id, 0, t('The order was manually completed by @user uid: @uid.', array('@user' => $user->name, '@uid' => $user->uid)));          
+          drupal_set_message("Order $arg1 has been manually completed.");
+        }        
+      }
+      drupal_goto("admin/store/orders/$arg1");
+  }
+}
+
+/**
  * Implementation of hook_perm().
  */
 function uc_paypal_perm() {
diff -up uc_paypal_old/uc_paypal.pages.inc uc_paypal_new/uc_paypal.pages.inc
--- uc_paypal_old/uc_paypal.pages.inc	2009-11-18 14:08:06.000000000 -0700
+++ uc_paypal_new/uc_paypal.pages.inc	2010-04-10 00:23:47.000000000 -0600
@@ -94,7 +94,10 @@ function uc_paypal_ipn($order_id = 0) {
       case 'Completed':
         $comment = t('PayPal transaction ID: @txn_id', array('@txn_id' => $txn_id));
         uc_payment_enter($order_id, 'paypal_wps', $payment_amount, $order->uid, NULL, $comment);
-        uc_cart_complete_sale($order);
+        //uc_cart_complete_sale($order);
+        if (uc_order_status_data($order->order_status, 'state') != 'payment_received') {
+            uc_order_update_status($order->order_id, uc_order_state_default('paypal_received'));
+        }
         uc_order_comment_save($order_id, 0, t('Payment of @amount @currency submitted through PayPal.', array('@amount' => uc_price($payment_amount, $context, $options), '@currency' => $payment_currency)), 'order', 'payment_received');
         uc_order_comment_save($order_id, 0, t('PayPal IPN reported a payment of @amount @currency.', array('@amount' => uc_price($payment_amount, $context, $options), '@currency' => $payment_currency)));
         break;
