From Md5 To Sha256

Hello,

the bank informed us that we should migrate our payment gateway from Md5 to SHA256, could you please help us to do it? we are using the following code:

if ( !defined(‘AREA’) ) { die(‘Access denied’); }

if (defined(‘PAYMENT_NOTIFICATION’)) {

$payment_id = db_get_field("SELECT payment_id FROM ?:orders WHERE order_id = ?i", $_REQUEST['order_id']);
$processor_data = fn_get_payment_method_data($payment_id);

switch ($_REQUEST['vpc_TxnResponseCode']) {
	case '0':
		$pp_response['order_status'] = 'P';
		break;
	case 'C':
		$pp_response['order_status'] = 'C';
		break;
	case '7':
		$pp_response['order_status'] = 'F';
		break;
	default:
		$pp_response['order_status'] = 'D';
		break;
}

$pp_response['reason_text'] = $_REQUEST['vpc_Message'];
$pp_response['transaction_id'] = $_REQUEST['vpc_TransactionNo'];

if (fn_check_payment_script('zienthbank.php', $_REQUEST['order_id'])) {
	fn_finish_payment($_REQUEST['order_id'], $pp_response, false);
	fn_order_placement_routines('route', $_REQUEST['order_id']);
}

exit;

} else {
$current_location = Registry::get(‘config.current_location’);
$total = $order_info[‘total’] * 100;

$post['vpc_Version'] = '1';
$post['vpc_Command'] = 'pay';
$post['vpc_MerchTxnRef'] = $order_id;
$post['vpc_AccessCode'] = $processor_data['processor_params']['accesscode'];
$post['vpc_Merchant'] = $processor_data['processor_params']['merchant'];
$post['vpc_OrderInfo'] = $order_id;
$post['vpc_Amount'] = $total;
$post['vpc_Locale'] = "en_EN";
$post['vpc_ReturnURL'] = "$current_location/$index_script?dispatch=payment_notification.finish&payment=zienthbank&order_id=$order_id";

ksort($post);

$md5hash = $processor_data['processor_params']['securehashsecret'];

foreach ($post as $k => $v) {
	$md5hash .= $v;
}

$post['vpc_SecureHash'] = strtoupper(md5($md5hash));

// MasterCard Payment Gateway
echo << EOT;

foreach ($post as $name => $value) {
echo “\n”;
}

$msg = fn_get_lang_var(‘text_cc_processor_connection’);
$msg = str_replace(‘[processor]’, ‘migs.mastercard.com.au’, $msg);
echo <<

{$msg}

EOT;

}

exit;
?>

Try to replace

$post['vpc_SecureHash'] = strtoupper(md5($md5hash));

with

$post['vpc_SecureHash'] = strtoupper(hash('sha256', $md5hash));

and check the result

Try to replace

$post['vpc_SecureHash'] = strtoupper(md5($md5hash));

with

$post['vpc_SecureHash'] = strtoupper(hash('sha256', $md5hash));

and check the result

i got this error:

HTTP Status - 400

E5000: Cannot form a matching secure hash based on the merchant's request using either of the two merchant's secrets

i got this error:
HTTP Status - 400
E5000: Cannot form a matching secure hash based on the merchant's request using either of the two merchant's secrets

In this case it is required to request more details from the bank

In this case it is required to request more details from the bank

Hello,

i have received the following detailed from the bank:

Example
An example using PHP coding language to change from MD5 Hash to SHA 256 is shown below:

Step 1: Create string with transaction data via the merchant application.

Example PHP Code:
foreach($_POST as $key => $value) {
// create the hash input and URL leaving out any fields that have no value
if (strlen($value) > 0) {

?>

0) && ((substr($key, 0,4)=="vpc_") || (substr($key,0,5) =="user_"))) { $hashinput .= $key . "=" . $value . "&"; } } Example String Code Generated: user_SessionId=567890&vpc_AccessCode=75A6GH9&vpc_Amount=1000&vpc_CardExp=1305&vpc_CardNum=345678901234564&vpc_Command=pay&vpc_MerchTxnRef=txn1&vpc_Merchant=MasterCard ITESTMERCHANT&vpc_Version=1 Step 2: Create SHA-256 HMAC • Obtain Secure Hash Secret either from existing MD5 calculation or from Merchant Administration • Calculate SHA-256 HMAC using the secret as a key to produce the secure hash • Add the hash to the request string to send to the gateway Example PHP Code: } $hashinput = rtrim($hashinput, "&"); ?>


Example SHA-256 HMAC Generated:
The Secure Hash Secret obtained from Merchant Administration/ Existing MD5 calculation :
3812B7C7D21726AAC9633E1D42BD43A73A329F8906C248EFAF9CEC354F8B0C08

Calculate SHA256 HMAC using the secret as a key to produce the secure hash:
7C6866D0B1DF14FE03FA4168F3328C2D33E192E7 CA5D08F5D4533F044A866D41

Add the hash to the request string to send to the gateway:
user_SessionId=567890&vpc_AccessCode=75A6GH9&vpc_Amount=1000&vpc_CardExp=1305&vpc_CardNum=345678901234564&vpc_Command=pay&vpc_MerchTxnRef=txn1&vpc_Merchant=MasterCardITESTMERCHANT&vpc_Version=1&vpc_SecureHash=7C6866D0B1DF14FE03FA4168F3328C2D33E192E7 CA5D08F5D4533F044A866D41&vpc_SecureHashType=SHA256

so i modified the code as below:

if ( !defined(‘AREA’) ) { die(‘Access denied’); }

if (defined(‘PAYMENT_NOTIFICATION’)) {

$payment_id = db_get_field("SELECT payment_id FROM ?:orders WHERE order_id = ?i", $_REQUEST['order_id']);
$processor_data = fn_get_payment_method_data($payment_id);

switch ($_REQUEST['vpc_TxnResponseCode']) {
	case '0':
		$pp_response['order_status'] = 'P';
		break;
	case 'C':
		$pp_response['order_status'] = 'C';
		break;
	case '7':
		$pp_response['order_status'] = 'F';
		break;
	default:
		$pp_response['order_status'] = 'D';
		break;
}

$pp_response['reason_text'] = $_REQUEST['vpc_Message'];
$pp_response['transaction_id'] = $_REQUEST['vpc_TransactionNo'];

if (fn_check_payment_script('zienthbank.php', $_REQUEST['order_id'])) {
	fn_finish_payment($_REQUEST['order_id'], $pp_response, false);
	fn_order_placement_routines('route', $_REQUEST['order_id']);
}

exit;

} else {
$current_location = Registry::get(‘config.current_location’);
$total = $order_info[‘total’] * 100;

$post['vpc_Version'] = '1';
$post['vpc_Command'] = 'pay';
$post['vpc_MerchTxnRef'] = $order_id;
$post['vpc_AccessCode'] = $processor_data['processor_params']['accesscode'];
$post['vpc_Merchant'] = $processor_data['processor_params']['merchant'];
$post['vpc_OrderInfo'] = $order_id;
$post['vpc_Amount'] = $total;
$post['vpc_Locale'] = "en_EN";
$post['vpc_ReturnURL'] = "$current_location/$index_script?dispatch=payment_notification.finish&payment=zienthbank&order_id=$order_id";

ksort($post);

//$hashinput = $processor_data['processor_params']['securehashsecret'];
$secureSecret = $processor_data['processor_params']['securehashsecret'];

//foreach ($post as $k => $v) {
//	$md5hash .= $v;
//}

foreach ($post as $k => $v) {
// create the hash input and URL leaving out any fields that have no value
if (strlen($v) > 0) {

?>

0) && ((substr($k, 0,4)=="vpc_") || (substr($k,0,5) =="user_"))) { $hashinput .= $k . "=" . $v . "&"; } } $hashinput = rtrim($hashinput, "&"); ?>


$value) { // echo "\n"; //} $msg = fn_get_lang_var('text_cc_processor_connection'); $msg = str_replace('[processor]', 'migs.mastercard.com.au', $msg); echo <<{$msg}
EOT; } exit; ?>

but still getting the same error.

Please try


/***************************************************************************

  •                                                                      *
    
  • Copyright (c) 2004 Simbirsk Technologies Ltd. All rights reserved. *
  •                                                                      *
    
  • This is commercial software, only users who have purchased a valid *
  • license and accept to the terms of the License Agreement can install *
  • and use this program. *
  •                                                                      *
    

  • PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
  • “copyright.txt” FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
    ****************************************************************************/
    use Tygh\Registry;

if ( !defined(‘AREA’) ) { die(‘Access denied’); }

if (defined(‘PAYMENT_NOTIFICATION’)) {

$payment_id = db_get_field("SELECT payment_id FROM ?:orders WHERE order_id = ?i", $_REQUEST['order_id']);
$processor_data = fn_get_payment_method_data($payment_id);

switch ($_REQUEST['vpc_TxnResponseCode']) {
	case '0':
		$pp_response['order_status'] = 'P';
		break;
	case 'C':
		$pp_response['order_status'] = 'C';
		break;
	case '7':
		$pp_response['order_status'] = 'F';
		break;
	default:
		$pp_response['order_status'] = 'D';
		break;
}

$pp_response['reason_text'] = $_REQUEST['vpc_Message'];
$pp_response['transaction_id'] = $_REQUEST['vpc_TransactionNo'];

if (fn_check_payment_script('zienthbank.php', $_REQUEST['order_id'])) {
	fn_finish_payment($_REQUEST['order_id'], $pp_response, false);
	fn_order_placement_routines('route', $_REQUEST['order_id']);
}

exit;

} else {
$current_location = Registry::get(‘config.current_location’);
$total = $order_info[‘total’] * 100;

$post['vpc_Version'] = '1';
$post['vpc_Command'] = 'pay';
$post['vpc_MerchTxnRef'] = $order_id;
$post['vpc_AccessCode'] = $processor_data['processor_params']['accesscode'];
$post['vpc_Merchant'] = $processor_data['processor_params']['merchant'];
$post['vpc_OrderInfo'] = $order_id;
$post['vpc_Amount'] = $total;
$post['vpc_Locale'] = "en_EN";
$post['vpc_ReturnURL'] = "$current_location/$index_script?dispatch=payment_notification.finish&payment=zienthbank&order_id=$order_id";

ksort($post);

$hashinput = '';

foreach ($post as $k => $v) {
            if ((strlen($v) > 0) && ((substr($k, 0,4)=="vpc_") || (substr($k,0,5) =="user_"))) {
	    $hashinput .= $k . "=" . $v . "&";
            }
}

$post['vpc_SecureHash'] = strtoupper(hash_hmac('SHA256', $hashinput, pack('H*',$processor_data['processor_params']['securehashsecret'])));
    $post['vpc_SecureHashType'] = 'SHA256';

// MasterCard Payment Gateway
echo << EOT;

foreach ($post as $name => $value) {
echo “\n”;
}

$msg = fn_get_lang_var(‘text_cc_processor_connection’);
$msg = str_replace(‘[processor]’, ‘migs.mastercard.com.au’, $msg);
echo <<

{$msg}

EOT;

}

exit;
?>

Please try

if ( !defined(‘AREA’) ) { die(‘Access denied’); }

if (defined(‘PAYMENT_NOTIFICATION’)) {

$payment_id = db_get_field("SELECT payment_id FROM ?:orders WHERE order_id = ?i", $_REQUEST['order_id']);
$processor_data = fn_get_payment_method_data($payment_id);

switch ($_REQUEST['vpc_TxnResponseCode']) {
	case '0':
		$pp_response['order_status'] = 'P';
		break;
	case 'C':
		$pp_response['order_status'] = 'C';
		break;
	case '7':
		$pp_response['order_status'] = 'F';
		break;
	default:
		$pp_response['order_status'] = 'D';
		break;
}

$pp_response['reason_text'] = $_REQUEST['vpc_Message'];
$pp_response['transaction_id'] = $_REQUEST['vpc_TransactionNo'];

if (fn_check_payment_script('zienthbank.php', $_REQUEST['order_id'])) {
	fn_finish_payment($_REQUEST['order_id'], $pp_response, false);
	fn_order_placement_routines('route', $_REQUEST['order_id']);
}

exit;

} else {
$current_location = Registry::get(‘config.current_location’);
$total = $order_info[‘total’] * 100;

$post['vpc_Version'] = '1';
$post['vpc_Command'] = 'pay';
$post['vpc_MerchTxnRef'] = $order_id;
$post['vpc_AccessCode'] = $processor_data['processor_params']['accesscode'];
$post['vpc_Merchant'] = $processor_data['processor_params']['merchant'];
$post['vpc_OrderInfo'] = $order_id;
$post['vpc_Amount'] = $total;
$post['vpc_Locale'] = "en_EN";
$post['vpc_ReturnURL'] = "$current_location/$index_script?dispatch=payment_notification.finish&payment=zienthbank&order_id=$order_id";

ksort($post);

$hashinput = '';

foreach ($post as $k => $v) {
            if ((strlen($v) > 0) && ((substr($k, 0,4)=="vpc_") || (substr($k,0,5) =="user_"))) {
	    $hashinput .= $k . "=" . $v . "&";
            }
}

$post['vpc_SecureHash'] = strtoupper(hash_hmac('SHA256', $hashinput, pack('H*',$processor_data['processor_params']['securehashsecret'])));
    $post['vpc_SecureHashType'] = 'SHA256';

// MasterCard Payment Gateway
echo << EOT;

foreach ($post as $name => $value) {
echo “\n”;
}

$msg = fn_get_lang_var(‘text_cc_processor_connection’);
$msg = str_replace(‘[processor]’, ‘migs.mastercard.com.au’, $msg);
echo <<

{$msg}

EOT;

}

exit;
?>

Thank you for your response.

i got this error:

HTTP Status - 400

E5000: Cannot form a matching secure hash based on the merchant's request using either of the two merchant's secrets

Thank you for your response.

i got this error:

HTTP Status - 400
E5000: Cannot form a matching secure hash based on the merchant's request using either of the two merchant's secrets

Please make sure that the correct key is used. I do not see any issues in the code

Please make sure that the correct key is used. I do not see any issues in the code

Hello,

finally it is working now, but when payment is finished, i get this message: "Important Transaction was canceled by the customer" and order is not placed on the website. i checked the &vpc_TxnResponseCode=0 .

please advice.

Hello,

finally it is working now, but when payment is finished, i get this message: "Important Transaction was canceled by the customer" and order is not placed on the website. i checked the &vpc_TxnResponseCode=0 .

please advice.

What status do you see for these orders in the admin panel?

What status do you see for these orders in the admin panel?

order status is "incomplete", i checked the database via phpmyadmin and i found the order and its status was set to 'N'.

order status is "incomplete", i checked the database via phpmyadmin and i found the order and its status was set to 'N'.

It means that the response is not received to the URL specified in the vpc_ReturnURL parameter

It means that the response is not received to the URL specified in the vpc_ReturnURL parameter

i checked the $pp_response['order_status'] value and it was set to 'P' after exiting the switch loop. do you mean the vpc_ReturnURL is wrong? what it should be?

Update: i followed the code to the controller then back to the payment gateway script. i tried to print a text to a file to check where the code stops, so i put a typing instruction after each function call, the last typing instruction executed was after "fn_finish_payment", the typing instruction after "fn_order_placement_routines" function is not executed at all. i dont know if this may help.

Update 2:

i think the main problem is in "fn_finish_payment", and in this line exactly:

"SELECT order_id FROM ?:order_data WHERE order_id = ?i AND type = 'S'"

because when i checked the database i found the order has been inserted 3 times and with these types: G, L, R and non of it is 'S'. do you have any information what this 'type' field mean?

i checked the $pp_response['order_status'] value and it was set to 'P' after exiting the switch loop. do you mean the vpc_ReturnURL is wrong? what it should be?

Update: i followed the code to the controller then back to the payment gateway script. i tried to print a text to a file to check where the code stops, so i put a typing instruction after each function call, the last typing instruction executed was after "fn_finish_payment", the typing instruction after "fn_order_placement_routines" function is not executed at all. i dont know if this may help.

Update 2:

i think the main problem is in "fn_finish_payment", and in this line exactly:

"SELECT order_id FROM ?:order_data WHERE order_id = ?i AND type = 'S'"

because when i checked the database i found the order has been inserted 3 times and with these types: G, L, R and non of it is 'S'. do you have any information what this 'type' field mean?

G - means product groups

L - means shipping information

R - means secondary currency

S - means special record which allows to change order status by payment script only one time (defined in the fn_start_payment function)

G - means product groups

L - means shipping information

R - means secondary currency

S - means special record which allows to change order status by payment script only one time (defined in the fn_start_payment function)

thank you for these information.

i checked the data base after i click on "checkout" button and before i entered the master card data. there is no order with type 'S', what does this mean? do you still think the error is in the vpc_ReturnURL ?

You don't get 'order_data' until after the order is "placed" which is after CC info is entered. Note that order_data requires and order_id which is not set before order placement.

Make sure that the exit function is called at the end of payment script. In other way, fn_finish_payment function is called and it deletes order data with S type

Make sure that the exit function is called at the end of payment script. In other way, fn_finish_payment function is called and it deletes order data with S type

WOW, i think it is working now after adding the exit function, thank you so much. i appreciate .

WOW, i think it is working now after adding the exit function, thank you so much. i appreciate .

You are welcome! :)