diff --git a/commerce_realex.module b/commerce_realex.module
index e1b86a0..5135af1 100644
--- a/commerce_realex.module
+++ b/commerce_realex.module
@@ -150,17 +150,65 @@ function _commerce_realex_supported_card_types() {
 }
 
 /**
+ * Function to autodetect card type
+ */
+function _commerce_realex_autodetect_card_type($cardnumber) {
+  $type = '';
+
+  if(preg_match("/^5[1-5]/", $cardnumber)) {
+    $type = 'mastercard';
+  }
+  elseif(preg_match("/^401179/", $cardnumber)) { 
+    $type = 'delta';
+  }
+  elseif(preg_match("/^(3713|3797|45443)/", $cardnumber)) {
+    $type = 'delta';
+  }
+  elseif(preg_match("/^(6304|6706|6771|6709)/", $cardnumber)) {
+    $type = 'laser';
+  }
+  elseif (preg_match("/^49/", $cardnumber)) {
+    $type = 'switch';
+  }
+  elseif (preg_match("/^(564182|633110)/", $cardnumber)) {
+    $type = 'switch';
+  }
+  elseif (preg_match("/^(6333|6759)/", $cardnumber)) {
+    $type = 'switch';
+  }
+  elseif (preg_match("/^(6334|6767)/", $cardnumber)) {
+    $type = 'solo';
+  }
+  elseif(preg_match("/^4/", $cardnumber)) { 
+    $type = 'visa';
+  }
+  elseif(preg_match("/^3[4-7]/", $cardnumber)) {
+    $type = 'amex';
+  }
+  elseif(preg_match("/^67/", $cardnumber)) {
+    $type = 'maestro';     
+  }
+  elseif(preg_match("/^(300|305)/", $cardnumber) || 
+    preg_match("/^3[68]/", $cardnumber)) {
+    $type = 'dc';
+  }
+
+  return $type ? $type : 'unknown';
+}
+
+/**
  * Parse the response XML and create and object.
  *
  * Code below is based on sample code provided by Realex at http://resource.realexpayments.com/m.php?ct=integration_oscode.php
  */
 class RealexParser {
 
-   // Initialise variables.
-   var $parser;
-   var $record;
-   var $timestamp;
-   var $field_type;
+  // Initialise variables.
+  var $parser;
+  var $parentElements = array();
+	var $currentElement = 0;
+	var $currentTSSCheck = "";
+	var $record = array();
 
   function RealexParser($response) {
     // Create and initialise XML parser
@@ -169,62 +217,58 @@ class RealexParser {
     xml_set_element_handler($this->parser, 'startElement', 'endElement');
     xml_set_character_data_handler($this->parser, 'cDataHandler');
 
-    // 1 = single field, 2 = array field, 3 = record container
-    $this->field_type = array('response' =>1,
-                              'orderid' => 1,
-                              'authcode' => 1,
-                              'result' => 2,
-                              'message' => 1,
-                              'pasref' => 1,
-                              'batchid' => 1,
-                              'md5hash' => 1,
-                              'sha1hash' => 1,
-                              'cvnresult' => 1,
-                              'dccinfo' => 2,
-                              'cardholdercurrency' => 1,
-                              'cardholderamount' => 1,
-                              'cardholderrate' => 1,
-                              'merchantcurrency' => 1,
-                              'merchantamount' => 1,
-                        );
-
     xml_parse($this->parser, $response);
     xml_parser_free($this->parser);
   }
 
-  /**
-   * The 'startElement()' function is called when an open element tag is found.
-   * It creates a variable on the fly contructed of all the parent elements
-   * joined together with an underscore. So the following xml:
-   * <response><something>Owen</something></response>
-   * would create two variables:  $RESPONSE and $RESPONSE_SOMETHING
-   */
-  function startElement($parser, $element, &$attrs) {
-    $element = strtolower($element);
-      $this->current_field = $element;
+  /* THe "startElement()" function is called when an open element tag is found.
+  It creates a variable on the fly contructed of all the parent elements
+   joined together with an underscore. So the following xml:
+
+   <response><something>Owen</something></response>
+   would create two variables:
+   $RESPONSE and $RESPONSE_SOMETHING
+  */
+  function startElement($parser, $name, $attrs) {
+    $name = strtolower($name);
+  	array_push($this->parentElements, $name);
+  	$this->currentElement = join("_", $this->parentElements);
+
+  	foreach ($attrs as $attr => $value) {
+      if ($this->currentElement == "response_tss_check" and $attr == "ID") {
+        $this->currentTSSCheck = $value;
+      }
 
-    if ($element == 'response' && $attrs['TIMESTAMP']) {
-      $this->record['timestamp'] = $attrs['TIMESTAMP'];
+      if ($this->currentElement == 'response' and $attr == "TIMESTAMP") {
+        $this->record['timestamp'] = $value;
+      }
     }
+
+    // Clean up the element names to remove the response_ prefix.
+    $this->currentElement = str_replace('response_', '', $this->currentElement);
   }
 
-  function endElement($parser, $element) {
-    $element = strtolower($element);
-    // $this->current_field = '';
+  /* The "cDataHandler()" function is called when the parser encounters any text that's
+     not an element. Simply places the text found in the variable that
+     was last created. So using the XML example above the text "Owen"
+     would be placed in the variable $RESPONSE_SOMETHING
+  */
+  function cDataHandler($parser, $cdata) {
+  	if ( trim ( $cdata ) ) {
+  		if ($this->currentTSSCheck != 0) {
+  			$this->record['tsschecks']["$this->currentTSSCheck"] = $cdata;
+  		}
+
+  		$this->record[$this->currentElement] = $cdata;
+  	}
   }
 
-  /**
-   * The 'cDataHandler()' function is called when the parser encounters any text that's
-   * not an element. Simply places the text found in the variable that
-   * was last created. So using the XML example above the text 'Owen'
-   * would be placed in the variable $RESPONSE_SOMETHING
-   */
-  function cDataHandler($parser, $text) {
-    if ($text != ' ') {
-      if (!empty($this->current_field)) {
-        $this->record[$this->current_field] = $text;
-      }
-    }
+  //  The "endElement()" function is called when the closing tag of an element is found.
+  //  Just removes that element from the array of parent elements.
+  function endElement($parser, $name) {
+  	$this->currentTSSCheck = 0;
+  	array_pop($this->parentElements);
   }
+
 }
 
diff --git a/commerce_realex_remote.inc b/commerce_realex_remote.inc
index 215ce3f..fdc85d6 100644
--- a/commerce_realex_remote.inc
+++ b/commerce_realex_remote.inc
@@ -86,6 +86,12 @@ function commerce_realex_remote_commerce_payment_method_settings_form($settings
     '#required' => TRUE,
   );
 
+  $form['card_types_autodetect'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Autodetect card type'),
+    '#default_value' => isset($settings['card_types_autodetect']) ? $settings['card_types_autodetect'] : FALSE,
+  );
+
   $form['cctype_subaccounts_enabled'] = array(
     '#type' => 'checkbox',
     '#title' => t('Use separate accounts for each card type'),
@@ -137,6 +143,11 @@ function commerce_realex_remote_commerce_payment_method_submit_form($payment_met
     'code' => '',
   );
 
+  //Add autodetect card.
+  if ($payment_method['settings']['card_types_autodetect']) {
+    unset($credit_card_settings['type']);
+  }
+
   // Get credit card fields.
   $form = commerce_payment_credit_card_form($credit_card_settings);
 
@@ -156,7 +167,12 @@ function commerce_realex_remote_commerce_payment_method_submit_form_validate($pa
   );
   $prefix = implode('][', $settings['form_parents']) . '][';
 
-  $card_type = $pane_values['credit_card']['type'];
+  if ($payment_method['settings']['card_types_autodetect']) {
+    $card_type = _commerce_realex_autodetect_card_type($pane_values['credit_card']['number']);
+  }
+  else {
+    $card_type = $pane_values['credit_card']['type'];
+  }
   if ($card_type == 'switch') {
     if (empty($pane_values['credit_card']['issue'])) {
       form_set_error($prefix . 'issue', t('Issue number field is required.'));
@@ -203,13 +219,20 @@ function commerce_realex_remote_commerce_payment_method_submit_form_submit($paym
   //$request['dcc_provider'] = $payment_method['settings']['dcc_provider'];
 
   $request['chname'] = $pane_values['credit_card']['owner'];
-  $request['cctype'] = _commerce_realex_get_card_type($pane_values['credit_card']['type']);
   $request['ccnumber'] = $pane_values['credit_card']['number'];
   $request['cvn'] = isset($pane_values['credit_card']['code']) ? $pane_values['credit_card']['code'] : NULL;
   $request['issueno'] = isset($pane_values['credit_card']['issue']) ? $pane_values['credit_card']['issue'] : '';
   $request['start_date'] = $start_date;
   $request['expiry_date'] = $expiry_date;
 
+  //Auto detect type
+  if ($payment_method['settings']['card_types_autodetect']) {
+    $request['cctype'] = _commerce_realex_get_card_type(_commerce_realex_autodetect_card_type($pane_values['credit_card']['number'])); 
+  }
+  else {
+    $request['cctype'] = _commerce_realex_get_card_type($pane_values['credit_card']['type']);
+  }
+
   // Sub-accounts can differ by card type
   if ($payment_method['settings']['cctype_subaccounts_enabled']) {
     $subaccount = $payment_method['settings']['cctype_accounts'][$pane_values['credit_card']['type']];
@@ -331,7 +354,13 @@ function commerce_realex_remote_get_dcc_offer($payment_method, $pane_values, &$o
   $request['dcc_provider'] = $payment_method['settings']['dcc_provider'];
 
   $request['chname'] = $pane_values['credit_card']['owner'];
-  $request['cctype'] = _commerce_realex_get_card_type($pane_values['credit_card']['type']);
+  //Auto detect type
+  if ($payment_method['settings']['card_types_autodetect']) {
+    $request['cctype'] = _commerce_realex_autodetect_card_type($pane_values['credit_card']['number']);
+  }
+  else {
+    $request['cctype'] = _commerce_realex_get_card_type($pane_values['credit_card']['type']);
+  }
   $request['ccnumber'] = $pane_values['credit_card']['number'];
   $request['cvn'] = isset($pane_values['credit_card']['code']) ? $pane_values['credit_card']['code'] : NULL;
   $request['issueno'] = isset($pane_values['credit_card']['issue']) ? $pane_values['credit_card']['issue'] : '';
