diff --git a/sites/all/modules/commerce_paybox/commerce_paybox.module b/sites/all/modules/commerce_paybox/commerce_paybox.module
index 985bffd..22aec17 100644
--- a/sites/all/modules/commerce_paybox/commerce_paybox.module
+++ b/sites/all/modules/commerce_paybox/commerce_paybox.module
@@ -229,51 +229,85 @@ function commerce_paybox_offsite_redirect_form($form, &$form_state, $order, $pay
   // Allow other modules to alter Paybox CGI module parameters.
   drupal_alter('commerce_paybox_offsite_params', $pbx_params, $order, $settings);
 
-  // Paybox mode and output must not be altered. Mode 4 is "command line" mode,
-  // output D is "output only PXB_DATA".
-  $pbx_params['PBX_MODE'] = 4;
-  $pbx_params['PBX_OUTPUT'] = 'D';
-
-  // Construct the command line.
-  $bin_params = '';
-  foreach ($pbx_params as $name => $value) {
-    $safe_value = escapeshellarg($value);
-    $bin_params .= " $name=$safe_value";
-  }
-  $bin_path = variable_get('commerce_paybox_cgi_module_path', '');
-  $cmd = DRUPAL_ROOT . '/' . $bin_path . $bin_params;
-
-  // Execute the command line : returns PBX_DATA value.
-  $output = trim(shell_exec($cmd));
-
-  $matches = array();
-  if (empty($output) || preg_match('#PAYBOX INPUT ERROR \(code (-[0-9]*?)\)#ism', $output, $matches)) {
-    // Something goes wrong with GCI execution...
-    $form['error'] = array(
-      '#type' => 'item',
-      '#title' => t('Error'),
-      '#markup' => t('Paybox module initialisation failed.'),
-    );
+  // If no hmac key, use cgi module
+  if (variable_get('commerce_paybox_hmac_key','') == '') {
+    // Paybox mode and output must not be altered. Mode 4 is "command line" mode,
+    // output D is "output only PXB_DATA".
+    $pbx_params['PBX_MODE'] = 4;
+    $pbx_params['PBX_OUTPUT'] = 'D';
+
+    // Construct the command line.
+    $bin_params = '';
+    foreach ($pbx_params as $name => $value) {
+      $safe_value = escapeshellarg($value);
+      $bin_params .= " $name=$safe_value";
+    }
+    $bin_path = variable_get('commerce_paybox_cgi_module_path', '');
+    $cmd = DRUPAL_ROOT . '/' . $bin_path . $bin_params;
+
+    // Execute the command line : returns PBX_DATA value.
+    $output = trim(shell_exec($cmd));
+
+    $matches = array();
+    if (empty($output) || preg_match('#PAYBOX INPUT ERROR \(code (-[0-9]*?)\)#ism', $output, $matches)) {
+      // Something goes wrong with GCI execution...
+      $form['error'] = array(
+        '#type' => 'item',
+        '#title' => t('Error'),
+        '#markup' => t('Paybox module initialisation failed.'),
+      );
 
-    // Log the error.
-    $log = 'Paybox CGI module execution has failed : error @code (shell command: "!cmd").';
-    $log_vars = array(
-      '@code' => $matches[1],
-      '!cmd' => $cmd,
-    );
-    $link = l(t('View transaction'), "admin/commerce/orders/$txn->order_id/payment/$txn->transaction_id/view");
-    watchdog('commerce_paybox', $log, $log_vars, WATCHDOG_ERROR, $link);
+      // Log the error.
+      $log = 'Paybox CGI module execution has failed : error @code (shell command: "!cmd").';
+      $log_vars = array(
+        '@code' => $matches[1],
+        '!cmd' => $cmd,
+      );
+      $link = l(t('View transaction'), "admin/commerce/orders/$txn->order_id/payment/$txn->transaction_id/view");
+      watchdog('commerce_paybox', $log, $log_vars, WATCHDOG_ERROR, $link);
 
-    return $form;
+      // Create hidden inputs from $pbx_params.
+      $pbx_params['PBX_DATA'] = $output;
+    }
+  }
+  else {
+    // here it is the 'HMAC case'
+    $pbx_params['PBX_HASH'] = variable_get('commerce_paybox_hmac_alg','SHA512');
+    // ISO-8601 datetime
+    $dateTime = date("c");
+    $pbx_params['PBX_TIME'] = $dateTime;
+
+    $form['#pre_render'][] = 'commerce_paybox_hmac_clean_form';
+
+    // disable form_token (target isn't ourselves)
+    $form['#token'] = FALSE;
+
+    // build of the string to hash matching POST's content
+    // used to generate PBX_HASH (except PBX_HASH of course)
+    $msg='';
+    foreach( $pbx_params as $k => $v) {
+      $msg .= $k."=".$v."&";
+    }
+    $msg = rtrim($msg,'&');
+
+    // code as paybox's example to generate HMAC key
+    $keyTest = variable_get('commerce_paybox_hmac_key','');
+    $binKey = pack("H*", $keyTest);
+    $hash = strtolower($pbx_params['PBX_HASH']);
+    $hmac = strtoupper(hash_hmac($hash, $msg, $binKey));
+    $pbx_params['PBX_HMAC'] = $hmac;
   }
 
-  // Create hidden inputs from $pbx_params.
-  $pbx_params['PBX_DATA'] = $output;
+  // order of the fiels NEEDS to be kept between form and
+  // hashed string: forcing #weight
+  $pbx_weight=0.01;
   foreach ($pbx_params as $name => $value) {
     $form[$name] = array(
       '#type' => 'hidden',
       '#value' => $value,
+      '#weight' => $pbx_weight,
     );
+    $pbx_weight=$pbx_weight+0.01;
   }
 
   $form['image'] = array(
@@ -294,7 +328,23 @@ function commerce_paybox_offsite_redirect_form($form, &$form_state, $order, $pay
   else {
     $form['#action'] = PAYBOX_URL;
   }
+  return $form ;
 
+
+}
+
+/**
+ * callback for cleaning form in the HMAC case
+ *
+ * removes drupal's specific form_id, form_build_id, form_token and submit's value
+ * from client's POST to paybox's servers
+ */
+function commerce_paybox_hmac_clean_form($form) {
+  // strip drupal's elements from form
+  unset($form['form_token']);
+  unset($form['form_build_id']);
+  unset($form['form_id']);
+  $form['submit']['#name']='';
   return $form;
 }
 
diff --git a/sites/all/modules/commerce_paybox/includes/commerce_paybox.admin.inc b/sites/all/modules/commerce_paybox/includes/commerce_paybox.admin.inc
index b56aa95..50215c2 100644
--- a/sites/all/modules/commerce_paybox/includes/commerce_paybox.admin.inc
+++ b/sites/all/modules/commerce_paybox/includes/commerce_paybox.admin.inc
@@ -16,6 +16,8 @@ function commerce_paybox_settings($form, &$form_state) {
   $rule_commerce_payment_paybox = rules_config_load('commerce_payment_paybox_offsite');
 
   $cgi_module_path = variable_get('commerce_paybox_cgi_module_path', '');
+  $hmac_key = variable_get('commerce_paybox_hmac_key', '');
+  $hmac_alg = variable_get('commerce_paybox_hmac_alg', 'SHA512');
   if ($rule_commerce_payment_paybox->active) {
     $bin_path = DRUPAL_ROOT . '/' . $cgi_module_path;
     if (is_file($bin_path) && !is_executable($bin_path)) {
@@ -31,11 +33,33 @@ function commerce_paybox_settings($form, &$form_state) {
     );
   }
 
+  // Paybox key
+  $form['commerce_paybox_hmac_key'] = array(
+    '#type' => 'textfield',
+    '#size' => '128',
+    '#title' => t('Paybox private key'),
+    '#description' => t('Private key generated on paybox\'s admin interface (see ManuelIntegrationPayboxSystem_V5.08_FR.pdf)'),
+    '#default_value' => $hmac_key,
+  );
+
+  // paybox key's algorithm
+  $form['commerce_paybox_hmac_alg'] = array(
+    '#type' => 'select',
+    '#title' => t('Algorithm to use with HMAC method'),
+    '#description' => t('Select algorithm from allowed list (SHA512 by default)'),
+    '#options' => array('SHA512' => 'SHA512',
+                        'SHA256' => 'SHA256',
+                        'SHA384' => 'SHA384',
+                        'RIPEMD160' => 'RIPEMD160',
+                        'SHA224' => 'SHA224',
+                        'MDC2' => 'MDC2'),
+    '#default' => $hmac_alg,
+  );
+
   // Path to the CGI module.
   $form['commerce_paybox_cgi_module_path'] = array(
     '#type' => 'textfield',
-    '#required' => $rule_commerce_payment_paybox->active,
-    '#title' => t('Path to the Paybox System CGI module'),
+    '#title' => t('Path to the Paybox System CGI module (if not using HMAC key, which is recommended)'),
     '#description' => t('Path to the Paybox CGI module, relative to the drupal root filesystem (ex : sites/all/libraries/paybox/module_debian64bits_noyau2-6-18_libc2-3-6.cgi).'),
     '#default_value' => $cgi_module_path,
   );
@@ -67,10 +91,18 @@ function commerce_paybox_settings($form, &$form_state) {
 function commerce_paybox_settings_validate($form, &$form_state) {
   $form_state['values']['commerce_paybox_cgi_module_path'] = trim($form_state['values']['commerce_paybox_cgi_module_path'], '/');
 
-  $cgi_module_path = $form_state['values']['commerce_paybox_cgi_module_path'];
-  if (!is_file(DRUPAL_ROOT . '/' . $cgi_module_path)) {
-    $message = t('File "@path" could not be found on the server.', array('@path' => $cgi_module_path));
-    form_set_error('commerce_paybox_cgi_module_path', $message);
+  $hmac_key = $form_state['values']['commerce_paybox_hmac_key'];
+  if ($hmac_key == '') {
+    $cgi_module_path = $form_state['values']['commerce_paybox_cgi_module_path'];
+    if (!is_file(DRUPAL_ROOT . '/' . $cgi_module_path)) {
+      $message = t('No HMAC key defined, which is the preferred method for paybox');
+      form_set_error('commerce_paybox_hmac_key',$message);
+      $message = t('File "@path" could not be found on the server.', array('@path' => $cgi_module_path));
+      form_set_error('commerce_paybox_cgi_module_path', $message);
+    }
+  }
+  else {
+    $form_state['values']['commerce_paybox_hmac_key'] = preg_replace('/\n/','',$form_state['values']['commerce_paybox_hmac_key']);
   }
 
   $pubkey_path = $form_state['values']['commerce_paybox_pubkey_path'];
