Super-Simple Event Registrations using Authorize.net and jQuery

January 11, 2011
Development

Here at New Media Campaigns, we do a lot of work with non-profits. The number one thing most of them want out of their brand new website is better fundraising opportunities, and one way we can provide that is through easy online registration for events. We often use PayPal for this purpose, since it is easy to set up and ubiquitous. If an organization already has a merchant account set up with their bank though, they may prefer to accept payments through Authorize.net, for the lower fees and easier accounting workflow.

Great, we say. Authorize.net has a hosted payment form, which provides many of the same benefits as using PayPal: offloading the responsibility for security and the payment logic to a third-party service. Although we do set up SSL-secured hosting for some of our clients, the extra overhead is beyond the budget of many smaller non-profits so a hosted payment form is an excellent compromise. The selection of event options (or products to buy) takes place entirely on the organization's website and visitors are only transferred to Authorize.net's server at the very end, to enter their credit card information.

Now, if there is only a single event or product that can be bought at a time, the process of integrating with Authorize.net is relatively easy, using their Server Integration Method. If there are options that a visitor can select, the code gets considerably more complicated. This is because Authorize.net requires an encoded fingerprint, which must be generated server-side to protect your account details. This fingerprint incorporates the total dollar amount of the order, so changing options on the checkout page will require new fingerprint. As you will see, we can use a bit of Javascript to make an AJAX call to a PHP script that generates a new fingerprint whenever different options are selected.

The first thing we need to do is to create the form where visitors will select their registration options. You can view a sample page here. A few things to note, though:

  • I have saved it with a .txt extension for easier code viewing, but the registration form will need to be a PHP file.
  • You will need an API Login ID and a Transaction ID for the Authorize.net account you plan to use (or a test account). Paste the API Login ID into the value attribute of the hidden x_login field.
  • The x_sequence field is meant to be used for an "order number". This can be anything you want, even just a randomly-generated number, but it is required.
  • While you are testing your code, you will want to change the x_test_request field's value to true so transactions are not actually processed. If you are using a test account, you should also change the form's action url to https://test.authorize.net/gateway/transact.dll.
  • Any arbitrary input fields that Authorize.net does not recognize will be passed through to the receipt email. We are using this functionality for the "Organization" field.
  • You can add as many price-affecting options as you want (either radio-buttons or checkboxes), with the following attributes: they must have a class of reg-option; there needs to be a data-price attribute containing the price of the option; and the value attribute will be used to construct a description of the order, so use something unique for each or you won't be able to tell from the receipt which options were selected.

Next, we need to download download Authorize.net's PHP SDK and upload the entire folder to our server. You can put it anywhere, but if it is in a different folder than the rest of your files, you will need to update the paths in the sample code. Now, create a new file in the same folder as your form named fingerprint.php. Paste the following code into it, and update the API Login ID and Transaction Key with the actual values from your Authorize.net account.

<?php
require_once 'anet_php_sdk/AuthorizeNet.php'; // Make sure this path is correct
$api_login_id = '1234abcd'; // From your Authorize.net account
$transaction_key = '5678efgh'; // From your Authorize.net account
echo AuthorizeNetSIM_Form::getFingerprint(
    $api_login_id,
    $transaction_key,
    $_POST['amount'],
    $_POST['sequence'],
    $_POST['time']
    );

Looking back at the sample form code, you will see some Javascript at the bottom of the page. I am using jQuery, but this code could very easily be adapted to work with any framework that provides AJAX helpers. Every time one of the options is selected or deselected, it calls the fingerprint.php script to generate a new fingerprint hash.

That's it! Now we can offer multiple registration options without annoying page reloads. With minimal changes, you could also adapt this code to a single-page e-commerce store, offering an assortment of products that could be selected for purchase. If you have improvements or new uses for this code, please share them in the comments.

Comments

Mike Johnson's avatar
Mike Johnson
I am getting error 97, but I have verified my timestamps. Just wanted to verify that the error no longer existed in the sample page referenced above.

Thank You.
Eli Van Zoeren's avatar
Eli Van Zoeren
There was a mistake in my example code, which is now fixed. Sorry about that!
Pablo Carrau's avatar
Pablo Carrau
Hey Eli,

Thanks for your prompt response! I just e-mailed you my code so that you can take a look if you don't mind.

Thanks!
Eli Van Zoeren's avatar
Eli Van Zoeren
Pablo,

It sounds like the hash that's being generated doesn't match the data you are actually submitting for some reason. This could happen if the field names you used don't match the ones referenced in my script, or if the price calculations aren't happening correctly. You might try using Firebug or Web Inspector to see what data is actually being send to the fingerprint script and make sure it matches what you submit to Authorize.net exactly. Beyond that, it's hard for me to say anything without being able to see your code.
Pablo Carrau's avatar
Pablo Carrau
Great code, but I keep running into the following error:

The following errors have occurred.
(99) This transaction cannot be accepted.

Any reason why this would be? I followed your instructions perfectly and I'm using an active Authorize.Net account.

I can verify that the fingerprint hash is being generated correctly. According to Authorize.Net, the 99 reason response code means:
"Applicable only to SIM API. The server-generated fingerprint does not match the merchant-specified fingerprint in the x_fp_hash field."

Am I missing something?

Leave a comment