diff --git a/tupas_registration.module b/tupas_registration.module
index 6677e10..c7dd496 100644
--- a/tupas_registration.module
+++ b/tupas_registration.module
@@ -335,29 +335,32 @@ function tupas_registration_return_rej($transaction_id = '') {
  */
 function tupas_registration_solve_hash($bank_id, $transaction_id = '') {
 
-  $rcv_key = db_query("SELECT rcv_key FROM {tupas_bank} WHERE id = :id", array(':id' => array($bank_id)))->fetchField();;
-
-  $macstring = '';
-
-  foreach ($_GET as $key => $value) {
-    // Drop q and the bank's MAC from the string.
-    if ($key != 'q' && $key != 'B02K_MAC') {
-      $macstring .= $value . '&';
+  $rcv_key = db_query("SELECT rcv_key FROM {tupas_bank} WHERE id = :id", array(':id' => array($bank_id)))->fetchField();
+
+  $macstring = array();
+
+  $mac_order = array(
+    'B02K_VERS',
+    'B02K_TIMESTMP',
+    'B02K_IDNBR',
+    'B02K_STAMP',
+    'B02K_CUSTNAME',
+    'B02K_KEYVERS',
+    'B02K_ALG',
+    'B02K_CUSTID',
+    'B02K_CUSTTYPE',
+  );
+  foreach ($mac_order as $key) {
+    if (!isset($_GET[$key])) {
+      continue;
     }
+    $macstring[] = $_GET[$key];
   }
+  // Append rcv key to mac.
+  $macstring[] = $rcv_key;
+  $macstring = implode('&', $macstring) . '&';
 
-  $macstring .= $rcv_key . '&';
-
-  // Calculate the MAC based on the encryption algorithm.
-  if ($_GET['B02K_ALG'] == 01) {
-    $mac = strtoupper(md5($macstring));
-  }
-  elseif ($_GET['B02K_ALG'] == 03) {
-    $mac = strtoupper(hash('sha256', $macstring));
-  }
-  else {
-    $mac = strtoupper(sha1($macstring));
-  }
+  $mac = tupas_registration_hash_mac($_GET['B02K_ALG'], $macstring);
 
   // If the MACs match.
   if ($_GET['B02K_MAC'] == $mac && variable_get('tupas_session_length', 30) != 0 && $transaction_id) {
@@ -384,6 +387,27 @@ function tupas_registration_active_session($transaction_id) {
 }
 
 /**
+ * Generate mac hash.
+ *
+ * @param $encryption_alg
+ * @param $mac_string
+ * @return string
+ */
+function tupas_registration_hash_mac($encryption_alg, $mac_string) {
+  // Calculate the MAC based on the encryption algorithm.
+  if ($encryption_alg == 01) {
+    $mac = strtoupper(md5($mac_string));
+  }
+  elseif ($encryption_alg == 03) {
+    $mac = strtoupper(hash('sha256', $mac_string));
+  }
+  else {
+    $mac = strtoupper(sha1($mac_string));
+  }
+  return $mac;
+}
+
+/**
  * Builds form with hidden fields and their values according to the bank data.
  *
  * @param array $form_state
@@ -489,15 +513,7 @@ function tupas_registration_bank_form($form, &$form_state, $bank, $transaction_i
   $macstring = "701&{$bank->cert_version}&{$bank->rcv_id}&FI&$stamp&$idtype&$retlink&$canlink&$rejlink&{$bank->keyvers}&{$bank->encryption_alg}&{$bank->rcv_key}&";
 
   // Calculate the MAC based on the encryption algorithm.
-  if ($bank->encryption_alg == 01) {
-    $mac = strtoupper(md5($macstring));
-  }
-  elseif ($bank->encryption_alg == 03) {
-    $mac = strtoupper(hash('sha256', $macstring));
-  }
-  else {
-    $mac = strtoupper(sha1($macstring));
-  }
+  $mac = tupas_registration_hash_mac($bank->encryption_alg, $macstring);
 
   // MAC.
   $form['A01Y_MAC'] = array(
diff --git a/tupas_registration.test b/tupas_registration.test
index b673f7f..4f7461b 100644
--- a/tupas_registration.test
+++ b/tupas_registration.test
@@ -68,4 +68,56 @@ class TupasRegistrationTests extends DrupalWebTestCase {
 
     return $ssn;
   }
+
+  /**
+   * Make sure that mac calculation is same regardless of what order url arguments
+   * were given.
+   */
+  public function testHashCalculation() {
+    $bank = db_query('SELECT * FROM {tupas_bank} WHERE id = 1')->fetchObject();
+    $transaction_id = rand(100000, 999999);
+
+    $_GET = $this->generateBankMac($bank, $transaction_id);
+    $ret = tupas_registration_solve_hash($bank->id, $transaction_id);
+    $this->assertTrue(!empty($ret['B02K_VERS']), 'Returned correct mac');
+
+    // Reverse array to test if we get same results.
+    $_GET = array_reverse($_GET);
+    $ret = tupas_registration_solve_hash($bank->id, $transaction_id);
+    $this->assertTrue(!empty($ret['B02K_VERS']), 'Returned correct mac when reversing url arguments');
+
+    // Make sure mac validation fails when missing required values.
+    unset($_GET['B02K_IDNBR']);
+    $ret = tupas_registration_solve_hash($bank->id, $transaction_id);
+    $this->assertFalse($ret, 'Returned invalid mac');
+  }
+
+  /**
+   * Generates bank mac.
+   */
+  protected function generateBankMac($bank, $transaction_id) {
+    $macstring = array();
+    $return_values = array(
+      'B02K_VERS' => $bank->cert_version,
+      'B02K_TIMESTMP' => 12345678,
+      'B02K_IDNBR' => 123456,
+      'B02K_STAMP' => date('YmdHis') . $transaction_id,
+      'B02K_CUSTNAME' => $this->randomName(),
+      'B02K_KEYVERS' => $bank->keyvers,
+      'B02K_ALG' => $bank->encryption_alg,
+      'B02K_CUSTID' => rand(1000, 2000),
+      'B02K_CUSTTYPE' => '01',
+    );
+    foreach ($return_values as $value) {
+      $macstring[] = $value;
+    }
+    // Append rcv key to mac.
+    $macstring[] = $bank->rcv_key;
+    $macstring = implode('&', $macstring) . '&';
+
+    // Calculate the MAC based on the encryption algorithm.
+    $return_values['B02K_MAC'] = tupas_registration_hash_mac($bank->encryption_alg, $macstring);
+
+    return $return_values;
+  }
 }
