cancel
Showing results for 
Search instead for 
Did you mean: 

Error 99 in PERL

So, I figured out how to fix the URL (for anyone who saw my earlier post), but now I can't get get it to log me in properly. Do I need to change it from ;https://secure.authorize.net/gateway/transact.dll'  to 'https://api.authorize.net/xml/v1/request.api'? It gives me error 99, which the help thing says my x_fp_hash data doesn't match. I'm so confused right now. This is the part where I think I'm getting the problem:

else {
        # Display form to go to AuthorizeNet
        my $fp_timestamp = time();
        my $fp_sequence = int(rand(1000));

        my $fp_hash = sha512_hex(
            $authorizenet_loginID . "^" . $fp_sequence . "^" . $fp_timestamp . "^" . $vars{'amount'} . "^",
            $authorizenet_transactionKey);

        # Remove any dollar symbol in amount field
        $vars{'amount'} =~ s/\$//;

        $page_content = process_template($form2_tpl, {
                authorizenet_url=>  $authorizenet_url,
                x_login         =>  $authorizenet_loginID,
                x_amount        =>  $vars{'amount'},
                x_invoice_num   =>  $vars{'invoice_num'},
                x_description   =>  sprintf("Online invoice payment from %s %s",
                                        $vars{'first_name'},
                                        $vars{'last_name'},),
                x_first_name    =>  $vars{'first_name'} ,
                x_last_name     =>  $vars{'last_name'} ,
                x_fp_sequence   =>  $fp_sequence,
                x_fp_timestamp  =>  $fp_timestamp,
                x_fp_hash       =>  $fp_hash,
            });
        # $page_content .= '<pre>' . Dumper($fp_sequence, $fp_timestamp,
        #   $vars{'amount'}, $authorizenet_transactionKey, $fp_hash) . '</pre>';
    }
}

I'm not sure what is incorrect in here. Is it redirecting to the wrong URL? Is there a bit of code out of place? I'm so lost... Someone else did all of this code, and I know very little when it comes to coding. Please help!

 

Chalisa91
Member
3 REPLIES 3

Your hash function has the variable named transaction_key.  If that variable is assigned the value of the transaction key, that is at least part of your problem. What you need is the signature key. It is generated in the merchant interface. You do not need to use the api.authorize.net url. That is for modern API integrations that you do not use.  Your post endpoint is correct.  

 

https://support.authorize.net/s/article/What-is-a-Signature-Key

 

Another issue I am noticing is that you have the $ being removed after the hash is calculated.  That could potentially throw you off. I would start with the signature key and go from there. Try using the signature key instead of the transaction key and see what you get.   

 

I am not good at all with Perl, so I cannot make full sense of the syntax of your code. If you still don't get the correct hash after using the signature key, you may not be appropriately converting to binary.  You want t o find out how you convert hexidecimal values to binary in perl, and apply that to your signature key before your hash function calculates.  

Renaissance
All Star

Okay, so I changed it up a bit. Does this look right? I know you're not an expert, but you likely know far more than I do, considering I've only been coding for a month or so now. I took some recommendations from another post. By the way, I didn't actually write any of the original code. It was done around 10 years ago by someone else, and then my brother-in-law played with it a bit to try and get us up to date with the SHA-512 migration.

my $authorizenet_loginID = '#(my actual login ID)#';
my $authorizenet_transactionKey = '#(my actual transaction key)#';
my $authorizenet_signatureKey = '#(my actual signature key)#';
  $authorizenet_signatureKey = pack("H*", $authorizenet_signatureKey);
# my $authorizenet_tx_key = '';
my $is_in_test_mode = 'NO';
my $authorizenet_url = $is_in_test_mode eq 'YES' ?
    'https://test.authorize.net/gateway/transact.dll' :
    'https://secure.authorize.net/gateway/transact.dll';

my $q = CGI->new();
my %vars = $q->Vars;

my $page_title = 'Pay my bill';
my $page_description = '<p>Please enter your information below, you will then be redirected to a secure server where you will enter your credit card information.</p>';
my $page_content = '';

if(defined $vars{'Next'}) {
    # Validate data
    my @errors = ();
    my $validation_hash = {
        first_name      =>      {
            label   =>  'First name',
            regex   =>  '\w+',
        },
        last_name       =>      {
            label   =>  'Last name',
            regex   =>  '\w+',
        },
        invoice_num     =>      {
            label   =>  'Invoice number',
            regex   =>  '\d+',
        },
        amount          =>      {
            label   =>  'Amount',
            regex   =>  '^\$?\d+(\.\d{2})?$',
        },
        email_address   =>      {
            label   =>  'E-mail address',
            regex   =>  '[\w\d]@[\w\d]',
        },

    };
    foreach my $key (keys %$validation_hash) {
        if($vars{$key} !~ m/$validation_hash->{$key}->{'regex'}/) {
            push @errors, "The information provided for '$validation_hash->{$key}->{'label'}' is not valid.";
        }
    }

    if(@errors) {
        $page_description = '<p>There is a problem with some of the information you provided. See below for specific information about the problem(s), then correct and submit the information again.</p><ul>';

        $page_description .= join("\n", map({ "<li>$_</li>" } @errors));
        $page_description .= '</ul>';

        $page_content = process_template($form1_tpl, {
                first_name      =>  $vars{'first_name'},
                last_name       =>  $vars{'last_name'},
                invoice_num     =>  $vars{'invoice_num'},
                amount          =>  $vars{'amount'},
                email_address   =>  $vars{'email_address'},
                my_url          =>  $q->url(),
            });

    }
    else {
        # Display form to go to AuthorizeNet
        my $fp_timestamp = time();
        my $fp_sequence = int(rand(1000));

        my $fp_hash = sha512_hex(
            $authorizenet_loginID . "^" . $fp_sequence . "^" . $fp_timestamp . "^" . $vars{'amount'} . "^",
            $authorizenet_signatureKey);

        # Remove any dollar symbol in amount field
        $vars{'amount'} =~ s/\$//;

        $page_content = process_template($form2_tpl, {
                authorizenet_url=>  $authorizenet_url,
                x_login         =>  $authorizenet_loginID,
                x_amount        =>  $vars{'amount'},
                x_invoice_num   =>  $vars{'invoice_num'},
                x_description   =>  sprintf("Online invoice payment from %s %s",
                                        $vars{'first_name'},
                                        $vars{'last_name'},),
                x_first_name    =>  $vars{'first_name'} ,
                x_last_name     =>  $vars{'last_name'} ,
                x_fp_sequence   =>  $fp_sequence,
                x_fp_timestamp  =>  $fp_timestamp,
                x_fp_hash       =>  $fp_hash,
            });
        # $page_content .= '<pre>' . Dumper($fp_sequence, $fp_timestamp,
        #   $vars{'amount'}, $authorizenet_transactionKey, $fp_hash) . '</pre>';
    }
}
else {
    $page_content = process_template($form1_tpl, {
        first_name      =>  '',
        last_name       =>  '',
        invoice_num     =>  '',
        amount          =>  '',
        email_address   =>  '',
        my_url          =>  $q->url(),

        });

}

my $html_output = process_template($wrapper_tpl, {
    title           =>  $page_title,
    pagedescription =>  $page_description,
    content         =>  $page_content,
    });

print $q->header('text/html'),
    $html_output;




sub process_template {
    my $tpl_txt = shift;
    my $vars = shift;

    foreach my $key (keys %$vars) {
        $tpl_txt =~ s/##${key}##/$vars->{$key}/gi;
    }

    return $tpl_txt;
}

 

@Chalisa91

That code looks sort of ok, but I can’t say for sure. Looks like you’re working on the fingerprint validation. The response is the part that will break your app in June or so. I won’t get into actual programming syntax as it relates to Perl, but here is what you need to do for the fingerprint:

1. Construct the string. Make your your amount is a decimal value to two places and in additional formatting.
2. Convert your signature key to binary.
3. Hash the string with the binary signature key, making sure to output a hexadecimal value, not raw binary.
4. Use the value from step 3 as your fingerprint.

The response verification works the same, but you have a different string.