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:
- * Owen
- * 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:
+
+ Owen
+ 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'] : '';