Tutorial: Integrate the Authorize.Net ARB API with PHP

This tutorial has been deprecated. You should read the new tutorial, “Tutorial: Integrate All Authorize.Net XML APIs With One Universal PHP Class (AIM, ARB, CIM, Transaction Details)” which offers new code for working with Authorize.Net’s XML APIs including sample code for every API call here.

Just like Authorize.Net’s Advanced Integration Method (AIM) API and Customer Information Manager (CIM) API, working with their Automated Recurring Billing (ARB) API isn’t difficult if you have suitable code to work with. The sample code offered by Authorize.Net will demonstrate how to work with their API but is not production ready. As with their AIM API and CIM API I have created a class that abstracts their ARB API into something easier to use and maintain.

To follow this tutorial and integrate ARB API into your PHP website follow these steps:

  1. If you don’t already have one sign up for a Authorize.Net Developer Account. This will allow you to test your code without having an actual Authorize.Net account or incurring any processing fees.
  2. Download the ARB Integration Guide (for reference)
  3. Download the PHP code for ARB

To begin you will need to include the class using PHP’s require() function:

  1. require('AuthnetARB.class.php');

As with any class/object the first thing we need to do is instantiate it. Up to three parameters are accepted in the constructor with the first two being required. myapilogin is the API login for the account. mYtRaNsaCTiOnKEy is the transaction key generated in the Authorize.Net control panel (or assigned to you with your test account information). If you have an Authorize.Net developer account you can use it with this script by setting the third parameters to TRUE (you may omit the third parameter if you are using this with the live server):

  1. // Set up the subscription. If you are using a live account remove the third parameter.
  2. $subscription = new AuthnetARB('myapilogin', 'mYtRaNsaCTiOnKEy', 
  3.                                               AuthnetARB::USE_DEVELOPMENT_SERVER);

Creating a subscription is very straight forward. We only need to set a few parameters before placing our API call. You can see the full list of parameters in the ARB Guide mentioned above. Naturally you will change these to be specific to your subscription:

  1. $subscription->setParameter('amount', 29.99);
  2. $subscription->setParameter('cardNumber', '4111111111111111');
  3. $subscription->setParameter('expirationDate', '2016-12');
  4. $subscription->setParameter('firstName', 'John');
  5. $subscription->setParameter('lastName', 'Conde');
  6. $subscription->setParameter('address', '123 Main Street');
  7. $subscription->setParameter('city', 'Townsville');
  8. $subscription->setParameter('state', 'NJ');
  9. $subscription->setParameter('zip', '12345');
  10. $subscription->setParameter('email', 'fakemail@example.com');
  11.  
  12. // Create the subscription
  13. $subscription->createAccount();

After making our API call we’ll want to verify it was successful and, if so, capture the subscription ID:

  1. // Check the results of our API call
  2. if ($subscription->isSuccessful())
  3. {
  4.     // Get the subscription ID
  5.     $subscription_id = $subscription->getSubscriberID();
  6. }
  7. else
  8. {
  9.     // The subscription was not created!
  10. }

Make sure you save the subscription ID as you will need to refer to it if you wish to update the subscription or delete it later.

By default the class assumes the subscription will be monthly. To change the frequency and length of the subscription you can use code similar to the following examples:

  1. // Put this before $subscription->createAccount(); 
  2. // if you want the subscription to be every three months.
  3. $subscription->setParameter('interval_length', 3);
  4. $subscription->setParameter('startDate', date("Y-m-d", strtotime("+ 3 months")));
  5.  
  6. // Put this before $subscription->createAccount();
  7. // if you want the subscription to be every year.
  8. $subscription->setParameter('interval_unit', 'years');
  9. $subscription->setParameter('startDate', date("Y-m-d", strtotime("+ 1 year")));

interval_length is how many units (i.e. weeks, months, years) you wish the subscription to wait before processing another payment. In the first example we set it to three which means the payment will process every three months. interval_unit sets the unit (i.e. weeks, months, years) you wish to use. In the second we changed it to “years” which means this subscription will be charged annually. startDate sets the date of the first subscription payment. We use PHP’s built in functions strtotime() and date() to make creating the date very easy. All we need to do is pass strtotime() the start date relative to today’s date in plain English. In our first example we want to set the first subscription payment to start in three months so we pass “+ 3 months” to strtotime(). In our second example we want the subscription to start in one year so we pass “+1 year” to strtotime().

By default the class assumes no trial period will occur. To create your subscription with a trial period just use the following snippet of code:

  1. // Put this before $subscription->createAccount(); 
  2. // if you want a trial period of three months for $10.00.
  3. $subscription->setParameter('trialOccurrences', 3);
  4. $subscription->setParameter('trialAmount', 10.00);

A common question concerning subscriptions is how do you handle delayed subscriptions where no money is charged up front? How do you verify the credit card is valid before making the subscription? Naturally you want to make sure the credit card is valid before making the subscription but if you’re not actually charging the first subscription payment up front (i.e. immediately) you won’t know if the credit card is valid. Fortunately verifying the credit card is easy to do. Just use the AIM API to do an Authorization Only. This will verify that the credit card is indeed valid before you create your subscription.

  1. $authorization = new AuthnetAIM('myapilogin', 'mYtRaNsaCTiOnKEy');
  2. $authorization->setTransaction($creditcard, $expiration, 0.00);
  3. $authorization->setTransactionType('AUTH_ONLY');
  4. $authorization->process();
  5.  
  6. if ($authorization->isApproved())
  7. {
  8.     // Set up ARB subscription
  9. }
  10. else if ($authorization->isDeclined())
  11. {
  12.     // The card is not valid
  13. }

The AuthnetARB class takes advantage of exceptions which are new in PHP5. These are only generated when an “exceptional” event occurs. The only exceptional event that might occur when using this class is cURL may fail. This may be due to server, network, or user errors. To catch these exceptions and handle them use code similar to this:

  1. try
  2. {
  3.     $cim = new AuthnetARB('myapilogin', 'mYtRaNsaCTiOnKEy');
  4.     // Do more ARB stuff here
  5. }
  6. catch (AuthnetARBException $e)
  7. {
  8.     echo 'There was an error processing the transaction. Here is the error message: ';
  9.     echo $e->__toString();
  10. }

Now that we have an idea of how to create subscriptions using the ARB API let’s see a practical example that sets the billing cycle to be every three months and has a trial subscription for three months:

  1. < ?php
  2. // Include AuthnetCIM class. Nothing works without it!
  3. require('AuthnetARB.class.php');
  4.  
  5. // Use try/catch so if an exception is thrown we can catch it 
  6. // and figure out what happened
  7. try
  8. {
  9.     // Set up the subscription. Use the developer account for testing..
  10.     $subscription = new AuthnetARB('myapilogin', 'mYtRaNsaCTiOnKEy', 
  11.                                               AuthnetARB::USE_DEVELOPMENT_SERVER);
  12.  
  13.     // Set subscription information
  14.     $subscription->setParameter('amount', 29.99);
  15.     $subscription->setParameter('cardNumber', '4111111111111111');
  16.     $subscription->setParameter('expirationDate', '2016-16');
  17.     $subscription->setParameter('firstName', 'John');
  18.     $subscription->setParameter('lastName', 'Conde');
  19.     $subscription->setParameter('address', '123 Main Street');
  20.     $subscription->setParameter('city', 'Townsville');
  21.     $subscription->setParameter('state', 'NJ');
  22.     $subscription->setParameter('zip', '12345');
  23.     $subscription->setParameter('email', 'fakemail@example.com');
  24.  
  25.     // Set the billing cycle for every three months
  26.     $subscription->setParameter('interval_length', 3);
  27.     $subscription->setParameter('startDate', date("Y-m-d", strtotime("+ 3 months")));
  28.  
  29.     // Set up a trial subscription for three months at a reduced price
  30.     $subscription->setParameter('trialOccurrences', 3);
  31.     $subscription->setParameter('trialAmount', 10.00);
  32.  
  33.     // Create the subscription
  34.     $subscription->createAccount();
  35.  
  36.     // Check the results of our API call
  37.     if ($subscription->isSuccessful())
  38.     {
  39.         // Get the subscription ID
  40.         $subscription_id = $subscription->getSubscriberID();
  41.     }
  42.     else
  43.     {
  44.         // The subscription was not created!
  45.     }
  46. }
  47. catch (AuthnetARBException $e)
  48. {
  49.     echo $e;
  50.     echo $subscription;
  51. }
  52. ?>

This class also supports updating and deleting subscriptions. Updating a subscription might look like this:

  1. $subscription = new AuthnetARB('myapilogin', 'mYtRaNsaCTiOnKEy');
  2. $subscription->setParameter('subscriptionId', $subscription_id);
  3. $subscription->setParameter('cardNumber', '4111111111111111');
  4. $subscription->setParameter('expirationDate', '2016-16');
  5. $subscription->setParameter('firstName', 'John');
  6. $subscription->setParameter('lastName', 'Conde');
  7. $subscription->setParameter('address', '123 Main Street');
  8. $subscription->setParameter('city', 'Townsville');
  9. $subscription->setParameter('state', 'NJ');
  10. $subscription->setParameter('zip', '12345');
  11. $subscription->setParameter('email', 'fakemail@example.com');
  12. $subscription->updateAccount();

Deleting a subscription would look like this:

  1. $subscription = new AuthnetARB('myapilogin', 'mYtRaNsaCTiOnKEy');
  2. $subscription->setParameter('subscriptionId', $subscription_id);
  3. $subscription->deleteAccount();

There you have it. Working with Authorize.Net’s ARB API is pretty easy once you hide their API behind some easy to use code. Have fun creating subscriptions!

60 thoughts on “Tutorial: Integrate the Authorize.Net ARB API with PHP

  1. You use strtotime(“+3 months”). Would I use that even if I wanted to start the subscription today.

    So if a user signs up today and I want the subscription to start today would I use:

    $subscription->setParameter(‘interval_length’, 3);
    $subscription->setParameter(‘startDate’, date(“Y-m-d”));

    ?

  2. Yes. But that’s not the best way to do it. If you want to start the subscription today you should charge their first payment via the AIM API. That way you get an immediate response and if there is a problem you can have the user try again while they are still there. If you use ARB to collect that first payment it won’t be charged until later that night. If it fails then you can’t collect from the user because they are long gone.

  3. Hi,

    My requirement is such that I want to charge first time setup fee & then set recurring billing.
    like this–
    Local Value – $149.00 set up fee/$99.00 monthly fee
    Since It is first time I’m using authorize.net. How to proceed?

  4. Alok,

    Use the AIM API to charge the initial $149 setup fee. The use ARB to create the subscription for $99 a month.

  5. Thnx for ur reply.

    Could u provide me with more help.
    Like how to merge both AIM & ARB?

    Can u refer to any URL for help where it’s already done.
    Thnx again.

  6. Thnx a lot.

    Your site is wonderful & it’s helpful as well.
    Keep up the good work.

  7. Thank you for this very helpful walk-through.

    I think I may have spotted a typo in your updateAccount() example. The parameter subscriptionId is actually named subscrId in the AuthnetARB.class.phps. Once I changed that, my updates began working.

  8. I also ran into that bug, and after some careful debugging found out about the subscriptionId thing. If the example could be updated, it may save some people some hair. Thanks for the great tutorial though John!

    One more question: Do users have to re-enter their credit card and billing info even if all that needs to be changed is the interval_length and amount?

    Sincerely,
    Leighton Whiting

  9. Hi,

    After creating a automated recurring billing, is it possible for me to charge the user using the subscription id , and the amount to be charged one time , say for example, an add-on payment apart from the recurring monthly payment ?

    Thanks,
    Manoj

  10. @Manoj, You cannot charge a credit card using an ARB subscription. You’ll need to use CIM for that.

    @Leighton, I’m not sure if they do need to re-enter that information or not. I think they do but I’m not 100% sure. You should hit the Authorize.Net developer forums and ask there.

  11. Hi,

    I set ARB for customer monthly say at 2010-Aug-07. my next recurring date will be 2010-Sep-07 and if there are not enough fund in customer’s creditcard or it get expired (means transaction not getting) what will happen in that case? is customer’s subscription get expired? how to i check programatically payment is done or not?

  12. @johny
    Thanx for reply.
    But what i want is i want to check it pogramatically and send email through my website.
    for ex:- I store the subscription_id for each user when they subscribed through my site when next payment date will come at that date i want to check payment is happen or not using that subscription_id and if it not done i want to expired his membership of my website and send an email to notify him/fer so.

  13. @johny:- thanx johny thanx a million!!!!
    Sorry but last question i know how to set URL (Home > Account > Settings > Transaction Format Settings > Transaction Response Settings > Silent Post URL) I also write a code for that the only thing i don’t know is how will icheck the code is working or not?

  14. How do you hide the api? We’ve had to convert the api from an asp method to php. We are now learning php.

  15. Regarding Silent posts. I read in the ARB doc.

    “ARB subscriptions only generate Silent Post responses if and when a transaction processes. If a transaction does not process, for example, if the credit card has expired, a Silent Post does not occur”

    So is there really no way to find out if users credit card has been expired and his subscription should be blocked?

  16. You should have recorded when their card is going to expire in your database when setting up the subscription to help keep track of these things. But if you didn’t you can use the new reporting API to check the status of the subscription to verify it is still valid and not suspended or cancelled.

  17. I was just about to start working on it. I had bookmarked your page and saw the response.

    I think I’ll record the next due date in database and will be using new api to see if the ‘status’ is suspended or canceled and act accordingly.

    So if user has subscribed at 12:00 PM on 4th Jan 2010 for 1 year then will add 1 year to it and store as next due date/time. Now the question is, will authorize.net exactly process the payment at 12:00 PM on 4th Jan 2011 or will wait till 2 AM PDT 5th Jan 2011. I am asking this because I want to know when should I really be checking the status to see if the next user payment was really successful or not.
    Perhaps a one day buffer? Meaning checking on 5th Jan 12:00 PM?

    Thanks so much for replying.

  18. Another quick question.

    You wrote:

    // if you want the subscription to be every year.
    $subscription->setParameter(‘interval_unit’, ‘years’);

    But I read that years unit is not supported by ARB?

  19. You can use an interval unit of 12 months to simulate annual subscriptions.

    Subscription payments are processed overnight regardless of what time of the day they are created. So if you want to check the status of a subscription I would wait until the next morning (i.e. a payment is scheduled for Jan 5, I would check Jan 6th just to be sure).

  20. Has anyone dealt with a situation where you give users the opportunity to upgrade a subscription.
    The following is the scenario.
    User subscribes to service on Jan 1, an arb subscription is created recurring monthly. On March 15th, user decides they love the service and would like to upgrade to an annual subscription. With 16 days left in March for which user has already paid for, how should one handle the upgrade.

    The objective is to allow the user to receive credit for the remainder of March since it already paid for, and have the annual arb begin on April 1 with no lapse in access to service.

  21. Hello Johnny,

    Thanks for all the help. I have implemented the ARB successfully.

    I am recording ‘next billing date’ in db to check status of transactions which were due for payment for those cases like expired card where silent post might not be sent. And there might be the other case when perhaps silent post somehow might have been missed (like server down).

    I am running a scheduled post at around 5:00 PM (assuming the payment was tried at 2 AM PST) to check for status of those subscriptions which were due and cancel them in case the status is not ‘active’

    So my question is does Authorize.net changes status from ‘active’ to something else on that day when payment was expected but either was declined or may be some other error occured?

    Because if I see the status ‘active’ on that ‘billing day’ I extend their subscription for 1 more year.

    So if Authorize.net doesn’t changes the status from active to something else on that due date then user might get 1 more free year subscription which is not what we want.

    Am I doing it right in looking at ‘active’ status?

    Thanks
    Sukhwinder

  22. Hello Again

    I found a work around and now everything is working okay since 1 month. Thanks for your help.

    But there is one problem I am facing with this xml and that is special characters.

    Address /name like these return xml error even when your class sets encoding to utf-8

    Vattenledningsvägen 16
    Hägersten

    Error returned is ‘Invalid character in the given encoding. Line 41, position 59.’

    Error is

  23. Hi John,

    Thanks for the post i have a one doubt i think you can able to clear my doubt. 🙂

    1) I create the Recurring Profile for the user

    2) i want to update the amount if his payment when he do some more option
    it is possible to update the Recurring amount.

    $subscription->setParameter(‘subscriptionId’, $subscription_id);
    $subscription->setParameter(‘amount’, 50.00);
    $subscription->updateAccount();

    Please give the advice

    Advance thanks 🙂

  24. Hi I am new to the authorize payment gate way. I was integrated arb stores all the date in authorized.net only. I stored in my date base only subscription _id and expiry date. While I was updating again its asking credit card number. Is it possible without storing the credit card number in my database . Plz tell me

  25. Hi John
    is this possible to use AIM with ARB ?
    I have integrate AIM in my site and it working very good now i want to use ARB, so can i use both or it use individually ?
    waiting for your advice
    Regards

  26. You can use both in the same script. In fact, this is the proper way to do it as you should use AIM first to verify the credit card and/or make the first subscription payment and then set up the subscription using ARB.

  27. thank you john.. one more thing please , can i perform subscription weekly or it only performed by monthly and yearly ?

  28. john i have some error on transaction.. please help me

    Notice: Undefined index: refID in C:\xampp\htdocs\deltatrac5\library\AuthnetARB.class.php on line 88

    Notice: Undefined index: subscrName in C:\xampp\htdocs\deltatrac5\library\AuthnetARB.class.php on line 90

    Notice: Undefined index: totalOccurrences in C:\xampp\htdocs\deltatrac5\library\AuthnetARB.class.php on line 97

  29. I`m trying to integrate Authorize.net ARB with my e-commerce site , Now I cant get the SSL certificate and I want the FORM that’s takes the Credit card information should be provided by Authorize.net . How can I get that FORM ? Do you have any idea ?

  30. Hi,Your blog is great, but there has been something I’ve been wondering about regarding AIM and ARB and made me think more after your previous comment about AIM first then ARB.

    With that being said, if i want to offer an item and then have the user opt in after the fact for a subscription, I guess this could be considered an “upsell” – do i process the first transaction and then do the subscription separate, or should I just verify with AIM and then see if they want the upsell and charge it all at once and set up ARB

    Which is considered better practice and more sensical?

  31. Charge them as soon as they choose a service that they should be charged for. If that occurs at a separate time then the upsell then having two distinct transactions is good because it makes it easier for the customer recognize the charges on their statement. But if both occur (normal purchase and upsell) at the same time then charge them together as the customer will recognize the combined total on their statement and not be confused and potentially initiate a chargeback.

  32. Great post, really good break down of the whole process. Thanks for the ARB class, very handy!

  33. Hello Jon

    I’ve Implemented it successfully wooohoooo

    By the way thanx for the code

    its just brilliant 🙂

  34. Hi!
    Great article!
    I’m using SilentPostUrl & TransactionDetailsApi for get all information about transactions.
    But, my customer want to use only Transaction Details API.

    Does it possable to get SubscriptionPaynum via TransactionDetails API (without SilentPostUrl)?

    I posted this question to support (developer@authorize.net) many times! But, I have no answer! )
    Maybe, somebody knows? )

  35. Hi John,

    I want to know is there any option to update the next payment date of the recurring Profile subscriber in ABR. I searched with google . they says we can able to start change the start date before the payment has been made. once its made we can able to change. but i want to know to stop the user recurring on a particular no of days is there any way to do that. i hope you are remember me i already asked doubt reg AIM.

    Advance Thanks

  36. I have embedded your code into my site but its still showing a problem that “The subscription was not created!”. i have entered my API ID and Trx ID and removed the 3rd param from the function and also did test mode off in authorize.net merchant account.

  37. I’m having the same problem. I followed your tutorial at developer.authorize.net to set up my first payment page, and it worked like a charm. Now I’m trying this for another situation where being able to check the subscription status is critical, and I’m finding the class doesn’t seem to be working. Any thoughts or assistance would be appreciated.

  38. Thanks for this amazing Authorize.net PHP class.

    You may need to change this line
    “$subscription->setParameter(‘expirationDate’, ‘2016-16’);” to a correct expiration date so that it works fine if you copy and paste the code to test it.

  39. Hi John, Thanks for this resource. I’m a total newb to anything but PayPal standard carts and I’m not familiar with php code. Though I feel pretty dumb disoriented after reading all the comments from people who seem to know more than I do before even getting started with implementing the ARB code, I must trouble you for some ultra-basic information. I’m working with WordPress and Cart66. Because my client will be offering wine along with other products in his online store, as well as membership subscriptions (and who knows what other reason), the bank where he has his merchant account required TWO accounts, thus two payment gateways with Authorize.net – one for wine and products, one for subscriptions. After getting all that set up, we learned that Cart66 can only handle one gateway, so I have to do the subscriptions separately, which is why I’m here. But I can’t seem to figure out where to place the provided .php files in the WordPress installation, which one represents the actual payment page, and how to place the payment page into the blog. Can you help me wrap my brain around this, or refer me to a resource that can help me get started? Thanks so much.

  40. Hi John

    I would like to know that is there any way to pause a subscription and activate later? I know there is a method to cancel it – but I want know if we can pause it rather than cancelling so that a user can stop the subscription for a month or two and can continue later

    Thank you
    Sathish

  41. There is no way to pause a subscription. However, a while back I did speak to Authorize.Net about this functionality and it was something there considering adding. Hopefully it is something they are still considering and we will see it in the near future.

Leave a Reply

Your email address will not be published. Required fields are marked *