cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

MD5 Hash - PHP - SDK - I'm sorta confused ...

What I've currently got in place isn't too complicated.
Basically, in total it's a simple relay-response:

<?php
require_once 'anet_php_sdk/AuthorizeNet.php'; // The SDK
$relay_response_url = "https://www.globalprotectivesolutions.com/account/relay_response.php?enrid=".$thisENR['id'];
$api_login_id = '456KDQvr7k';
$transaction_key = '6NqnC59p222TSp6V';
$amount = "$totaltoCARD;";
$fp_sequence = $thisENR['id']; // Any sequential number like an invoice number.
echo AuthorizeNetDPM::getCreditCardForm($amount, $fp_sequence, $relay_response_url, $api_login_id, $transaction_key );
?>

That's IT.

I'm sorta confused about depreciated things, end of life things, and the MD5 end of life ...

It doesn't appear that I'm using the hash to start with. So, for the moment, should I be OK at the end of the month?
Second, docs on the autho site about this method are sorta old, but there seems to be different things on different pages, so I'm confused if this is depreciated and needs replacing. If so, replaced with what? Hate to screw with a working thing ...

Advise please?

LGMizzell
Contributor
1 ACCEPTED SOLUTION

Accepted Solutions
The code you have above is for API not SIM. It is a non factor in your hash validation. Either an md5 validation is taking place behind the scenes or your response validation is disabled. In the first case your app will break when md5 is disabled. In the 2nd case your app is somewhat insecure. IM me if you need more detailed help.

View solution in original post

9 REPLIES 9

@LGMizzell 

 

What you need to check is the file that hosts your relay response url. You need to see if it is calculating a hash before acting on the response.  Copy and paste the code from that file and we will be able to help you. 

 

If you are calculating a hash (which is very recommended) to verify the response, your app will break when MD5 expires. 

Renaissance
All Star

Looks like that *is* being calculated:

$api_login_id = 'xxxxxxxx';
$md5_setting = "mdmdmdmdmd"; // Your MD5 Setting
$response = new AuthorizeNetSIM($api_login_id, $md5_setting);
$enrID = $_GET['enrid'];
$transID = htmlentities($_GET['transaction_id']);
$responseC = $_GET['response_code'];

Although recommended, if I just commented the md5 parts out, would it work?
Meanwhile, do I need to recode the entire payment process a different way at this point?

@LGMizzell 

 

you have an object oriented validation set up. I would have to see the rest of your code. Commenting out the md5 won't work here, for what you have posted. Somewhere in the code for that class there will be some sort of conditional statement.  If it has a syntax of return true; and return false; you could just change the false to true. 

 

I have working hash verification for SIM/DPM that has been tested. I also have working code for API that has been tested and should work also for AIM (but has never been tested on AIM). Looks like you are using SIM/DPM.  

 

All that needs changed is your hashing method and you're good. Problem is that your hashing seems to be tied up with the rest of your response handling in that class file. That means you might have to do some reworking.  

 

See the post marked as the solution in the below thread, which I started and solved.

 

 

https://community.developer.authorize.net/t5/Integration-and-Testing/Working-php-hash-verification/m...

Based on your code, plus some other things I've been reading, the below is working for me in the current live environment. Fingers crossed it still works after whatever the heck autho.net is doing next week gets done ....

----------------------------------------

 

$enrID = $_GET['enrid'];

$responseC = $_GET['response_code'];

$payDATE = date('Y-m-d');

$login = "xxxxx";
$signatureKey ="xxxxx";
$signatureKey = hex2bin($signatureKey);
$amount = $amount;

$transId = $response-&gt;getTransactionResponse()-&gt;getTransId();
$string = '^'.$login.'^'.$transId.'^'.$amount.'^';


$hash = $response-&gt;getTransactionResponse()-&gt;getTransHashSha2();
$digest = strtoupper(HASH_HMAC('sha512',$string,$signatureKey));

if(hash_equals ($digest,$hash)){

if ($response->approved) { DO MY STUFF };

----------------------------------------

 

The code you have above is for API not SIM. It is a non factor in your hash validation. Either an md5 validation is taking place behind the scenes or your response validation is disabled. In the first case your app will break when md5 is disabled. In the 2nd case your app is somewhat insecure. IM me if you need more detailed help.

@LGMizzell 

 

Does your code look like this

 

 

<?php
/**
 * Easily use the Authorize.Net Server Integration Method(SIM).
 *
 * @package    AuthorizeNet
 * @subpackage AuthorizeNetSIM
 * @link       http://www.authorize.net/support/SIM_guide.pdf SIM Guide
 */

/**
 * Easily parse an AuthorizeNet SIM Response.
 * @package    AuthorizeNet
 * @subpackage AuthorizeNetSIM
 */
class AuthorizeNetSIM extends AuthorizeNetResponse
{

    // For ARB transactions
    public $subscription_id;
    public $subscription_paynum;

    /**
     * Constructor.
     *
     * @param string $api_login_id
     * @param string $md5_setting For verifying an Authorize.Net message.
     */
    public function __construct($api_login_id = false, $md5_setting = false)
    {
        $this->api_login_id = ($api_login_id ? $api_login_id : (defined('AUTHORIZENET_API_LOGIN_ID') ? AUTHORIZENET_API_LOGIN_ID : ""));
        $this->md5_setting = ($md5_setting ? $md5_setting : (defined('AUTHORIZENET_MD5_SETTING') ? AUTHORIZENET_MD5_SETTING : ""));
        $this->response = $_POST;
        
        // Set fields without x_ prefix
        foreach ($_POST as $key => $value) {
            $name = substr($key, 2);
            $this->$name = $value;
        }
        
        // Set some human readable fields
        $map = array(
            'invoice_number' => 'x_invoice_num',
            'transaction_type' => 'x_type',
            'zip_code' => 'x_zip',
            'email_address' => 'x_email',
            'ship_to_zip_code' => 'x_ship_to_zip',
            'account_number' => 'x_account_number',
            'avs_response' => 'x_avs_code',
            'authorization_code' => 'x_auth_code',
            'transaction_id' => 'x_trans_id',
            'customer_id' => 'x_cust_id',
            'md5_hash' => 'x_MD5_Hash',
            'card_code_response' => 'x_cvv2_resp_code',
            'cavv_response' => 'x_cavv_response',
        );
        foreach ($map as $key => $value) {
            $this->$key = (isset($_POST[$value]) ? $_POST[$value] : "");
        }
        
        $this->approved = ($this->response_code == self::APPROVED);
        $this->declined = ($this->response_code == self::DECLINED);
        $this->error    = ($this->response_code == self::ERROR);
        $this->held     = ($this->response_code == self::HELD);
    }
    
    /**
     * Verify the request is AuthorizeNet.
     *
     * @return bool
     */
    public function isAuthorizeNet()
    {
        return count($_POST) && $this->md5_hash && ($this->generateHash() == $this->md5_hash);
    }
    
    /**
     * Generates an Md5 hash to compare against Authorize.Net's.
     *
     * @return string Hash
     */
    public function generateHash()
    {
        $amount = ($this->amount ? $this->amount : "0.00");
        return strtoupper(md5($this->md5_setting . $this->api_login_id . $this->transaction_id . $amount));
    }

}

/**
 * A helper class for using hosted order page.
 *
 * @package    AuthorizeNet
 * @subpackage AuthorizeNetSIM
 */
class AuthorizeNetSIM_Form
{
    public $x_address;
    public $x_amount;
    public $x_background_url;
    public $x_card_num;
    public $x_city;
    public $x_color_background;
    public $x_color_link;
    public $x_color_text;
    public $x_company;
    public $x_country;
    public $x_cust_id;
    public $x_customer_ip;
    public $x_description;
    public $x_delim_data;
    public $x_duplicate_window;
    public $x_duty;
    public $x_email;
    public $x_email_customer;
    public $x_fax;
    public $x_first_name;
    public $x_footer_email_receipt;
    public $x_footer_html_payment_form;
    public $x_footer_html_receipt;
    public $x_fp_hash;
    public $x_fp_sequence;
    public $x_fp_timestamp;
    public $x_freight;
    public $x_header_email_receipt;
    public $x_header_html_payment_form;
    public $x_header_html_receipt;
    public $x_invoice_num;
    public $x_last_name;
    public $x_line_item;
    public $x_login;
    public $x_logo_url;
    public $x_method;
    public $x_phone;
    public $x_po_num;
    public $x_receipt_link_method;
    public $x_receipt_link_text;
    public $x_receipt_link_url;
    public $x_recurring_billing;
    public $x_relay_response;
    public $x_relay_url;
    public $x_rename;
    public $x_ship_to_address;
    public $x_ship_to_company;
    public $x_ship_to_country;
    public $x_ship_to_city;
    public $x_ship_to_first_name;
    public $x_ship_to_last_name;
    public $x_ship_to_state;
    public $x_ship_to_zip;
    public $x_show_form;
    public $x_state;
    public $x_tax;
    public $x_tax_exempt;
    public $x_test_request;
    public $x_trans_id;
    public $x_type;
    public $x_version;
    public $x_zip;
    
    /**
     * Constructor
     *
     * @param array $fields Fields to set.
     */
    public function __construct($fields = false)
    {
        // Set some best practice fields
        $this->x_relay_response = "FALSE";
        $this->x_version = "3.1";
        $this->x_delim_char = ",";
        $this->x_delim_data = "TRUE";
        
        if ($fields) {
            foreach ($fields as $key => $value) {
                $this->$key = $value;
            }
        }
    }
    
    /**
     * Get a string of HTML hidden fields for use in a form.
     *
     * @return string
     */
    public function getHiddenFieldString()
    {
        $array = (array)$this;
        $string = "";
        foreach ($array as $key => $value) {
            if ($value) {
                $string .= '<input type="hidden" name="'.$key.'" value="'.$value.'">';
            }
        }
        return $string;
    }
    
    /**
     * Generates a fingerprint needed for a hosted order form or DPM.
     *
     * @param string $api_login_id    Login ID.
     * @param string $transaction_key API key.
     * @param string $amount          Amount of transaction.
     * @param string $fp_sequence     An invoice number or random number.
     * @param string $fp_timestamp    Timestamp.
     *
     * @return string The fingerprint.
     */
    public static function getFingerprint($api_login_id, $transaction_key, $amount, $fp_sequence, $fp_timestamp)
    {
        $api_login_id = ($api_login_id ? $api_login_id : (defined('AUTHORIZENET_API_LOGIN_ID') ? AUTHORIZENET_API_LOGIN_ID : ""));
        $transaction_key = ($transaction_key ? $transaction_key : (defined('AUTHORIZENET_TRANSACTION_KEY') ? AUTHORIZENET_TRANSACTION_KEY : ""));
        if (function_exists('hash_hmac')) {
            return hash_hmac("md5", $api_login_id . "^" . $fp_sequence . "^" . $fp_timestamp . "^" . $amount . "^", $transaction_key); 
        }
        return bin2hex(mhash(MHASH_MD5, $api_login_id . "^" . $fp_sequence . "^" . $fp_timestamp . "^" . $amount . "^", $transaction_key));
    }
    
}

I'm going to be honest. I gave up on it. I don't have enough hair left to continue down that path!

I'm working on an accept.js solution now - which is going MUCH better for me than the previous solution (so far anyway).

I'm at the point where I'm getting the token back when the payment form is submitted ... so I'm 55% there now!!! And that has only taken me since earlier this morning - unlike ... well, never mind how much time I've fought with the previous ...

Thank you so very very much for your assistance, and hopefully stuff posted here has helped *somebody* along the way!

@LGMizzell 

 

You are welcome. Could you kindly mark this thread as solved? Best of luck to you.