diff --git a/modules/wpp/commerce_paypal_wpp.module b/modules/wpp/commerce_paypal_wpp.module
index 91cc83e..4366971 100644
--- a/modules/wpp/commerce_paypal_wpp.module
+++ b/modules/wpp/commerce_paypal_wpp.module
@@ -33,6 +33,7 @@ function commerce_paypal_wpp_default_settings() {
     'api_username' => '',
     'api_password' => '',
     'api_signature' => '',
+    'api_certificate' => '',
     'server' => 'sandbox',
     'code' => TRUE,
     'card_types' => drupal_map_assoc(array('visa', 'mastercard', 'amex', 'discover')),
@@ -61,10 +62,29 @@ function commerce_paypal_wpp_settings_form($settings = NULL) {
     '#title' => t('API password'),
     '#default_value' => $settings['api_password'],
   );
+  $form['fieldset_prefix'] = array(
+      '#type' => 'markup',
+      '#markup' => '<fieldset class="form-wrapper">' 
+                    . '<legend><span class="fieldset-legend">' . t('Credentials') . '</span></legend>'
+                    . '<div class="fieldset-wrapper">'
+                    . '<p>' . t('Paypal offers two methods of authentication, Signature or Certificate. You only need to enter one of these values. Signature will take precedence.') . '</p>'
+  );
   $form['api_signature'] = array(
     '#type' => 'textfield',
     '#title' => t('Signature'),
     '#default_value' => $settings['api_signature'],
+    '#suffix' => '<p>OR</p>',
+  );
+  $form['api_certificate'] = array(
+      '#type' => 'managed_file',
+      '#title' => t('Certificate'),
+      '#upload_location' => 'private://commerce_paypal/wpp/',
+      '#default_value' => $settings['api_certificate'],
+      '#submit' => 'commerce_paypal_wpp_settings_form_api_certificate_submit',
+  );
+  $form['fieldset_suffix'] = array(
+      '#type' => 'markup',
+      '#markup' => '</div></fieldset>',
   );
   $form['server'] = array(
     '#type' => 'radios',
@@ -115,9 +135,28 @@ function commerce_paypal_wpp_settings_form($settings = NULL) {
     ),
     '#default_value' => $settings['log'],
   );
+
   return $form;
 }
 
+/*
+ * Implements hook_process and acts as a form_submit for commerce_paypal_wpp_settings_form.
+ * TODO: J0RD20110818 This needs to get improved, but I'm unsure what hooks are required.
+ */
+function commerce_paypal_wpp_process($variables, $hook) {
+  if($hook == 'process') {
+    if(!empty($variables->settings['payment_method']['method_id']) 
+        && $variables->settings['payment_method']['method_id'] == 'paypal_wpp'
+        && !empty($variables->settings['payment_method']['settings']['api_certificate'])) {
+      $file = file_load($variables->settings['payment_method']['settings']['api_certificate']);
+      if(!empty($file)) {
+        $file->status = FILE_STATUS_PERMANENT;
+        file_save($file);
+      }
+    }
+  }
+}
+
 /**
  * Payment method callback: checkout form.
  */
@@ -327,17 +366,31 @@ function commerce_paypal_wpp_submit_form_submit($payment_method, $pane_form, $pa
  *   The set of name-value pairs describing the transaction to submit.
  */
 function commerce_paypal_wpp_request($payment_method, $nvp = array()) {
+  // Check and see if paypal is configured for signature or certificate authentication
+  $certificate = NULL;
+
+  if(empty($payment_method['settings']['api_signature']) && !empty($payment_method['settings']['api_certificate'])) {
+    $file = file_load($payment_method['settings']['api_certificate']);
+    if(!empty($file)) {
+      $certificate = drupal_realpath($file->uri);
+    }
+  }
+
   // Get the API endpoint URL for the method's transaction mode.
-  $url = commerce_paypal_wpp_server_url($payment_method['settings']['server']);
+  $url = commerce_paypal_wpp_server_url($payment_method['settings']['server'], $certificate);
 
   // Add the default name-value pairs to the array.
   $nvp += array(
     // API credentials
     'USER' => $payment_method['settings']['api_username'],
     'PWD' => $payment_method['settings']['api_password'],
-    'SIGNATURE' => $payment_method['settings']['api_signature'],
     'VERSION' => '76.0',
   );
+  if(!$certificate) {
+    $nvp += array(
+        'SIGNATURE' => $payment_method['settings']['api_signature'],
+        );
+  }
 
   // Allow modules to alter parameters of the API request.
   drupal_alter('commerce_paypal_wpp_request', $nvp);
@@ -347,7 +400,11 @@ function commerce_paypal_wpp_request($payment_method, $nvp = array()) {
     // Mask the credit card number and CVV.
     $log_nvp = $nvp;
     $log_nvp['PWD'] = str_repeat('X', strlen($log_nvp['PWD']));
-    $log_nvp['SIGNATURE'] = str_repeat('X', strlen($log_nvp['SIGNATURE']));
+    
+    // If authentication type is not certificate, set the API signature
+    if(!$certificate) {
+      $log_nvp['SIGNATURE'] = str_repeat('X', strlen($log_nvp['SIGNATURE']));
+    }
 
     if (!empty($log_nvp['ACCT'])) {
       $log_nvp['ACCT'] = str_repeat('X', strlen($log_nvp['ACCT']) - 4) . substr($log_nvp['ACCT'], -4);
@@ -357,7 +414,7 @@ function commerce_paypal_wpp_request($payment_method, $nvp = array()) {
       $log_nvp['CVV2'] = str_repeat('X', strlen($log_nvp['CVV2']));
     }
 
-    watchdog('commerce_paypal', 'PayPal WPP request to @url: !param', array('@url' => $url, '!param' => '<pre>' . check_plain(print_r($log_nvp, TRUE)) . '</pre>'), WATCHDOG_DEBUG);
+    watchdog('commerce_paypal', 'PayPal WPP [@authtype] request to @url: !param', array('@authtype' => $certificate ? 'certificate' : 'signature', '@url' => $url, '!param' => '<pre>' . check_plain(print_r($log_nvp, TRUE)) . '</pre>'), WATCHDOG_DEBUG);
   }
 
   // Prepare the name-value pair array to be sent as a string.
@@ -377,6 +434,12 @@ function commerce_paypal_wpp_request($payment_method, $nvp = array()) {
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
   curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
+
+  // If authentication type is certificate, configure curl appropriately
+  if($certificate) {
+    curl_setopt($ch, CURLOPT_SSLCERT, $certificate);
+  }
+
   $result = curl_exec($ch);
 
   // Log any errors to the watchdog.
@@ -396,7 +459,7 @@ function commerce_paypal_wpp_request($payment_method, $nvp = array()) {
 
   // Log the response if specified.
   if ($payment_method['settings']['log']['response'] == 'response') {
-    watchdog('commerce_paypal', 'PayPal WPP response: !param', array('!param' => '<pre>' . check_plain(print_r($response, TRUE)) . '</pre>', WATCHDOG_DEBUG));
+    watchdog('commerce_paypal', 'PayPal WPP [@authtype] response: !param', array('@authtype' => $certificate ? 'certificate' : 'signature', '!param' => '<pre>' . check_plain(print_r($response, TRUE)) . '</pre>', WATCHDOG_DEBUG));
   }
 
   return $response;
@@ -411,12 +474,22 @@ function commerce_paypal_wpp_request($payment_method, $nvp = array()) {
  * @return
  *   The URL to use to submit requests to the PayPal WPP server.
  */
-function commerce_paypal_wpp_server_url($server) {
-  switch ($server) {
-    case 'sandbox':
-      return 'https://api-3t.sandbox.paypal.com/nvp';
-    case 'live':
-      return 'https:///api-3t.paypal.com/nvp';
+function commerce_paypal_wpp_server_url($server, $certificate = NULL) {
+  if($certificate) {
+    switch ($server) {
+      case 'sandbox':
+        return 'https://api.sandbox.paypal.com/nvp';
+      case 'live':
+        return 'https:///api.paypal.com/nvp';
+    }
+  }
+  else {
+    switch ($server) {
+      case 'sandbox':
+        return 'https://api-3t.sandbox.paypal.com/nvp';
+      case 'live':
+        return 'https:///api-3t.paypal.com/nvp';
+    }
   }
 }
 
