diff --git a/includes/uc_payflowpro_recurring.inc b/includes/uc_payflowpro_recurring.inc
index f008963..a1bcdca 100644
--- a/includes/uc_payflowpro_recurring.inc
+++ b/includes/uc_payflowpro_recurring.inc
@@ -1007,16 +1007,6 @@ function theme_payflow_address($title = 'Address', $address) {
 
   return drupal_render($render);
 }
-function _payment_payflowpro_auth_info() {
-  static $auth;
-  if(!isset($auth)) {
-    $auth['vendor'] = variable_get('ec_payflowpro_vendor', '');
-    $auth['partner'] = variable_get('ec_payflowpro_partner', '');
-    $auth['user'] = variable_get('ec_payflowpro_user', '');
-    $auth['password'] = variable_get('ec_payflowpro_password', '');
-  }
-  return $auth;
-}
 
 function uc_payflowpro_cancel_form($form_state, $profile_id, $cancel_path) {
   $form = array();
diff --git a/uc_payflowpro.install b/uc_payflowpro.install
index fed6a4b..e173593 100644
--- a/uc_payflowpro.install
+++ b/uc_payflowpro.install
@@ -174,22 +174,9 @@ function uc_payflowpro_update_1() {
  */
 function uc_payflowpro_uninstall() {
   drupal_uninstall_schema('uc_payflowpro');
-  
-  //This block is referenced but never set.
-  /*variable_del('ec_payflowpro_partner');
-  variable_del('ec_payflowpro_password');
-  variable_del('ec_payflowpro_sdk_cert_path');
-  variable_del('ec_payflowpro_tx_mode');
-  variable_del('ec_payflowpro_user');
-  variable_del('ec_payflowpro_vendor');*/
 
   //These variables are actually set by the settings form.
   variable_del('uc_payflowpro_cert_path');
-  variable_del('uc_payflowpro_ec_reqconfirmed_addr');
-  variable_del('uc_payflowpro_ec_review_comment');
-  variable_del('uc_payflowpro_ec_review_company');
-  variable_del('uc_payflowpro_ec_review_phone');
-  variable_del('uc_payflowpro_ec_review_shipping');
   variable_del('uc_payflowpro_enable_recurring');
   variable_del('uc_payflowpro_error_codes_accept');
   variable_del('uc_payflowpro_mode');
@@ -199,5 +186,4 @@ function uc_payflowpro_uninstall() {
   variable_del('uc_payflowpro_recurring_site_key');
   variable_del('uc_payflowpro_user');
   variable_del('uc_payflowpro_vendor');
-  variable_del('uc_payment_method_payflowpro_ec_checkout');
 }
diff --git a/uc_payflowpro.module b/uc_payflowpro.module
index b96d034..3fed181 100644
--- a/uc_payflowpro.module
+++ b/uc_payflowpro.module
@@ -26,39 +26,6 @@ require_once('includes/uc_payflowpro_recurring.inc');
  * Implementation of hook_menu()
  */
 function uc_payflowpro_menu() {
-
-  // Callback functions for Express Checkout
-  $items['cart/echeckout/selected'] = array(
-    'title' => 'Review order',
-    'page callback' => 'uc_payflowpro_ec_review_redirect',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['cart/echeckout/review'] = array(
-    'title' => 'Review payment',
-    'page callback' => 'uc_payflowpro_ec_review',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['cart/echeckout/submit'] = array(
-    'title' => 'Submit order',
-    'page callback' => 'uc_payflowpro_ec_submit',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['cart/echeckout/complete'] = array(
-    'title' => 'Order complete',
-    'page callback' => 'uc_payflowpro_ec_complete',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['cart/echeckout/cancel'] = array(
-    'title' => 'PayPal payment cancelled',
-    'page callback' => 'uc_payflowpro_ec_cancel',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
-
   // Recurring Billing administration
   $items['admin/store/settings/uc_recurring'] = array(
     'title' => 'Payflow Pro Recurring Settings',
@@ -127,64 +94,11 @@ function uc_payflowpro_theme($existing, $type, $theme, $path) {
   );
 }
 
-/**
- * Implementation of hook_form_alter()
- * To allow express checkout
- */
-function uc_payflowpro_form_alter(&$form, $form_state, $form_id) {
-  if ($form_id == 'uc_cart_checkout_form' && variable_get('uc_payment_method_payflowpro_ec_checkout', FALSE)) {
-    $form['#submit'] = (array)$form['#submit'] + array('uc_payflowpro_ec_checkout' => array());
-  }
-
-  if ($form_id == 'uc_cart_checkout_review_form' && !empty($_SESSION['TOKEN'])) {
-    $form['#submit'] = (array)$form['#submit'] + array('uc_payflowpro_ec_submit_form_submit' => array());
-  }
-
-}
-
 /*******************************************************************************
  * Hook Functions (Ubercart)
  ******************************************************************************/
 
 /**
- * Implementation of hook_cart_pane()
- */
-function uc_payflowpro_cart_pane() {
-
-  $panes[] = array(
-    'id' => 'uc_payflowpro_ec',
-    'title' => t('PayPal Express Checkout'),
-    'enabled' => FALSE,
-    'weight' => 1,
-    'body' => '<div align="right">'. drupal_get_form('uc_payflowpro_ec_form') .'</div>',
-  );
-
-  return $panes;
-}
-
-/**
-* Implementation of hook_payment_method().
- */
-function uc_payflowpro_payment_method() {
-  $title1 = '<img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" style="position: relative; top: 5px; margin-right: 4px;">'
-            . t('PayPal - pay without sharing your financial information.');
-
-  $methods[] = array(
-    'id' => 'payflowpro_ec',
-    'name' => t('PayPal Express Checkout'),
-    'title' => $title1,
-    'review' => t('PayPal'),
-    'desc' => t('Complete orders through PayPal Express Checkout.'),
-    'callback' => 'uc_payment_method_payflowpro_ec',
-    'weight' => 1,
-    'checkout' => FALSE,
-    'backend' => FALSE,
-  );
-
-  return $methods;
-}
-
-/**
  * Implementation of hook_payment_gateway()
  */
 function uc_payflowpro_payment_gateway() {
@@ -395,40 +309,6 @@ function uc_payflowpro_settings_form() {
     '#description' => t('PayFlow password.  WARNING: Until a core bug #486544 is fixed, you will need to re-enter your password if you change any settings.'),
   );
 
-
-  $form['payflowpro_settings']['ec'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Express Checkout'),
-    '#description' => t('These settings are specifically for the alternate checkout system offered by Express Checkout.<br>To enable this on your site, you must enable the corresponding cart pane in the <em>Cart settings</em> menu.'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['payflowpro_settings']['ec']['uc_payflowpro_ec_reqconfirmed_addr'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Require Express Checkout users to use a PayPal confirmed shipping address.'),
-    '#default_value' => variable_get('uc_payflowpro_ec_reqconfirmed_addr', FALSE),
-  );
-  $form['payflowpro_settings']['ec']['uc_payflowpro_ec_review_shipping'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable the shipping select form on the Review payment page.'),
-    '#default_value' => variable_get('uc_payflowpro_ec_review_shipping', TRUE),
-  );
-  $form['payflowpro_settings']['ec']['uc_paypflowpro_ec_review_company'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable the company name box on the Review payment page.'),
-    '#default_value' => variable_get('uc_payflowpro_ec_review_company', TRUE),
-  );
-  $form['payflowpro_settings']['ec']['uc_payflowpro_ec_review_phone'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable the contact phone number box on the Review payment page.'),
-    '#default_value' => variable_get('uc_payflowpro_ec_review_phone', TRUE),
-  );
-  $form['payflowpro_settings']['ec']['uc_payflowpro_ec_review_comment'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable the comment text box on the Review payment page.'),
-    '#default_value' => variable_get('uc_payflowpro_ec_review_comment', TRUE),
-  );
-
   return $form;
 }
 
@@ -455,427 +335,6 @@ function uc_payflow_pro_pfp_gateway_validate($element, &$form_state) {
 }
 
 /*******************************************************************************
- * Express Checkout Functions
- ******************************************************************************/
-
-// Handles the Express Checkout payment method
-function uc_payment_method_payflowpro_ec($op, &$arg1) {
-  switch ($op) {
-    //case 'order-view':
-    case 'settings':
-      $form['redirect'] = array(
-        '#value' => '<div>'. t('For Express Checkout, you need to !cp_link and !wpp_link.', array('!cp_link' => l(t('enable the cart pane'), 'admin/store/settings/cart/edit/panes'), '!wpp_link' => l(t('configure the PayFlow Pro settings'), 'admin/store/settings/payment/edit/gateways'))) .'</div>',
-      );
-      return $form;
-  }
-}
-
-// Handles the review page for Express Checkout Mark Flow.
-function uc_payflowpro_ec_review_redirect() {
-  if (!isset($_SESSION['TOKEN']) || ($order = uc_order_load($_SESSION['cart_order'])) == FALSE) {
-    unset($_SESSION['cart_order']);
-    unset($_SESSION['have_details']);
-    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
-    drupal_set_message(t('An error has occurred in your PayPal payment. Please review your cart and try again.'));
-    drupal_goto('cart');
-  }
-
-  $request = _uc_payflowpro_get_ec_xml($_SESSION['TOKEN']);
-  $response = _uc_payflowpro_submit_xml($request);
-
-  $_SESSION['PAYERID'] = $response->PayPalResult->PayerID;
-
-  drupal_goto('cart/checkout/review');
-}
-
-// Handles the review page for Express Checkout Shortcut Flow.
-function uc_payflowpro_ec_review() {
-  if (!isset($_SESSION['TOKEN']) || ($order = uc_order_load($_SESSION['cart_order'])) == FALSE) {
-    unset($_SESSION['cart_order']);
-    unset($_SESSION['have_details']);
-    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
-    drupal_set_message(t('An error has occurred in your PayPal payment. Please review your cart and try again.'));
-    drupal_goto('cart');
-  }
-
-  if ($_SESSION['have_details'][$order->order_id] !== TRUE) {
-    $request = _uc_payflowpro_get_ec_xml($_SESSION['TOKEN']);
-    $response = _uc_payflowpro_submit_xml($request);
-
-    $_SESSION['PAYERID'] = $response->PayPalResult->PayerID;
-
-    // get variables to populate form
-    $billto_name = check_plain(trim($response->PayPalResult->Name));
-    $name_split = strrpos($billto_name, ' ');
-    if ($name_split > 0) {
-      $billto_firstname = substr($billto_name, 0, $name_split);
-      $billto_lastname = substr($billto_name, $name_split);
-    }
-    else {
-      $billto_firstname = $billto_name;
-      $billto_lastname = '';
-    }
-
-    if (empty($response->PayPalResult->ShipTo->Name)) {
-      $shipto_firstname = $billto_firstname;
-      $shipto_lastname = $billto_lastname;
-    }
-    else {
-      $shipto_name = check_plain(trim($response->PayPalResult->Name));
-      $name_split = strrpos($shipto_name, ' ');
-      if ($name_split > 0) {
-        $shipto_firstname = substr($shipto_name, 0, $name_split);
-        $shipto_lastname = substr($shipto_name, $name_split);
-      }
-      else {
-        $shipto_firstname = $shipto_name;
-        $shipto_lastname = '';
-      }
-    }
-
-    $zone_id = db_result(db_query("SELECT zone_id FROM {uc_zones} WHERE zone_code = '%s'", check_plain($response->PayPalResult->ShipTo->Address->State)));
-    $country_id = db_result(db_query("SELECT country_id FROM {uc_countries} WHERE country_iso_code_2 = '%s'", check_plain($response->PayPalResult->ShipTo->Address->Country)));
-
-    $order->delivery_first_name = $shipto_firstname;
-    $order->delivery_last_name = $shipto_lastname;
-    $order->delivery_street1 = check_plain($response->PayPalResult->ShipTo->Street);
-    $order->delivery_city = check_plain($response->PayPalResult->ShipTo->City);
-    $order->delivery_zone = !empty($zone_id) ? $zone_id : 0;
-    $order->delivery_postal_code = check_plain($response->PayPalResult->ShipTo->Zip);
-    $order->delivery_country = !empty($country_id) ? $country_id : 840;
-
-    $order->billing_first_name = $billto_firstname;
-    $order->billing_last_name = $billto_lastname;
-    $order->billing_street1 = $response->PayPalResult->EMail;
-
-    if (empty($order->primary_email)) {
-      $order->primary_email = $response->PayPalResult->EMail;
-    }
-    $order->payment_method = 'payflowpro_ec';
-
-    uc_order_save($order);
-
-    $_SESSION['have_details'][$order->order_id] = TRUE;
-  }
-
-  $output = t("Your order is almost complete!  Please fill in the following details and click 'Continue checkout' to finalize the purchase.");
-
-  $output .= drupal_get_form('uc_payflowpro_ec_review_form', $order);
-
-  return $output;
-}
-
-// Present the final total to the user for checkout!
-function uc_payflowpro_ec_submit() {
-  if (!isset($_SESSION['TOKEN']) || ($order = uc_order_load($_SESSION['cart_order'])) == FALSE) {
-    unset($_SESSION['cart_order'], $_SESSION['have_details']);
-    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
-    drupal_set_message(t('An error has occurred in your PayPal payment. Please review your cart and try again.'));
-    drupal_goto('cart');
-  }
-
-  // [ML] FIXME: this doesn't seem normal to be here..
-  $output = '<div style="border: solid 1px #bbb;">'. _cart_review_table(FALSE) .'</div>';
-  $output .= uc_order_pane_line_items('customer', $order);
-  $output .= '<p>'. t("Your order is not complete until you click the 'Submit order' button below. Your PayPal account will be charged for the amount shown above once your order is placed. You will receive confirmation once your payment is complete.") .'</p>';
-  $output .= drupal_get_form('uc_payflowpro_ec_submit_form');
-
-  return $output;
-}
-
-// Redirects if a customer selects PayPal Express Checkout as a payment method.
-function uc_payflowpro_ec_checkout($form_id, $form_values) {
-  if ($form_values['panes']['payment']['pane']['payment_method'] != 'payflowpro_ec') {
-    return;
-  }
-
-  if (!_uc_payflowpro_check_requirements()) {
-    return array('success' => FALSE);
-  }
-
-  global $user;
-
-  $order_id = intval($_SESSION['cart_order']);
-
-  $order = uc_order_load($order_id);
-  if ($order === FALSE || $order->order_status != uc_get_order_status_id('in_checkout')) {
-    $_SESSION['cart_order'] = NULL;
-    unset($_SESSION['cart_order']);
-    drupal_goto('cart');
-  }
-
-  $request = _uc_payflowpro_set_ec_xml($order);
-  $response = _uc_payflowpro_submit_xml($request);
-
-  if (!$response) {
-    drupal_set_message(t('Received blank message from PayPal.  Please try again later'));
-    drupal_goto('cart/checkout');
-  }
-
-  $txn_result_code = $response->Result;
-  $txn_message = $response->Message;
-
-  if ((int)$txn_result_code != 0) {
-    drupal_set_message(t('Error message from PayPal:<br>!message', array('!message' => $txn_message)), 'error');
-    drupal_goto('cart/checkout');
-  }
-
-  $_SESSION['TOKEN'] = $response->PayPalResult->Token;
-
-  header('Location: '. _uc_payflowpro_ec_url());
-  exit();
-}
-
-function uc_payflowpro_ec_complete($order_id = 0) {
-  if (intval($order_id) < 1) {
-    drupal_goto('cart');
-  }
-
-  if (intval($_SESSION['cart_order']) != $order_id) {
-    $_SESSION['cart_order'] = $order_id;
-  }
-
-  $order = uc_order_load($order_id);
-
-  if ($order === FALSE || $oder->order_status != uc_get_order_status_id('in_checkout')) {
-    drupal_goto('cart');
-  }
-
-  // This lets us know it's a legitimate access of the complete page.
-  $_SESSION['do_complete'] = TRUE;
-
-  drupal_goto('cart/checkout/complete');
-}
-
-function uc_payflowpro_ec_cancel() {
-  unset($_SESSION['cart_order']);
-
-  drupal_set_message(t('Your PayPal.com payment was cancelled. Please feel free to continue shopping or contact us for assistance.'));
-
-  drupal_goto('cart');
-}
-
-function _uc_payflowpro_ec_url() {
-  if (variable_get('uc_payflowpro_mode', 'test') == 'test') {
-    $url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='. $_SESSION['TOKEN'];
-  }
-  else {
-    $url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='. $_SESSION['TOKEN'];
-  }
-
-  return $url;
-  header('Location: '. $url);
-}
-
-/*******************************************************************************
- * Express Checkout Forms
- ******************************************************************************/
-
-// Returns the form for Express Checkout Shortcut Flow.
-function uc_payflowpro_ec_form() {
-  if (!_uc_payflowpro_check_requirements()) {
-    return array('success' => FALSE);
-  }
-
-  // Hack to allow the image button to submit.
-  if (isset($_POST['submit_x'])) {
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => 'submit',
-    );
-  }
-
-  $form['submit_image'] = array(
-    '#value' => '<input name="submit" type="image" title="'. t('Checkout with PayPal.') .'" src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckoutsm.gif" style="position: relative; top: -1.25em;">',
-  );
-
-  return $form;
-}
-
-// Returns the form for the custom Review Payment screen for Express Checkout.
-function uc_payflowpro_ec_review_form($order) {
-  if (module_exists('uc_quote') && variable_get('uc_payflowpro_ec_review_shipping', TRUE)) {
-    // Remove once line items are out of checkout. -RS
-    uc_add_base_path_js();
-    drupal_add_js(drupal_get_path('module', 'uc_payment') .'/uc_payment.js');
-
-    $result = uc_checkout_pane_quotes('view', $order, NULL);
-    $form['panes'] = array('#tree' => TRUE);
-    $form['panes']['quotes'] = $result->fields;
-    $form['panes']['quotes']['pane']['#collapsible'] = FALSE;
-    $form['panes']['quotes']['pane']['#title'] = t('Calculate shipping');
-
-    // Fake the checkout form delivery information.
-    $form['delivery_first_name'] = array('#type' => 'hidden', '#value' => $order->delivery_first_name);
-    $form['delivery_last_name'] = array('#type' => 'hidden', '#value' => $order->delivery_last_name);
-    $form['delivery_company'] = array('#type' => 'hidden', '#value' => $order->delivery_company);
-    $form['delivery_street1'] = array('#type' => 'hidden', '#value' => $order->delivery_street1);
-    $form['delivery_street2'] = array('#type' => 'hidden', '#value' => $order->delivery_street2);
-    $form['delivery_city'] = array('#type' => 'hidden', '#value' => $order->delivery_city);
-    $form['delivery_postal_code'] = array('#type' => 'hidden', '#value' => $order->delivery_postal_code);
-    $form['delivery_phone'] = array('#type' => 'hidden', '#value' => $order->delivery_phone);
-    $form['delivery_zone'] = array(
-      '#type' => 'select',
-      '#options' => drupal_map_assoc(array($order->delivery_zone)),
-      '#default_value' => $order->delivery_zone,
-      '#attributes' => array('style' => 'display: none;'),
-    );
-    $form['delivery_country'] = array(
-      '#type' => 'select',
-      '#options' => drupal_map_assoc(array($order->delivery_country)),
-      '#default_value' => $order->delivery_country,
-      '#attributes' => array('style' => 'display: none;'),
-    );
-  }
-
-  if (variable_get('uc_payflowpro_ec_review_company', TRUE)) {
-    $form['delivery_company'] = array(
-      '#type' => 'textfield',
-      '#title' => uc_get_field_name('company'),
-      '#description' => t('Leave blank if shipping to a residence.'),
-      '#default_value' => $order->delivery_company,
-    );
-  }
-
-  if (variable_get('uc_payflowpro_ec_review_phone', TRUE)) {
-    $form['delivery_phone'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Contact phone number'),
-      '#default_value' => $order->delivery_phone,
-      '#size' => 24,
-    );
-  }
-
-  if (variable_get('uc_payflowpro_ec_review_comment', TRUE)) {
-    $form['order_comments'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Order comments'),
-      '#description' => t('Special instructions or notes regarding your order.'),
-    );
-  }
-
-  if (empty($form)) {
-    drupal_goto('cart/echeckout/submit');
-  }
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Continue checkout'),
-  );
-
-  return $form;
-}
-
-// Submits an order, calling the NVP API to send the order total to PayPal.
-function uc_payflowpro_ec_submit_form() {
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Submit order'),
-  );
-
-  return $form;
-}
-
-/*******************************************************************************
- * Express Checkout Form Submissions
- ******************************************************************************/
-
-function uc_payflowpro_ec_form_submit($form, &$form_state) {
-  global $user;
-  $items = uc_cart_get_contents();
-
-  if (!is_array($items) || count($items) == 0) {
-    drupal_set_message(t('You do not have any items in your shopping cart.'));
-    return;
-  }
-
-  $order = uc_order_new($user->uid);
-  $order->products = $items;
-
-  $request = _uc_payflowpro_set_ec_xml($order);
-  $response = _uc_payflowpro_submit_xml($request);
-
-  if (!$response) {
-    drupal_set_message(t('Received blank message from PayPal.  Please try again later'));
-    drupal_goto('cart/checkout');
-  }
-
-  $txn_result_code = $response->Result;
-  $txn_message = $response->Message;
-
-  if ((int)$txn_result_code != 0) {
-    drupal_set_message(t('Error message from PayPal:<br>!message', array('!message' => $txn_message)), 'error');
-    drupal_goto('cart/checkout');
-  }
-
-  uc_order_save($order);
-
-  $_SESSION['cart_order'] = $order->order_id;
-  $_SESSION['token'] = $response->PayPalResult->Token;
-
-  $form_state['redirect'] = _uc_payflowpro_ec_url();
-}
-
-function uc_payflowpro_ec_review_form_validate($form, &$form_state) {
-  if (module_exists('uc_quote') && variable_get('uc_payflowpro_ec_review_shipping', TRUE)) {
-    if (empty($form_state['values']['panes']['quotes']['pane']['quote_method']) || !isset($_POST['quote-option'])) {
-      drupal_set_message(t('You must specify a shipping option.'), 'error');
-      return FALSE;
-    }
-  }
-}
-
-function uc_payflowpro_ec_review_form_submit($form, &$form_state) {
-  $order = uc_order_load($_SESSION['cart_order']);
-
-  if (module_exists('uc_quote') && variable_get('uc_payflowpro_ec_review_shipping', TRUE)) {
-    $order->quote['method'] = $form_state['values']['panes']['quotes']['pane']['quote_method'];
-    $order->quote['accessorials'] = isset($_POST['quote-option']) ? strval($_POST['quote-option']) : 0;
-    $order->quote['rate'] = $_POST['rate'][$order->quote['accessorials']];
-    $order->quote['quote_form'] = rawurldecode($_POST['quote-form']);
-    $methods = module_invoke_all('shipping_method');
-    $method = $methods[$order->quote['method']];
-    $label = is_null($_POST['quote-option']) ? t('Error calculating shipping') : $method['quote']['accessorials'][$order->quote['accessorials']];                   $result = db_query("SELECT line_item_id FROM {uc_order_line_items} WHERE order_id = %d AND type = 'shipping'", $order->order_id);                               if ($lid = db_result($result)) {
-      uc_order_update_line_item($lid, $label, $order->quote['rate']);
-    }
-    else {
-      uc_order_line_item_add($order->order_id, 'shipping', $label, $order->quote['rate']);
-    }
-  }
-
-  if (variable_get('uc_payflowpro_ec_review_company', TRUE)) {
-    $order->delivery_company = $form_state['values']['delivery_company'];
-  }
-
-  if (variable_get('uc_payflowpro_ec_review_phone', TRUE)) {
-    $order->delivery_phone = $form_state['values']['delivery_phone'];
-  }
-
-  if (variable_get('uc_payflowpro_ec_review_comment', TRUE)) {
-    db_query("DELETE FROM {uc_order_comments} WHERE order_id = %d", $order->order_id);
-    uc_order_comment_save($order->order_id, 0, $form_state['values']['order_comments'], 'order');
-  }
-
-  uc_order_save($order);
-
-  // drupal_goto('cart/echeckout/submit');
-  $form_state['redirect'] = 'cart/echeckout/submit';
-}
-
-function uc_payflowpro_ec_submit_form_submit($form, &$form_state) {
-  $order = uc_order_load($_SESSION['cart_order']);
-
-  $request = _uc_payflowpro_do_ec_xml($order);
-  $response = _uc_payflowpro_submit_xml($request);
-
-  unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
-  $_SESSION['do_complete'] = TRUE;
-
-  // drupal_goto('cart/checkout/complete');
-  $form_state['redirect'] = 'cart/checkout/complete';
-}
-
-/*******************************************************************************
  * XML Helper Functions
  ******************************************************************************/
 
@@ -1146,73 +605,6 @@ function _uc_payflowpro_cc_info_xml($order_id) {
   return $xml;
 }
 
-// Generate XML for SetExpressCheckout
-function _uc_payflowpro_set_ec_xml($order) {
-  // Get payment action (Sale or Authorization)
-  $payment_action = variable_get('uc_payflowpro_payment_action', '');
-
-  $xml = '         <SetExpressCheckout>
-          <' . $payment_action . '>
-            <PayData>
-' . _uc_payflowpro_invoice_xml($order) . '
-              <Tender>
-                <PayPal>
-                  <EMail>' . check_plain($order->primary_email) . '</EMail>
-                  <ReturnURL>' . url('cart/echeckout/selected', array('absolute' => TRUE)) . '</ReturnURL>
-                  <CancelURL>' . url('uc_payflowpro/ec/cancel', array('absolute' => TRUE)) . '</CancelURL>
-                  <ReqConfirmShipping>' . check_plain(variable_get('uc_payflowpro_ec_reqconfirmed_addr', '')) . '</ReqConfirmShipping>
-                </PayPal>
-              </Tender>
-            </PayData>
-          </' . $payment_action . '>
-        </SetExpressCheckout>';
-
-  return _uc_payflowpro_wrap_xml($xml);
-}
-
-// Generate XML for GetExpressCheckout
-function _uc_payflowpro_get_ec_xml($token) {
-  // Get payment action (Sale or Authorization)
-  $payment_action = variable_get('uc_payflowpro_payment_action', '');
-
-  $xml = '         <GetExpressCheckout>
-          <' . $payment_action . '>
-            <PayData>
-              <Tender>
-                <PayPal>
-                  <Token>' . check_plain($token) . '</Token>
-                </PayPal>
-              </Tender>
-            </PayData>
-          </' . $payment_action . '>
-        </GetExpressCheckout>';
-
-  return _uc_payflowpro_wrap_xml($xml);
-}
-
-// Generate XML for DoExpressCheckout
-function _uc_payflowpro_do_ec_xml($order) {
-  // Get payment action (Sale or Authorization)
-  $payment_action = variable_get('uc_payflowpro_payment_action', '');
-
-  $xml = '         <DoExpressCheckout>
-          <' . $payment_action . '>
-            <PayData>
-' . _uc_payflowpro_invoice_xml($order) . '
-              <Tender>
-                <PayPal>
-                  <Token>' . check_plain($_SESSION['TOKEN']) . ' </Token>
-                  <PayerID>' . check_plain($_SESSION['PAYERID']) . '</PayerID>
-                  <ButtonSource>Ubercart_ShoppingCart_EC_US</ButtonSource>
-                </PayPal>
-              </Tender>
-            </PayData>
-          </' . $payment_action . '>
-          </DoExpressCheckout>';
-
-  return _uc_payflowpro_wrap_xml($xml);
-}
-
 // Generate XML for Recurring profiles
 function _uc_payflowpro_recurring_profile($order, $opt = array()) {
   $billing_country = uc_get_country_data(array('country_id' => $order->billing_country));
diff --git a/uc_payflowpro_ec/uc_payflowpro_ec.admin.inc b/uc_payflowpro_ec/uc_payflowpro_ec.admin.inc
new file mode 100644
index 0000000..5e806a6
--- /dev/null
+++ b/uc_payflowpro_ec/uc_payflowpro_ec.admin.inc
@@ -0,0 +1,333 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * PayFlow Pro Express Checkout administration menu items.
+ */
+
+/**
+ * Handles the Get Express Checkout action for the checkout page.
+ */
+function uc_payflowpro_ec_review_redirect() {
+  if (!isset($_SESSION['TOKEN']) || ($order = uc_order_load($_SESSION['cart_order'])) == FALSE) {
+    unset($_SESSION['cart_order'], $_SESSION['have_details']);
+    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
+    drupal_set_message(t('An error has occurred in your PayPal payment. Please review your cart and try again.'));
+    drupal_goto('cart');
+  }
+
+  module_load_include('inc', 'uc_payflowpro_ec', 'uc_payflowpro_ec');
+
+  // Set parameters specific to this request.
+  $request = array(
+    'TRXTYPE' => uc_payflowpro_ec_txn_type(),
+    'TOKEN' => $_SESSION['TOKEN'],
+    'ACTION' => 'G',
+  );
+
+  // Send the request and get the response.
+  $response = uc_payflowpro_ec_request($request);
+
+  // Get the PayerID from the response.
+  $_SESSION['PAYERID'] = check_plain($response['PAYERID']);
+
+  drupal_goto('cart/checkout/review');
+}
+
+/**
+ * Handles the Get Express Checkout action for the cart page.
+ */
+function uc_payflowpro_ec_review() {
+  if (!isset($_SESSION['TOKEN']) || ($order = uc_order_load($_SESSION['cart_order'])) == FALSE) {
+    unset($_SESSION['cart_order'], $_SESSION['have_details']);
+    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
+    drupal_set_message(t('An error has occurred in your PayPal payment. Please review your cart and try again.'));
+    drupal_goto('cart');
+  }
+
+  if ($_SESSION['have_details'][$order->order_id] !== TRUE) {
+    module_load_include('inc', 'uc_payflowpro_ec', 'uc_payflowpro_ec');
+
+    // Set parameters specific to this request.
+    $request = array(
+      'TRXTYPE' => uc_payflowpro_ec_txn_type(),
+      'TOKEN' => $_SESSION['TOKEN'],
+      'ACTION' => 'G',
+    );
+
+    // Send the request and get the response.
+    $response = uc_payflowpro_ec_request($request);
+
+    // If no response was received from PayFlow Pro.
+    if (!$response) {
+      drupal_set_message(t('Received a blank response from PayPal.'), 'error');
+      watchdog('uc_payflowpro_ec', 'Received a blank response from PayFlow Pro.<br />Action: GetExpressCheckout<br />Order: !order_id', array('!order' => $order->order_id), WATCHDOG_ERROR);
+      drupal_goto('cart');
+    }
+    // If an error message was received from PayFlow Pro.
+    elseif ($response['RESULT'] != 0) {
+      drupal_set_message(t('Received an error message from PayPal:<br />@message', array('@message' => $response['RESPMSG'])), 'error');
+      watchdog('uc_payflowpro_ec', 'Received an error message from PayFlow Pro.<br />Result: @result<br />Message: @message<br />Action: GetExpressCheckout<br />Order: !order_id', array('@result' => $response['RESULT'], '@message' => $response['RESPMSG'], '!order_id' => $order->order_id), WATCHDOG_ERROR);
+      drupal_goto('cart');
+    }
+    // If approved message was received from PayFlow Pro.
+    else {
+      $_SESSION['PAYERID'] = check_plain($response['PAYERID']);
+
+      $order->payment_method = 'payflowpro_ec';
+
+      if (empty($order->primary_email)) {
+        $order->primary_email = $response['EMAIL'];
+      }
+
+      $shipname = check_plain($response['SHIPTONAME']);
+      if (strpos($shipname, ' ') > 0) {
+        $order->delivery_first_name = substr($shipname, 0, strrpos(trim($shipname), ' '));
+        $order->delivery_last_name = substr($shipname, strrpos(trim($shipname), ' ') + 1);
+      }
+      else {
+        $order->delivery_first_name = $shipname;
+        $order->delivery_last_name = '';
+      }
+
+      $country_id = db_result(db_query("SELECT country_id FROM {uc_countries} WHERE country_iso_code_2 = '%s'", $response['SHIPTOCOUNTRY']));
+      $zone = check_plain($response['SHIPTOSTATE']);
+      $zone_id = 0;
+
+      if (!empty($country_id) && !empty($zone)) {
+        $zone_id = db_result(db_query("SELECT zone_id FROM {uc_zones} WHERE zone_country_id = '%s' AND (zone_code = '%s' OR zone_name = '%s')", $country_id, $zone, $zone));
+      }
+
+      $order->delivery_street1 = check_plain($response['SHIPTOSTREET']);
+      $order->delivery_street2 = check_plain($response['SHIPTOSTREET2']);
+      $order->delivery_city = check_plain($response['SHIPTOCITY']);
+      $order->delivery_zone = !empty($zone_id) ? $zone_id : 0;
+      $order->delivery_postal_code = check_plain($response['SHIPTOZIP']);
+      $order->delivery_country = !empty($country_id) ? $country_id : 840;
+      $order->delivery_company = check_plain($response['SHIPTOBUSINESS']);
+      $order->delivery_phone = check_plain($response['PHONENUM']);
+      $order->billing_first_name = $response['FIRSTNAME'];
+      $order->billing_last_name = $response['LASTNAME'];
+      $order->billing_street1 = $response['STREET'];
+      $order->billing_street2 = $response['STREET2'];
+      $order->billing_city = $response['CITY'];
+      $order->billing_zone = $response['STATE'];
+      $order->billing_postal_code = $response['ZIP'];
+      $order->billing_country = $response['COUNTRYCODE'];
+
+      uc_order_save($order);
+
+      $_SESSION['have_details'][$order->order_id] = TRUE;
+    }
+  }
+
+  $output = t("Your order is almost complete!  Please fill in the following details and click 'Continue checkout' to finalize the purchase.");
+
+  $output .= drupal_get_form('uc_payflowpro_ec_review_form', $order);
+
+  return $output;
+}
+
+/**
+ * Form builder for the PayFlow Pro Express Checkout review form.
+ *
+ * @param $order
+ *   An Ubercart order object.
+ *
+ * @see uc_payflowpro_ec_review_form_validate()
+ * @see uc_payflowpro_ec_review_form_submit()
+ * @ingroup forms
+ */
+function uc_payflowpro_ec_review_form($form_state, $order) {
+  if (module_exists('uc_quote') && variable_get('uc_payflowpro_ec_review_shipping', TRUE) && uc_order_is_shippable($order)) {
+    $result = uc_checkout_pane_quotes('view', $order, NULL);
+    $form['panes']['quotes'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Calculate shipping'),
+      '#collapsible' => FALSE,
+    );
+    $form['panes']['quotes'] += $result['contents'];
+    $form['panes']['quotes']['quote_button']['#value'] = t('Click to refresh shipping options');
+
+    $form['panes']['quotes']['quote_div'] = array(
+      '#value' => '<div id="quote"></div>',
+    );
+
+    // Small hack; automatically looks for shipping quotes on page load
+    drupal_add_js("\$(document).ready(function() { \$(' #edit-quote-button').click(); });", 'inline');
+
+    // Fake the checkout form delivery information.
+    $form['delivery_first_name'] = array('#type' => 'hidden', '#value' => $order->delivery_first_name);
+    $form['delivery_last_name'] = array('#type' => 'hidden', '#value' => $order->delivery_last_name);
+    $form['delivery_company'] = array('#type' => 'hidden', '#value' => $order->delivery_company);
+    $form['delivery_street1'] = array('#type' => 'hidden', '#value' => $order->delivery_street1);
+    $form['delivery_street2'] = array('#type' => 'hidden', '#value' => $order->delivery_street2);
+    $form['delivery_city'] = array('#type' => 'hidden', '#value' => $order->delivery_city);
+    $form['delivery_postal_code'] = array('#type' => 'hidden', '#value' => $order->delivery_postal_code);
+    $form['delivery_phone'] = array('#type' => 'hidden', '#value' => $order->delivery_phone);
+    $form['delivery_zone'] = array(
+      '#type' => 'select',
+      '#options' => drupal_map_assoc(array($order->delivery_zone)),
+      '#default_value' => $order->delivery_zone,
+      '#attributes' => array('style' => 'display: none;'),
+    );
+    $form['delivery_country'] = array(
+      '#type' => 'select',
+      '#options' => drupal_map_assoc(array($order->delivery_country)),
+      '#default_value' => $order->delivery_country,
+      '#attributes' => array('style' => 'display: none;'),
+    );
+
+    $form['shippable'] = array('#type' => 'hidden', '#value' => 'true');
+  }
+
+  // Get the required status of Ubercart address fields.
+  $required = variable_get('uc_address_fields_required', drupal_map_assoc(array('first_name', 'last_name', 'street1', 'city', 'zone', 'postal_code', 'country')));
+
+  if (variable_get('uc_payflowpro_ec_review_company', TRUE)) {
+    $form['delivery_company'] = array(
+      '#type' => 'textfield',
+      '#title' => uc_get_field_name('company'),
+      '#description' => uc_order_is_shippable($order) ? t('Leave blank if shipping to a residence.') : '',
+      '#default_value' => $order->delivery_company,
+      '#required' => isset($required['company']) ? TRUE : FALSE,
+    );
+  }
+
+  if (variable_get('uc_payflowpro_ec_review_phone', TRUE)) {
+    $form['delivery_phone'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Contact phone number'),
+      '#default_value' => $order->delivery_phone,
+      '#required' => isset($required['phone']) ? TRUE : FALSE,
+      '#size' => 24,
+    );
+  }
+
+  if (variable_get('uc_payflowpro_ec_review_comment', TRUE)) {
+    $form['order_comments'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Order comments'),
+      '#description' => t('Special instructions or notes regarding your order.'),
+    );
+  }
+
+  if (empty($form)) {
+    drupal_goto('uc_payflowpro_ec/submit');
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Continue checkout'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form validation handler for uc_payflowpro_ec_review_form().
+ *
+ * @see uc_payflowpro_ec_review_form()
+ * @see uc_payflowpro_ec_review_form_submit()
+ */
+function uc_payflowpro_ec_review_form_validate($form, &$form_state) {
+  if ($form_state['values']['shippable'] == 'true') {
+    if (!isset($_POST['quote-option'])) {
+      form_set_error('shipping', t('You must calculate and select a shipping option.'));
+    }
+  }
+}
+
+/**
+ * Form submission handler for uc_payflowpro_ec_review_form().
+ *
+ * @see uc_payflowpro_ec_review_form()
+ * @see uc_payflowpro_ec_review_form_validate()
+ */
+function uc_payflowpro_ec_review_form_submit($form, &$form_state) {
+  $order = uc_order_load($_SESSION['cart_order']);
+
+  if ($form_state['values']['shippable'] == 'true') {
+    $method_accessorials= split("---", isset($_POST['quote-option']) ? strval($_POST['quote-option']) : 0);
+    $order->quote['method'] = $method_accessorials[0];
+    $order->quote['accessorials'] = $method_accessorials[1];
+    $order->quote['rate'] = $_POST['rate'][isset($_POST['quote-option']) ? strval($_POST['quote-option']) : 0];
+
+    $order->quote['quote_form'] = rawurldecode($_POST['quote-form']);
+    $methods = module_invoke_all('shipping_method');
+    $method = $methods[$order->quote['method']];
+    $label = is_null($_POST['quote-option']) ? t('Error calculating shipping') : $method['quote']['accessorials'][$order->quote['accessorials']];
+    $result = db_query("SELECT line_item_id FROM {uc_order_line_items} WHERE order_id = %d AND type = 'shipping'", $order->order_id);
+    if ($lid = db_result($result)) {
+      uc_order_update_line_item($lid, $label, $order->quote['rate']);
+    }
+    else {
+      uc_order_line_item_add($order->order_id, 'shipping', $label, $order->quote['rate']);
+    }
+  }
+
+  if (variable_get('uc_payflowpro_ec_review_company', TRUE)) {
+    $order->delivery_company = $form_state['values']['delivery_company'];
+  }
+
+  if (variable_get('uc_payflowpro_ec_review_phone', TRUE)) {
+    $order->delivery_phone = $form_state['values']['delivery_phone'];
+  }
+
+  if (variable_get('uc_payflowpro_ec_review_comment', TRUE)) {
+    db_query("DELETE FROM {uc_order_comments} WHERE order_id = %d", $order->order_id);
+    uc_order_comment_save($order->order_id, 0, $form_state['values']['order_comments'], 'order');
+  }
+
+  uc_order_save($order);
+
+  $form_state['redirect'] = 'uc_payflowpro_ec/submit';
+}
+
+/**
+ * Presents the final total to the user for checkout.
+ */
+function uc_payflowpro_ec_submit() {
+  if (!isset($_SESSION['TOKEN']) || ($order = uc_order_load($_SESSION['cart_order'])) == FALSE) {
+    unset($_SESSION['cart_order'], $_SESSION['have_details']);
+    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
+    drupal_set_message(t('An error has occurred in your PayPal payment. Please review your cart and try again.'));
+    drupal_goto('cart');
+  }
+
+  drupal_add_css(drupal_get_path('module', 'uc_cart') .'/uc_cart.css');
+  $output = '<div>'. theme('cart_review_table', FALSE) .'</div>';
+  $output .= uc_order_pane_line_items('customer', $order);
+  $output .= '<p>'. t("Your order is not complete until you click the 'Submit order' button below. Your PayPal account will be charged for the amount shown above once your order is placed. You will receive confirmation once your payment is complete.") .'</p>';
+  $output .= drupal_get_form('uc_payflowpro_ec_submit_form');
+
+  return $output;
+}
+
+/**
+ * Form builder for the PayFlow Pro Express Checkout submit form.
+ *
+ * @see uc_payflowpro_ec_submit_form_submit()
+ * @ingroup forms
+ */
+function uc_payflowpro_ec_submit_form() {
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit order'),
+  );
+
+  return $form;
+}
+
+/**
+ * Handles a canceled Express Checkout sale.
+ */
+function uc_payflowpro_ec_cancel() {
+  unset($_SESSION['cart_order']);
+  unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
+
+  drupal_set_message(t('Your PayPal payment was cancelled. Please feel free to continue shopping or contact us for assistance.'));
+
+  drupal_goto('cart');
+}
diff --git a/uc_payflowpro_ec/uc_payflowpro_ec.inc b/uc_payflowpro_ec/uc_payflowpro_ec.inc
new file mode 100644
index 0000000..74ded1c
--- /dev/null
+++ b/uc_payflowpro_ec/uc_payflowpro_ec.inc
@@ -0,0 +1,201 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ *   Provides wrapper functions to the PayFlow Pro API.
+ */
+
+/**
+ * Adds user parameters to a PayFlow Pro request and sends the request.
+ *
+ * @param $request
+ *   Associative array containig parameters specific to the request.
+ *
+ * @return
+ *   Name/Value pair string response from PayFlow Pro.
+ */
+function uc_payflowpro_ec_request($request) {
+  // We use += to add parameters so existing keys will not be overridden.
+  $request += array(
+    'TENDER' => 'P',
+    'PARTNER' => check_plain(variable_get('uc_payflowpro_partner', 'PayPal')),
+    'VENDOR' => check_plain(variable_get('uc_payflowpro_vendor', '')),
+    'USER' => check_plain(variable_get('uc_payflowpro_user', '')),
+    'PWD' => check_plain(variable_get('uc_payflowpro_password', '')),
+  );
+
+  $data = '';
+  foreach ($request as $key => $value) {
+    $data .= $key . '=' . str_replace(',', '', $value) . '&';
+  }
+  $data = substr($data, 0, -1);
+
+  // Get the server to send the request to (test or live).
+  if (variable_get('uc_payflowpro_mode', 'test') == 'test') {
+    $url = 'https://pilot-payflowpro.paypal.com:443';
+  }
+  else {
+    $url = 'https://payflowpro.paypal.com:443';
+  }
+
+  $headers = array(
+    'Content-Type' => 'text/namevalue',
+    'X-VPS-Timeout' => '30',
+    'X-VPS-VIT-OS-Name' => 'Linux',  // Name of your Operating System (OS)
+    'X-VPS-VIT-OS-Version' => 'RHEL 4',  // OS Version
+    'X-VPS-VIT-Client-Type' => 'PHP/cURL',  // Language you are using
+    'X-VPS-VIT-Client-Version' => '1.0',  // For your info
+    'X-VPS-VIT-Client-Architecture' => 'x86',  // For your info
+    'X-VPS-VIT-Client-Certification-Id' => '33baf5893fc2123d8b191d2d011b7fdc', // This header requirement will be removed
+    'X-VPS-VIT-Integration-Product' => 'Ubercart',  // For your info, would populate with application name
+    'X-VPS-VIT-Integration-Version' => '2.0', // Application version
+    'X-VPS-Request-ID' => sha1($data . time()),
+  );
+
+  $ch = curl_init();
+  curl_setopt($ch, CURLOPT_CAINFO, check_plain(variable_get('uc_payflowpro_cert_path', '')));
+  curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
+  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
+  curl_setopt($ch, CURLOPT_HEADER, FALSE);
+  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+  curl_setopt($ch, CURLOPT_NOPROGRESS, TRUE);
+  curl_setopt($ch, CURLOPT_POST, TRUE);
+  curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+  curl_setopt($ch, CURLOPT_URL, $url);
+  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
+  curl_setopt($ch, CURLOPT_VERBOSE, FALSE);
+  $response = curl_exec($ch);
+  if ($error = curl_error($ch)) {
+    watchdog('uc_payflowpro', '!error', array('!error' => $error), WATCHDOG_ERROR);
+  }
+  curl_close($ch);
+
+  return uc_payflowpro_ec_nvp_to_array($response);
+}
+
+/**
+ * Builds the product section of a PayFlow Pro Express Checkout request.
+ *
+ * @param $products
+ *   Reference to an Ubercart products array.
+ *
+ * @return
+ *   An associative array containing:
+ *   - $request: The product section of a PayFlow Pro request.
+ *   - $subtotal: The subtotal of all products.
+ */
+function uc_payflowpro_ec_request_products(&$products) {
+  // Create an altered price context.
+  $context = array(
+    'revision' => 'original',
+    'type' => 'amount',
+  );
+
+  // Create a price context and options array adhering to the PayFlow Pro
+  // Express Checkout guidelines.
+  $ec_context = array(
+    'revision' => 'formatted-original',
+    'type' => 'amount',
+  );
+  $ec_options = array(
+    'dec' => '.',
+    'prec' => 2,
+    'sign' => FALSE,
+    'thou' => FALSE,
+  );
+
+  $subtotal = 0;
+  $i = 1;
+
+  // Build the request for each product and calculate the subtotal.
+  foreach ($products as $product) {
+    $price_info = array(
+      'price' => $product->price,
+      'qty' => $product->qty,
+    );
+    $request['L_NAME' . $i] = substr($product->title, 0, 36);
+    $request['L_DESC' . $i] = substr($product->model, 0, 35);
+    $request['L_COST' . $i] = substr(uc_price($price_info, $ec_context, $ec_options), 0, 10);
+    $request['L_QTY' . $i] = substr($product->qty, 0, 10);
+
+    $subtotal += uc_price($price_info, $context);
+    ++$i;
+  }
+
+  // Set the item subtotal amount.
+  $request['ITEMAMT'] = substr(uc_price($subtotal, $ec_context, $ec_options), 0, 10);
+
+  return array($request, $subtotal);
+}
+
+/**
+ * Returns an associative array of PayFlow Pro supported currencies.
+ */
+function uc_payflowpro_ec_currencies() {
+  return array(
+    'AUD' => 'Australian Dollar',
+    'BRL' => 'Brazilian Real',
+    'CAD' => 'Canadian Dollar',
+    'CZK' => 'Czech Koruna',
+    'DKK' => 'Danish Krone',
+    'EUR' => 'Euro',
+    'HKD' => 'Hong Kong Dollar',
+    'HUF' => 'Hungarian Forint',
+    'ILS' => 'Israeli New Sheqel',
+    'JPY' => 'Japanese Yen',
+    'MYR' => 'Malaysian Ringgit',
+    'MXN' => 'Mexican Peso',
+    'NOK' => 'Norwegian Krone',
+    'NZD' => 'New Zealand Dollar',
+    'PHP' => 'Phillippine Peso',
+    'PLN' => 'Polish Zloty',
+    'GBP' => 'Pound Sterling',
+    'SGD' => 'Singapore Dollar',
+    'SEK' => 'Swedish Krona',
+    'CHF' => 'Swiss Franc',
+    'TWD' => 'Taiwan New Dollar',
+    'THB' => 'Thai Baht',
+    'USD' => 'U.S. Dollar',
+  );
+}
+
+/**
+ * Maps Drupal locales to the most relevant PayFlow Pro locales (countries).
+ *
+ * @return
+ *   An associative array of Drupal locale keys and PayFlow Pro locale values.
+ */
+function uc_payflowpro_ec_locales() {
+  return array(
+    //'AT', // Austria
+    'en' => 'US', // Australia, Canada, United Kingdom
+    //'BE', // Belgium
+    //'CH', // Switzerland
+    'zh-hans' => 'CN', // China
+    'zh-hant' => 'CN', // China
+    'de' => 'DE', // Germany
+    'es' => 'ES', // Spain
+    'fr' => 'FR', // France
+    'it' => 'IT', // Italy
+    'ja' => 'JP', // Japan
+    'nl' => 'NL', // Netherlands
+    'pl' => 'PL', // Poland
+  );
+}
+
+/**
+ * Converts a Name/Value pair string into an associative array.
+ *
+ * @param $nvpstr
+ *   Name/Value pair string.
+ */
+function uc_payflowpro_ec_nvp_to_array($nvpstr) {
+  foreach (explode('&', $nvpstr) as $nvp) {
+    list($key, $value) = explode('=', $nvp);
+    $nvp_array[$key] = $value;
+  }
+
+  return $nvp_array;
+}
diff --git a/uc_payflowpro_ec/uc_payflowpro_ec.info b/uc_payflowpro_ec/uc_payflowpro_ec.info
new file mode 100755
index 0000000..8ace3e2
--- /dev/null
+++ b/uc_payflowpro_ec/uc_payflowpro_ec.info
@@ -0,0 +1,7 @@
+; $Id$
+name = PayFlow Pro Express Checkout
+description = Allows use of Express Checkout with uc_payflowpro.
+dependencies[] = uc_payflowpro
+package = Ubercart - payment
+core = 6.x
+php = 5.0
diff --git a/uc_payflowpro_ec/uc_payflowpro_ec.install b/uc_payflowpro_ec/uc_payflowpro_ec.install
new file mode 100755
index 0000000..3930f14
--- /dev/null
+++ b/uc_payflowpro_ec/uc_payflowpro_ec.install
@@ -0,0 +1,22 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Install, update and uninstall functions for the UC PayPal PayFlow Pro
+ * Express Checkout module.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function uc_payflowpro_ec_uninstall() {
+  variable_del('uc_payflowpro_ec_currency');
+  variable_del('uc_payflowpro_ec_reqbillingaddress');
+  variable_del('uc_payflowpro_ec_reqconfirmshipping');
+  variable_del('uc_payflowpro_ec_review_comment');
+  variable_del('uc_payflowpro_ec_review_company');
+  variable_del('uc_payflowpro_ec_review_phone');
+  variable_del('uc_payflowpro_ec_review_shipping');
+  variable_del('uc_payment_method_payflowpro_ec_checkout');
+}
diff --git a/uc_payflowpro_ec/uc_payflowpro_ec.module b/uc_payflowpro_ec/uc_payflowpro_ec.module
new file mode 100755
index 0000000..a07fc77
--- /dev/null
+++ b/uc_payflowpro_ec/uc_payflowpro_ec.module
@@ -0,0 +1,535 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Adds a PayPal Express Checkout payment method to Ubercart.
+ */
+
+/******************************************************************************
+ * Hook Functions (Drupal)
+ *****************************************************************************/
+
+/**
+ * Implements hook_menu().
+ */
+function uc_payflowpro_ec_menu() {
+  // Callback functions for Express Checkout.
+  $items['uc_payflowpro_ec/selected'] = array(
+    'title' => 'Review order',
+    'page callback' => 'uc_payflowpro_ec_review_redirect',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_payflowpro_ec.admin.inc',
+  );
+  $items['uc_payflowpro_ec/review'] = array(
+    'title' => 'Review payment',
+    'page callback' => 'uc_payflowpro_ec_review',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_payflowpro_ec.admin.inc',
+  );
+  $items['uc_payflowpro_ec/submit'] = array(
+    'title' => 'Submit order',
+    'page callback' => 'uc_payflowpro_ec_submit',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_payflowpro_ec.admin.inc',
+  );
+  $items['uc_payflowpro_ec/cancel'] = array(
+    'title' => 'PayFlow Pro Express Checkout payment cancelled',
+    'page callback' => 'uc_payflowpro_ec_cancel',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_payflowpro_ec.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function uc_payflowpro_ec_form_uc_cart_checkout_form_alter(&$form, $form_state) {
+  if (variable_get('uc_payment_method_payflowpro_ec_checkout', FALSE)) {
+    $form['#submit'][] = 'uc_payflowpro_ec_checkout';
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function uc_payflowpro_ec_form_uc_cart_checkout_review_form_alter(&$form, $form_state) {
+  if (!empty($_SESSION['TOKEN'])) {
+    $form['#submit'][] = 'uc_payflowpro_ec_submit_form_submit';
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function uc_payflowpro_ec_form_uc_payment_gateways_form_alter(&$form, $form_state) {
+  module_load_include('inc', 'uc_payflowpro_ec', 'uc_payflowpro_ec');
+
+  // Add Express Checkout settings to the PayPal PayFlow Pro gateway settings.
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Express Checkout'),
+    '#description' => t('These settings are specifically for the alternate checkout system offered by Express Checkout.<br>To enable this on your site, you must enable the corresponding cart pane in the <em>Cart settings</em> menu.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_payflowpro_ec_currency'] = array(
+    '#type' => 'select',
+    '#title' => t('Currency code'),
+    '#description' => t('Transactions can only be processed in one of the listed currencies. N O T E : The Brazilian Real and Malaysian Ringgit currencies are supported as a payment currency and a currency balance for in-country PayPal accounts only.'),
+    '#options' => uc_payflowpro_ec_currencies(),
+    '#default_value' => variable_get('uc_payflowpro_ec_currency', 'USD'),
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_payflowpro_ec_reqbillingaddress'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Require that the buyer’s billing address on file with PayPal be a confirmed address.'),
+    '#default_value' => variable_get('uc_payflowpro_ec_reqbillingaddress', FALSE),
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_payflowpro_ec_reqconfirmshipping'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Require that the buyer’s shipping address on file with PayPal be a confirmed address.'),
+    '#default_value' => variable_get('uc_payflowpro_ec_reqconfirmshipping', FALSE),
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_payflowpro_ec_review_shipping'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable the shipping select form on the Review payment page.'),
+    '#default_value' => variable_get('uc_payflowpro_ec_review_shipping', TRUE),
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_paypflowpro_ec_review_company'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable the company name box on the Review payment page.'),
+    '#default_value' => variable_get('uc_payflowpro_ec_review_company', TRUE),
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_payflowpro_ec_review_phone'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable the contact phone number box on the Review payment page.'),
+    '#default_value' => variable_get('uc_payflowpro_ec_review_phone', TRUE),
+  );
+  $form['gateways']['payflowpro']['payflowpro_settings']['ec']['uc_payflowpro_ec_review_comment'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable the comment text box on the Review payment page.'),
+    '#default_value' => variable_get('uc_payflowpro_ec_review_comment', TRUE),
+  );
+}
+
+/******************************************************************************
+ * Hook Functions (Ubercart)
+ *****************************************************************************/
+
+/**
+ * Implements hook_cart_pane().
+ */
+function uc_payflowpro_ec_cart_pane() {
+  $panes[] = array(
+    'id' => 'uc_payflowpro_ec',
+    'title' => t('PayFlow Pro Express Checkout'),
+    'enabled' => FALSE,
+    'weight' => 1,
+    'body' => '<div align="right">'. drupal_get_form('uc_payflowpro_ec_form') .'</div>',
+  );
+
+  return $panes;
+}
+
+/**
+ * Implements hook_payment_method().
+ */
+function uc_payflowpro_ec_payment_method() {
+  $methods[] = array(
+    'id' => 'payflowpro_ec',
+    'name' => t('PayFlow Pro Express Checkout'),
+    'title' => '<img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" style="position: relative; top: 5px; margin-right: 4px;">' . t('PayPal - pay without sharing your financial information.'),
+    'review' => t('PayFlow Pro Express Checkout'),
+    'desc' => t('Complete orders through PayFlow Pro Express Checkout.'),
+    'callback' => 'uc_payment_method_payflowpro_ec',
+    'weight' => 1,
+    'checkout' => FALSE,
+    'no_gateway' => TRUE,
+  );
+
+  return $methods;
+}
+
+/******************************************************************************
+ * Callback Functions
+ *****************************************************************************/
+
+/**
+ * Handles the Set Express Checkout action for the checkout page.
+ *
+ * Added to the Ubercart checkout form as a submit handler.
+ *
+ * @see uc_cart_checkout_form()
+ */
+function uc_payflowpro_ec_checkout($form, &$form_state) {
+  if ($form_state['values']['panes']['payment']['payment_method'] != 'payflowpro_ec') {
+    return;
+  }
+
+  $order_id = intval($_SESSION['cart_order']);
+
+  $order = uc_order_load($order_id);
+  if ($order === FALSE || uc_order_status_data($order->order_status, 'state') != 'in_checkout') {
+    $_SESSION['cart_order'] = NULL;
+    unset($_SESSION['cart_order']);
+    drupal_goto('cart');
+  }
+
+  module_load_include('inc', 'uc_payflowpro_ec', 'uc_payflowpro_ec');
+
+  list($request, $subtotal) = uc_payflowpro_ec_request_products($order->products);
+
+  // Set the locale based on the current language.
+  $locales = uc_payflowpro_ec_locales();
+  if (in_array($language->language, $locales)) {
+    $local_code = $locales[$language->language];
+  }
+  else {
+    $locale_code = $locales['en'];
+  }
+
+  $country = uc_get_country_data(array('country_id' => $order->billing_country));
+  if ($country === FALSE) {
+    $country = array(0 => array('country_iso_code_2' => 'US'));
+  }
+
+  $context = array(
+    'revision' => 'formatted-original',
+    'type' => 'order_total',
+    'subject' => array(
+      'order' => $order,
+    ),
+  );
+  $options = array(
+    'dec' => '.',
+    'prec' => 2,
+    'sign' => FALSE,
+    'thou' => FALSE,
+  );
+
+  // Add parameters specific to this request.
+  $request += array(
+    'TRXTYPE' => uc_payflowpro_ec_txn_type(),
+    'ACTION' => 'S',
+    'AMT' => substr(uc_price($order->order_total, $context, $options), 0, 10),
+    'CURRENCY' => variable_get('uc_payflowpro_ec_currency', 'USD'),
+    'RETURNURL' => url('uc_payflowpro_ec/selected', array('absolute' => TRUE)),
+    'CANCELURL' => url('uc_payflowpro_ec/cancel', array('absolute' => TRUE)),
+    'ALLOWNOTE' => FALSE,
+    'INVNUM' => $order->order_id,
+    'PHONENUM' => substr($order->delivery_phone, 0, 20),
+    'REQBILLINGADDRESS' => variable_get('uc_payflowpro_ec_reqbillingaddress', FALSE),
+    'REQCONFIRMSHIPPING' => variable_get('uc_payflowpro_ec_reqconfirmshipping', FALSE),
+    'ADDROVERRIDE' => TRUE,
+    'LOCALECODE' => $locale_code,
+    'EMAIL' => isset($user->mail) ? substr($user->mail, 0, 127) : '',
+    'SHIPTONAME' => substr($order->delivery_first_name .' '. $order->delivery_last_name, 0, 32),
+    'SHIPTOSTREET' => substr($order->delivery_street1, 0, 30),
+    'SHIPTOSTREET2' => substr($order->delivery_street2, 0, 30),
+    'SHIPTOCITY' => substr($order->delivery_city, 0, 40),
+    'SHIPTOSTATE' => uc_get_zone_code($order->delivery_zone),
+    'SHIPTOZIP' => substr($order->delivery_postal_code, 0, 16),
+    'SHIPTOCOUNTRY' => $country[0]['country_iso_code_2'],
+  );
+
+  if (!uc_cart_is_shippable()) {
+    $request['NOSHIPPING'] = 1;
+    unset($request['ADDROVERRIDE']);
+  }
+
+  // Send the request and get the response.
+  $response = uc_payflowpro_ec_request($request);
+
+  // If no response was received from PayFlow Pro.
+  if (!$response) {
+    drupal_set_message(t('Received a blank response from PayFlow Pro.'), 'error');
+    watchdog('uc_payflowpro_ec', 'Received a blank response from the PayFlow Pro gateway.<br />Action: SetExpressCheckout<br />Order #: !order_id', array('!order_id' => $order->order_id), WATCHDOG_ERROR);
+    drupal_goto('cart/checkout');
+  }
+  // If an error message was received from PayFlow Pro.
+  elseif ($response['RESULT'] != 0) {
+    drupal_set_message(t('Received an error message from PayPal:<br />@message', array('@message' => $response['RESPMSG'])), 'error');
+    watchdog('uc_payflowpro_ec', 'Received an error message from PayFlow Pro.<br />Result: @result<br />Message: @message<br />Action: SetExpressCheckout<br />Order #: !order_id', array('@result' => $response['RESULT'], '@message' => $response['RESPMSG'], '!order_id' => $order->order_id), WATCHDOG_ERROR);
+    drupal_goto('cart/checkout');
+  }
+  // If approved message was received from PayFlow Pro.
+  else {
+    $_SESSION['TOKEN'] = $response['TOKEN'];
+    header('Location: ' . uc_payflowpro_ec_url());
+    exit();
+  }
+}
+
+/**
+ * Form submit handler for uc_payflowpro_ec_submit_form().
+ *
+ * Added as a submit handler for uc_cart_checkout_review_form() if the PayFlow
+ * Pro Express Checkout payment method is selected.
+ *
+ * Handles the Do Express Checkout action.
+ *
+ * @see uc_payflowpro_ec_submit_form()
+ * @see uc_cart_checkout_review_form()
+ */
+function uc_payflowpro_ec_submit_form_submit($form, &$form_state) {
+  $order = uc_order_load($_SESSION['cart_order']);
+
+  if ($order->payment_method != 'payflowpro_ec') {
+    return;
+  }
+
+  module_load_include('inc', 'uc_payflowpro_ec', 'uc_payflowpro_ec');
+
+  list($request, $subtotal) = uc_payflowpro_ec_request_products($order->products);
+
+  $shipping = 0;
+  if (is_array($order->line_items)) {
+    foreach ($order->line_items as $item) {
+      if ($item['type'] == 'shipping') {
+        $shipping += $item['amount'];
+      }
+    }
+  }
+
+  $tax = 0;
+  if (module_exists('uc_taxes')) {
+    foreach (uc_taxes_calculate($order) as $tax_item) {
+      $tax += $tax_item->amount;
+    }
+  }
+
+  $subtotal = $order->order_total - $tax - $shipping;
+
+  $context = array(
+    'revision' => 'formatted-original',
+    'type' => 'order_total',
+    'subject' => array(
+      'order' => $order,
+    ),
+  );
+  $options = array(
+    'dec' => '.',
+    'prec' => 2,
+    'sign' => FALSE,
+    'thou' => FALSE,
+  );
+
+  // Add parameters specific to this request.
+  $request += array(
+    'TRXTYPE' => uc_payflowpro_ec_txn_type(),
+    'TOKEN' => $_SESSION['TOKEN'],
+    'ACTION' => 'D',
+    'PAYERID' => $_SESSION['PAYERID'],
+    'AMT' => uc_price($order->order_total, $context, $options),
+    'ORDERURL' => url('user/' . $order->uid . '/order/' . $order->order_id, array('absolute' => TRUE)),
+    'INVNUM' => $order->order_id,
+    'BUTTONSOURCE' => 'Ubercart_PayFlowPro_EC_US',
+    // TODO: 'NOTIFYURL',
+    'TAXAMT' => substr(uc_price($tax, $context, $options), 0, 10),
+    'FREIGHTAMT' => substr(uc_price($shipping, $context, $options), 0, 10),
+    // TODO: 'DISCOUNT',
+  );
+
+  // Send the request and get the response.
+  $response = uc_payflowpro_ec_request($request);
+
+  // If no response was received from PayFlow Pro.
+  if (!$response) {
+    drupal_set_message(t('Received a blank response from PayPal.'), 'error');
+    watchdog('uc_payflowpro_ec', 'Received a blank response from PayFlow Pro.<br />Action: DoExpressCheckout<br />Order: !order_id', array('!order' => $order->order_id), WATCHDOG_ERROR);
+    drupal_goto('cart');
+  }
+  // If an error message was received from PayFlow Pro.
+  elseif ($response['RESULT'] != 0) {
+    drupal_set_message(t('Received an error message from PayPal:<br />@message', array('@message' => $response['RESPMSG'])), 'error');
+    watchdog('uc_payflowpro_ec', 'Received an error message from PayFlow Pro.<br />Result: @result<br />Message: @message<br />Action: DoExpressCheckout<br />Order: !order_id', array('@result' => $response['RESULT'], '@message' => $response['RESPMSG'], '!order_id' => $order->order_id), WATCHDOG_ERROR);
+    drupal_goto('cart');
+  }
+  // If approved message was received from PayFlow Pro.
+  else {
+    $comment = t('Credit card payment processed successfully with pnref @pnref.', array('@pnref' => $response['PNREF']));
+    $data = array(
+      'pnref' => $response['PNREF'],
+      'ppref' => $response['PPREF'],
+      'avsaddr' => $response['AVSADDR'],
+      'avszip' => $response['AVSZIP'],
+    );
+
+    // Save the comment to the order.
+    uc_order_comment_save($order->order_id, $user->uid, $comment, 'admin');
+
+    // Log the payment to the order.
+    uc_payment_enter($order->order_id, 'payflowpro_ec', uc_price($order->order_total, $context, $options), $user->uid, $data, $comment);
+
+    unset($_SESSION['TOKEN'], $_SESSION['PAYERID']);
+    $_SESSION['do_complete'] = TRUE;
+
+    $form_state['redirect'] = 'cart/checkout/complete';
+  }
+}
+
+/**
+ * Returns the Express Checkout form for the cart pane.
+ *
+ * @see uc_payflowpro_ec_cart_pane()
+ */
+function uc_payflowpro_ec_form() {
+  if (!variable_get('uc_cap_uc_payflowpro_ec_enabled', FALSE)) {
+    return;
+  }
+
+  // Hack to allow the image button to submit.
+  if (isset($_POST['submit_x'])) {
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => 'submit',
+    );
+  }
+
+  $form['submit_image'] = array(
+    '#value' => '<input name="submit" type="image" title="'. t('Checkout with PayPal.') .'" src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckoutsm.gif">',
+  );
+
+  return $form;
+}
+
+/**
+ * Handles the Set Express Checkout action for the cart page.
+ *
+ * Submit handler for the PayFlow Pro Express Checkout form.
+ *
+ * @see uc_payflowpro_ec_form()
+ */
+function uc_payflowpro_ec_form_submit($form, &$form_state) {
+  global $user;
+  $items = uc_cart_get_contents();
+
+  if (!is_array($items) || count($items) == 0) {
+    drupal_set_message(t('You do not have any items in your shopping cart.'));
+    return;
+  }
+
+  module_load_include('inc', 'uc_payflowpro_ec', 'uc_payflowpro_ec');
+
+  list($request, $subtotal) = uc_payflowpro_ec_request_products($items);
+
+  $order = uc_order_new($user->uid);
+
+  // Set the locale based on the current language.
+  $locales = uc_payflowpro_ec_locales();
+  if (in_array($language->language, $locales)) {
+    $local_code = $locales[$language->language];
+  }
+  else {
+    $locale_code = $locales['en'];
+  }
+
+  $context = array(
+    'revision' => 'formatted-original',
+    'type' => 'amount',
+  );
+  $options = array(
+    'dec' => '.',
+    'prec' => 2,
+    'sign' => FALSE,
+    'thou' => FALSE,
+  );
+
+  // Add parameters specific to this request.
+  $request += array(
+    'TRXTYPE' => uc_payflowpro_ec_txn_type(),
+    'ACTION' => 'S',
+    'AMT' => substr(uc_price($subtotal, $context, $options), 0, 10),
+    'CURRENCY' => variable_get('uc_payflowpro_ec_currency', 'USD'),
+    'RETURNURL' => url('uc_payflowpro_ec/review', array('absolute' => TRUE)),
+    'CANCELURL' => url('uc_payflowpro_ec/cancel', array('absolute' => TRUE)),
+    'ALLOWNOTE' => FALSE,
+    'INVNUM' => $order->order_id,
+    'REQBILLINGADDRESS' => variable_get('uc_payflowpro_ec_reqbillingaddress', FALSE),
+    'REQCONFIRMSHIPPING' => variable_get('uc_payflowpro_ec_reqconfirmshipping', FALSE),
+    'LOCALECODE' => $locale_code,
+    'EMAIL' => isset($user->mail) ? substr($user->mail, 0, 127) : '',
+  );
+
+  $order->products = $items;
+  uc_order_save($order);
+
+  // Send the request and get the response.
+  $response = uc_payflowpro_ec_request($request);
+
+  // If no response was received from PayFlow Pro.
+  if (!$response) {
+    drupal_set_message(t('Received a blank response from PayFlow Pro.'), 'error');
+    watchdog('uc_payflowpro_ec', 'Received a blank response from the PayFlow Pro gateway.<br />Action: SetExpressCheckout<br />Order #: !order_id', array('!order_id' => $order->order_id), WATCHDOG_ERROR);
+    drupal_goto('cart');
+  }
+  // If an error message was received from PayFlow Pro.
+  elseif ($response['RESULT'] != 0) {
+    drupal_set_message(t('Received an error message from PayPal:<br />@message', array('@message' => $response['RESPMSG'])), 'error');
+    watchdog('uc_payflowpro_ec', 'Received an error message from PayFlow Pro.<br />Result: @result<br />Message: @message<br />Action: SetExpressCheckout<br />Order #: !order_id', array('@result' => $response['RESULT'], '@message' => $response['RESPMSG'], '!order_id' => $order->order_id), WATCHDOG_ERROR);
+    drupal_goto('cart');
+  }
+  // If approved message was received from PayFlow Pro.
+  else {
+    $_SESSION['cart_order'] = $order->order_id;
+    $_SESSION['TOKEN'] = check_plain($response['TOKEN']);
+    header('Location: ' . uc_payflowpro_ec_url());
+    exit();
+  }
+}
+
+/**
+ * Handles the PayFlow Pro Express Checkout payment method.
+ *
+ * @see uc_payflowpro_ec_payment_method()
+ */
+function uc_payment_method_payflowpro_ec($op, &$arg1) {
+  switch ($op) {
+    // TODO: case 'order-view':
+    case 'settings':
+      $form['redirect'] = array(
+        '#value' => '<div>'. t('For Express Checkout, you need to <a href="!cp_link">enable the cart pane</a> and <a href="!pfp_link">configure the PayFlow Pro settings</a>.', array('!cp_link' => url('admin/store/settings/cart/edit/panes'), '!pfp_link' => url('admin/store/settings/payment/edit/gateways'))) .'</div>',
+      );
+      return $form;
+  }
+}
+
+/******************************************************************************
+ * Module and Helper Functions
+ *****************************************************************************/
+
+/**
+ * Returns the PayFlow Pro Express Checkout URL.
+ */
+function uc_payflowpro_ec_url() {
+  if (variable_get('uc_payflowpro_mode', 'test') == 'test') {
+    $url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='. $_SESSION['TOKEN'];
+  }
+  else {
+    $url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='. $_SESSION['TOKEN'];
+  }
+
+  return $url;
+}
+
+/**
+ * Returns the PayFlow Pro Express Checkout transaction type.
+ */
+function uc_payflowpro_ec_txn_type() {
+  // Get the transaction type (Sale or Authorization).
+  $txn_type = variable_get('uc_payflowpro_payment_action', '');
+  if ($txn_type == 'Sale') {
+    $txn_type = 'S';
+  }
+  elseif ($txn_type == 'Authorization') {
+    $txn_type = 'A';
+  }
+
+  return $txn_type;
+}
