--- /dev/null
+++ b/uc_sf_product/uc_sf_product.admin.inc
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * Bulk price import confirmation form.
+ */
+function uc_sf_product_salesforce_bulk_price_import() {
+  // Get all pricebook entries from Salesforce.
+  $pricebook = variable_get('uc_sf_product_pricebook', 'Standard Price Book');
+  $query = "SELECT Id, ProductCode, UnitPrice, CurrencyIsoCode FROM PricebookEntry WHERE Pricebook2.Name = '$pricebook'";
+  $response = _uc_sf_product_query($query);
+
+  $models = array();
+  foreach ($response->records as $entry) {
+    $models[$entry->ProductCode][$entry->CurrencyIsoCode] = array(
+      'sfid' => $entry->Id,
+      'price' => $entry->UnitPrice,
+    );
+  }
+
+  // Map Salesforce Product Codes to nodes.
+  $nodes = array();
+  $result = db_query("SELECT DISTINCT nid, model FROM {uc_products}");
+  while ($row = db_fetch_object($result)) {
+    if (isset($models[$row->model])) {
+      $nodes[$row->nid] = $models[$row->model];
+    }
+  }
+
+  $form['nodes'] = array('#type' => 'value', '#value' => $nodes);
+
+  return confirm_form($form, t('Are you sure you want to import product prices from Salesforce?'), 'admin/store/products', format_plural(count($nodes), '1 product node will be updated.', '@count product nodes will be updated.'), t('Import prices'), t('Cancel'));
+}
+
+/**
+ * Bulk price import handler.
+ */
+function uc_sf_product_salesforce_bulk_price_import_submit($form, &$form_state) {
+  $fieldmap = variable_get('uc_sf_order_order_product_export_fieldmap', FALSE);
+
+  foreach ($form_state['values']['nodes'] as $nid => $prices) {
+    $node = node_load($nid);
+    foreach ($prices as $currency => $data) {
+      if ($currency == variable_get('uc_currency_code', 'USD')) {
+        $node->sell_price = $data['price'];
+      }
+      elseif (module_exists('uc_multicurrency')) {
+        $node->multicurrency[$currency]['sell_price'] = $data['price'];
+      }
+
+      // Store the pricebook ID
+      if ($fieldmap) {
+        salesforce_api_id_save('uc_sf_pricebook_' . $currency, $nid, $data['sfid'], $fieldmap);
+      }
+    }
+    node_save($node);
+  }
+
+  drupal_set_message(t('Product prices have been imported from Salesforce.'));
+  drupal_goto('admin/store/products');
+}
+
+/**
+ * Salesforce product settings form.
+ */
+function uc_sf_product_salesforce_settings_form(&$form_state) {
+  $response = _uc_sf_product_query("SELECT Name FROM Pricebook2");
+
+  $options = array();
+  foreach ($response->records as $pricebook) {
+    $options[$pricebook->Name] = $pricebook->Name;
+  }
+
+  $form['uc_sf_product_pricebook'] = array(
+    '#type' => 'select',
+    '#title' => t('Salesforce pricebook'),
+    '#description' => t('This pricebook will be used to find product prices.'),
+    '#options' => $options,
+    '#default_value' => variable_get('uc_sf_product_pricebook', 'Standard Price Book'),
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Runs a Salesforce query.
+ */
+function _uc_sf_product_query($query) {
+  $sf = salesforce_api_connect();
+  if (!$sf) {
+    drupal_set_message(t('Unable to connect to Salesforce.'), 'error');
+    drupal_goto('admin/settings/salesforce');
+  }
+
+  return $sf->client->query($query);
+}
--- /dev/null
+++ b/uc_sf_product/uc_sf_product.info
@@ -0,0 +1,6 @@
+name = Ubercart Salesforce Product
+description = Allows Ubercart product prices to be imported from Salesforce.
+dependencies[] = salesforce_api
+dependencies[] = uc_product
+package = Salesforce
+core = 6.x
--- /dev/null
+++ b/uc_sf_product/uc_sf_product.module
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Implementation of hook_menu().
+ */
+function uc_sf_product_menu() {
+  $items['admin/store/products/salesforce-price-import'] = array(
+    'title' => 'Import prices from Salesforce',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_sf_product_salesforce_bulk_price_import'),
+    'access arguments' => array('administer salesforce'),
+    'type' => MENU_NORMAL_ITEM,
+    'file' => 'uc_sf_product.admin.inc',
+  );
+  $items['admin/store/settings/salesforce-products'] = array(
+    'title' => 'Salesforce product settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_sf_product_salesforce_settings_form'),
+    'access arguments' => array('administer salesforce'),
+    'type' => MENU_NORMAL_ITEM,
+    'file' => 'uc_sf_product.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
+ * Implementation of hook_fieldmap_objects_alter().
+ */
+function uc_sf_product_fieldmap_objects_alter(&$objects) {
+  // makes the same fields available for export to a contact as they are to an order
+  $objects['drupal']['uc_order_products']['fields']['pricebook_sfid'] = array(
+    'label' => t('Pricebook Entry Salesforce ID'),
+    'group' => t('Order Line Item Information'),
+    'type' => SALESFORCE_FIELD_SOURCE_ONLY,
+    'export' => '_uc_sf_product_export_pricebook_sfid',
+  );
+}
+
+function _uc_sf_product_export_pricebook_sfid($product) {
+  static $currency = array();
+
+  if (!isset($currency[$product->order_id])) {
+    $order = uc_order_load($product->order_id);
+    $currency[$product->order_id] = $order->currency;
+  }
+
+  $pricebook = salesforce_api_id_load('uc_sf_pricebook_' . $currency[$product->order_id], $product->nid);
+  return $pricebook->sfid;
+}
