Damon Cortesi ( @dacort ) over at Untitled Startup recently wrote up a summary of recurring payment services provided for startups. It's a decent analysis of current payment services that offer a hosted recurring billing solution, if you don't have a merchant account or want to handle your own e-commerce. If you're writing a software-as-a-service platform from the ground up, and would like to outsource the payment side of things, these are good options. But what if you already have a merchant account, or a retail offering, or an e-commerce site? What if you want to have a subscription product, or store a customer's credit cart for repeat business? The first thing to consider is security. If you're going to repeat a transaction, your customer's credit card number needs to be stored somewhere. If that's on your web site, you become a target for attack. As a company that hosts e-commerce systems for our clients, we would just as soon not have to protect thousands of credit card numbers. Fortunately there are quite a few payment gateways that can store the sensitive information for us, and all we need is a unique transaction number to use for future charges. In Ubercart, the recurring payments module has been removed from the core e-commerce system and put in its own module. This work is incomplete, but we are using it (carefully) in production. It's going to take time for the modules for various payment processors to catch up, but here's a quick run-down of a few gateways we've looked at, which features they can support, and which features work today. But first, a little lay of the land.

What is a payment gateway?

If you accept credit cards on your web site, you're likely working directly with three different companies, and there's probably a couple more in the background. On the e-commerce side, there are basically these components: [graphviz] digraph g { "Web Site/Shopping Cart" -> "Online Gateway" -> "Merchant Account" -> "Your Bank" } [/graphviz] The Web site is of course your site. If you have a shopping cart on the web site, it usually manages your products and handles the checkout (although it is possible to send a cart to the gateway and never see the customer's credit card number). The Online Gateway is the interface between your web site and the merchant account -- it's a service out on the web that acts like your credit card reader, basically taking transactions via the Internet. Common gateways include Authorize.net, Cybersource, eProcessingNetwork, Heartland, NMI, and many others. Paypal is also in effect an online gateway, though they're a bit of a special case. Online gateways usually provide a "virtual terminal" where you can go to view payments collected, void a transaction in the current batch, refund a previous transaction, capture payment on "authorize only" transactions, and more. They also often provide their own shopping cart functionality, although it's usually primitive compared to something like Ubercart or even ZenCart. The Merchant Account is essentially a line of credit that works directly with Visa/MasterCard/American Express (the payment processors) to get funds taken out of the card holder's account and put into your bank account. And finally, your bank account is where the money goes, when all of this is working correctly!

Recurring payments: Who stores the credit cart number?

If we take it as a given that we don't want to store the credit card numbers with the web site, we need to rely on the online gateway to store it for us. Fortunately, most of them provide a way of storing recurring transactions. Unfortunately, each gateway does it their own way. That means it's a lot of work to make a general solution that works for all the gateways. On top of that, the recurring payment module itself is going through substantial change, with the capabilities changing as it develops. There are basically 3 different approaches we've seen for handling recurring payments in this type of setup: Shopping cart creates a recurring transaction from the gateway. This is what Authorize.net calls "Automatic Recurring Billing," or ARB. This type of recurring billing is fairly straightforward to create a plugin to use, but you can't change the payment schedule or amount from the shopping cart without canceling the transaction and creating a new one (and getting the credit card number). This is the old-style recurring billing we've been able to do for a while, and it should cover most subscription needs. Shopping cart asks for a recurring product from the gateway. This sounds similar to the previous approach, but it's a lot more restrictive. NMI is a gateway that only offers this type of recurring billing. If you want to use this, you first need to go set up your product with all the billing details at the payment gateway. And then you need to go back to your shopping cart and repeat the whole process. Finally, the payment module needs to be smart enough to match your subscription product in your cart with the one at the payment gateway. This type of recurring billing really sucks, and we would recommend choosing a different processor if you have any variation in the subscription pricing whatsoever. We do not currently have this implemented. Gateway stores customer credit card info for future billing. This is by far the best approach. With this model, the shopping cart collects the credit card info and stores it at the online gateway. The gateway returns a unique transaction key that only your site can use--it's useless for anybody else. You can then do future charges to that customer in varying amounts and frequencies. Authorize.net calls this feature "Customer Information Manager" or CIM. We've also built a payment module for eProcessingNetwork that works this way, and Paypal support is pretty much there, too. It's also possible, but inadvisable, to store the credit card numbers in the shopping cart. We have support for doing this encrypted to a secret key, but the key must be stored on the server, so if the server got hacked it's possible for an attacker to decrypt the credit card numbers -- not something we want to make possible. But this approach does allow for doing repeated transactions with arbitrary amounts from any online gateway.

But what can you do with recurring payments?

So assuming your online gateway supports the third option, what does the Ubercart Recurring module currently support? Subscriptions, either for a fixed number of charges, or for unlimited repeating charges. That's the main thing you can do right now. You can schedule recurring charges to happen every day, week, month, or year, or after some number of the time period--every 3 months, every 2 years, whatever. You can set it up to charge immediately or after a delay--with one catch--some gateways require a small transaction to store the recurring details for later. You can easily cancel a transaction, as well as process one on demand -- although if you process a payment manually, the last time I dug into it it reset the time interval so future billings may happen on a new day... You can set it up so that users can cancel their own recurring billing, as well as prevent them from doing so. Each recurring payment becomes a new order in the system, so products with recurring billing can be mixed with normal products on the first order. There are plenty of actions to configure related to recurring billing--we can set it up to fire off an email on successful billing as well as failure, and can automatically change the state of the order to fulfilled. Because of the flexibility of Ubercart, you can set up a subscription for a wide range of items: physical products, access to content on the site via a purchased user role, access to particular content, and quite a bit more. We did just find a different module that allows customers to update their stored credit card information in Authorize.net's CIM, so in certain cases, this type of functionality is also available. At the moment, we don't have more in place--there's the potential to add other recurring payment schemes, but they just aren't implemented yet. Examples of this kind of thing would be for an automatic refill below a certain commit level, or a standing order for a special that has a variable price, or allowing a new order using a credit card on file. Each of these are possible, just not done yet!

Recurring payments in Ubercart versus a recurring billing system

So to wrap up, recurring billing out of Ubercart solves a substantially different problem than using a recurring billing service. A billing service is similar to an online gateway, except that they also handle the merchant account and all the complexity of routing payment to your bank account. However, the current solutions in this space don't sound like a match for shopping carts with a lot of products and a mix of one-time purchases and recurring billing. And they are designed to handle payment for custom sites. Ubercart and Drupal can plug into certain online gateways and get the same result.

Thanks, John. This was a very helpful write-up. I've just been doing some research on recurring billing for a very specific type of implementation, and information like this helps add some background as I try to determine the most efficient strategy. I was looking at UC Recurring to see if it will make the most sense to use that given a potential need to code support for an additional payment processor and integration with some other functionality for the site.

I've been trying to get a feel for general experience using the module, CIM vs. ARB vs. WP, and status on some of the payment processor integration. You mentioned you're using it "carefully". Has anything crept up in the last few weeks that has been a concern or challenge?

- Matt Winters
Kinaba / WebNewCastle


Our epn module seems to be working great with recurring payments! The one quirky thing is that if you want to charge the first payment after a period of time (instead of immediately) you need to set the product price to zero, and set the recurring price in the feature. A little bit odd...

I would recommend doing a CIM-style connection if you have a choice -- store the credit card info at the gateway, and get a handle Ubercart can use for future payments. Though not all gateways support that. Just digging into FirstData for a client, and it looks like we'll be adding support to that for an ARB-style connection.

- John

CIM is "Customer Information Manager", and basically allows you to put the customer's card info on file. You then get a handle that's unique to your store that you can use for arbitrary transactions... basically you have the credit card "on file" in a secure way.

So it's possible to change the payment amount, skip a payment, delay a payment, etc. Ubercart doesn't necessarily support these features (yet) but it's at least possible.

uc_recurring initiates the recurring payment, using the customer details stored in CIM.

ARB is "Automatic Recurring Billing." With ARB, Ubercart (or other shopping cart) tells Authorize.net to charge on a schedule. Authorize.net provides a transaction id that can be used to cancel it in the future, but otherwise once it's set up, you can't necessarily change it.

With ARB, Ubercart/uc_recurring is far more passive--it may enter a new order, but it doesn't do anything further with ARB. If your site disappears entirely, ARB would continue to make charges on the customer's card.

CIM is new, and is what the new uc_recurring is targeting. ARB has been around a while, and is supported in older uc_recurring.

I always been concerned with taking credit cards on my websites (those where it's needed) but except for the recurring billing issue, it may be less of a hassel that I thought. Thanks for the info.

Is there any point to having both CIM and ARB with Drupal and Ubercart? I currently have CIM setup with recurring fees, and everything seems to be working. Except for one thing - I can't figure out how to send a notification email to a customer prior to their card expiration date (so they can update their expiration date prior to renewal). I can only notify them in the event of a failed renewal.

From what I can tell, ARB allows me to do this, but I'm not sure it's worth paying an extra $10/ month just for this feature. Anyone know of a way to do this with just CIM? If not, is Ubercart stable enough to run both CIM and ARB?

Finally, I haven't yet actually encountered a failed renewal event (and can't find a way to test it), but when I do, it seems that the email sent to the customer will contain a [recurring-link] element, which they can supposedly click on to update their card details. Does this work without them logging in to my site? Or do I need to add their login details to the email?

Great article, thanks for taking the time to read my questions!


My e-commerce store is using the Authorize.net payment gateway and there are many opinions around the campfire on how to store and make recurring payments. 3 developers = 5 opinions!! We currently store credit card numbers on a 'secure server' (I put in quotes for obvious reasons) database and run the charges on the first of the month. (#1) One idea was to store the expiration dates on another 'secure server' database to spread the risk off just one server. (#2) Another idea was to not store the exp date / 3-digit code in a database at all and run the payments by hand through our voip phone systems. (#3) And then we have the purists who want zero risk and wish to have an employee run them by hand every month through our online payment gateway UI.

I have a problem with #3 because, thinking as a businessman, this solution is not scalable. I consider anything that involves human input on a regular basis not scalable. It's easy to poke holes in #1 and #2 considering the risk of storing credit card information online.

the puzzle continues...

Add new comment

The content of this field is kept private and will not be shown publicly.

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <blockquote cite> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h1> <h2 id> <h3 id> <h4 id> <h5 id> <p> <br> <img src alt height width>
  • Lines and paragraphs break automatically.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.