Looking for uc_recurring.module testers

Posts: 3192
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Alrighty, I've got in working order a recurring payments module, and I'm looking for folks to check it out, test it, and see if it makes sense. Smiling

First, I'll try to spell out what the module is not: this is not a one-stop killer module to handle anyone's recurring payment needs. Neither is it an interface to every payment gateway imaginable. It will also never become either of these things. So... what is it good for?

Well, the module is good for providing a framework for your modules to hook into. That's what we want in core, right? Eye-wink It does provide a product fee called "recurring fee" that you can attach to a product/SKU. With this you can specify a fee amount, an initial charge (relative to checkout), an interval for further charges, and the total number of intervals. When a customer goes to checkout, the module will restrict them to the payment method options on your site that work for recurring payments. (These can be adjusted in the product features settings form for recurring payments.) Once they complete checkout, the module passes the fee information onto the recurring payment handler of your choice for processing. The rest is up to your handler.

The module also provides a very basic default handler. This depends on you using some sort of credit card payment processor and stores CC data locally to be charged on the proper intervals. There's a cron task to do this automatically, and there's also an admin menu at /admin/store/orders/recurring that lets you tweak the fees and charge them manually. This also includes a few workflow events and a hook_recurring_api($op, $fee) for modules to hook into. I highly recommend using CC encryption if you intend to go this route. Eye-wink

The default handler can be an example in some ways for others to build on in their own modules. It's my understanding that a lot of payment gateways have built in subscription management. In that case, you'll need to code your own functions to setup subscriptions and decide what to do when someone's charge fails or their subscription expires. To be the most flexible, I highly recommend invoking the hook and workflow events you'll see invoked in the uc_recurring_charge() function at the bottom of the module.

Handlers are made by simply implementing hook_recurring_fee($order, $fee) in your module. The arguments are pretty self-explanatory. You can dump $fee with print_r() to see what it contains... basically all the info from the product feature.

I don't intend to work on this indefinitely, and I want it to stay slim. But I want some assessment as to the ease of use for the product feature and the default handler, and I also want to know if anything is lacking for folks to use this as a framework to build their own handlers.

This is the last major hurdle on my beta-do list, so thanks for any help! Cool

AttachmentSize
uc_recurring.tar40.5 KB
Posts: 21
Joined: 02/02/2008

Dear Ryan,

Thank you very much!

I will be testing this for sure.

I am a bit dizzy by all the Recurring / Subscriptions modules, and I am posting links to those as well for reference. Maybe we can take the best from all of these, and combine them into a single kick ass recurring module (even though it was stated this one is not meant to be an all in all solution but a preprocessor for the payment gateways, and these latter should do their own thing regarding recurring stuff) Sticking out tongue

http://www.ubercart.org/contrib/2851#comment-12320
http://www.ubercart.org/contrib/1461

Posts: 12
Joined: 10/30/2007

Authorize.net recently added a new feature called the "Customer Information Manager" to store/manage customer data for recurring billing. For those who use them, this will save them having to store cc data on their own servers. The guide can be found here: http://www.authorize.net/support/CIM_XML_guide.pdf
They provide sample intergration code here: http://developer.authorize.net/samplecode
Hopefully that can help.

Posts: 3
Joined: 02/28/2008

I will also be glad to test this module. We need a module to generate monthly bills to stay member in a certain role. The payment method we use is a batchmethod called automatic incasso to send to the bank on a monthly base.
We will go live in June and would like to test this in our situation.

Posts: 3
Joined: 02/28/2008

I am not sure if we have it clear what situations we might have for recurring events.

1. The situation that someone buys a product but wants to pay for it in several stages.
What we need then is a partial payment for every period, and a single order and invoice.

2. The situation that we have a product that we want to renew every period, with a new order and invoice

3. The situation that we would like to have a order recurred, with a set of products included.

This module is focusing on the first situation, while subscriptions is focusing on the second situation am i right?

Posts: 3192
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

This module is more for the second situation where you attach a recurring fee to a product, like a monthly membership fee. It mostly facilitates this sort of work, though, and will most likely need to be integrated into your payment service.

Posts: 60
Joined: 12/28/2007
Bug FinderGetting busy with the Ubercode.

Zahor - You're in luck, I've written a CIM module. Check it out in contrib if you're interested. Smiling

Ryan - I've done some testing of the recurring module with the CIM module. It seems to work quite well, just using the default handler (no work for me to do! Eye-wink) but I think I found a couple bugs and have a couple thoughts for you:

1) $method isn't defined in uc_recurring_charge. I think you can just replace it with 'credit' since that's the only option, right?

$func = $gateways[$keys[0]]['credit']; //EDIT from: $func = $gateways[$keys[0]][$method];

2) $order_id and $amount aren't defined in uc_recurring_charge either. Here's what I think the charge line should look like:

$result = $func($fee['order_id'], $fee['fee_amount'], NULL);  //EDIT from: $result = $func($order_id, $amount, NULL);

3) Your default handler works well with CIM (since CIM is just like charging a credit card normally, only the number isn't stored in your database) except for one line. In uc_recurring_recurring_fee you check that the payment method is 'credit'. In the CIM module I briefly change the payment method to 'cim' so that I can handle pre-orders / partial payments. What would you think about changing that line to:

if ($order->payment_method !== 'credit' && $order->payment_method !== 'cim') { //EDIT from: if ($order->payment_method !== 'credit')

4) I noticed that you commented out part of this query:

$result = db_query("SELECT * FROM {uc_recurring_users} WHERE remaining_intervals > 0"); // AND next_charge <= %d", time());

Was that just for testing, maybe?

5) I noticed that you're logging payments to the usual uc_payments table, which makes the order balance go negative. What do you think about using a new uc_recurring_payments table instead? There could be a pane or tab on the order page that shows those payments separately. Seems a little more intuitive...although a bit more work as well...

Hope that's helpful. I'll let you know if I come up with anything else.

Best,
Chad

Posts: 3192
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Chad, great feedback! I fixed the bugs you mentioned, but since the cim method isn't really a core feature I don't feel good about making a special exception for it in that if block. If it comes down to it, you may have to copy the functions and make your own recurring fee handler. Not a huge deal. We can brainstorm other solutions.

I love the idea of a recurring payment receipts table, too! Can't believe I didn't think of it. Eye-wink I won't put that into the beta 7 version, but put it on the feature list for the future.

Posts: 60
Joined: 12/28/2007
Bug FinderGetting busy with the Ubercode.

Sounds good, Ryan. I can take care of the cim method on my end...the easiest way might be for me to create a new handler, which just changes the payment method to credit briefly, calls your handler, then changes it back to cim. Alternatively, if you ever wanted to integrate support for partial payments and pre-orders into the uc_credit module, I could probably go back to leaving the payment method as credit in the cim module.

There is one other point that I think may be important. I believe that most payment gateway modules will need to mark recurring transactions as recurring when they're processed. (In Auth.net AIM this is the x_recurring_billing option). The card associations seem to require this, plus I've read some reports that setting this option can save you some transaction fees, since the recurring transactions (except for the first) won't have any CVV data and might otherwise get downgraded as a result. If anyone has any experience with this I'd be curious to get their input.

The thing I'm not sure about is how to handle an order that contains some recurring and some non-recurring items. Should the whole order be flagged as recurring to the gateway? Or should the recurring portion be charged separately, with the flag? Or can we wait until the automatic recurring charge is made (as opposed to the first charge made when the user checks out)?

I'm just not quite sure how this is supposed to work. If anyone has any experience with this, it would be very helpful.

Best,
Chad

Posts: 781
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

Just to chime in, Ryan, I'm not sure what changes you've made (haven't checked yet) - but I would suggest not making 'credit' the only method of a recurring payment. We have almost as many users who use PayPal compared to our Credit Card customers. It's more like 2/3 Credit and 1/3 PayPal... not a ton, but I think it's enough to keep the method of recurring payment flexible, if possible. Smiling

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 3192
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Aye, the recurring fee handler in core is simply a default one to work with the credit module. The other modules will need their own handlers if they're going to handle the fees, and in that case you'd enable them in the recurring fee product feature settings as valid payment methods.

I guess where the pinch is is that right now we use a single handler to process recurring fees. I guess that means you'd need a custom module to route it to the correct one depending on their payment method selection... which is unintended. Sticking out tongue

Good feedback, though... will have to work that out as we go. Thoughts? I wasn't intending to write a hook to declare fee handlers, but maybe I'll have to so you can choose a different one for every enabled payment method? Oof.

Posts: 781
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

If it's not a ton of work, I'd say that it's a great idea to write a handler to accept any payment method. This would be good for people writing their own custom payment methods, although writing their own handlers might not be a bad idea. I think even if we have to force users to user a Credit card to buy a subscription, that's not so bad. But I like having the option there for PayPal as well and anything else that comes down the road.

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 3192
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Oh yeah, as is it works off a hook on a per-module basis. So, any module implementing the hook will be listed in the settings menu as a recurring fee handler. You just can't specify a different handler depending on payment method right now. If you had a custom module and implemented your own hook_recurring_fee(), you could have that check $order->payment_method and kick out to a different charge function accordingly. So... it's possible, just roundabout right now. Sticking out tongue

Posts: 60
Joined: 12/28/2007
Bug FinderGetting busy with the Ubercode.

Ryan - I can think of two options:

1) Provide a recurring fee handler selection for each enabled payment method, as you mentioned above.

2) Provide a checkbox selection for each recurring fee handler and modify uc_recurring_process to call all enabled handlers. In this case it's each handler's responsibility to only process the appropriate orders, based on order->payment_method (like you do when you check for 'credit' in the default).

I think 2 would be easier to implement, but I'm not sure if order->payment_method is going to always be enough for a handler to know if it's the right one to process the fee. (I'm just not that familiar with how each gateway or payment method works). And there's a slight risk that if there are ever two handlers written for one payment method or gateway, then customers could get double charged if they're both enabled...but that seems unlikely to happen...

Chad

Posts: 83
Joined: 08/08/2007
Getting busy with the Ubercode.Not Kulvik

I put in the issue queue the postgres support. you should find it here:
http://www.ubercart.org/issue/3786/postgres_support_uc_recurring

Posts: 9
Joined: 03/04/2008

I am a total noob to UberCart. But so far it's great.
I need to set up recurring fees but the products themselves do not have the option to set the fee.
I may have something wrong it either the install, modules used, or general "no idea what I'm doing" arenas. Please feel free to correct me.
What I'm looking for is setting up recurring fees for specific items. Example, Access to a video tutorial that requires a monthly fee. It may be subscription, but I want to be able to manually cut users off. Kind of a long story, but this fits what I am doing better.
If I could figure out where the settings are.

Posts: 10
Joined: 04/04/2008

Don't know if you ever figured this out but it was driving me crazy too. You have to first enable recurring fees in the Product Features section of Store Configuration. Then create your product. Then go into Edit on the product and click the Features tab. That's where you can assign a recurring fee to your product. Not sure about manually cutting users off yet though.

--

Chisholm Technologies, Inc.
Custom software development since 1999!
www.chisholmtech.com

Posts: 10
Joined: 04/04/2008

Chad, did you ever resolve the issue of non-recurring items in the cart with recurring items? I wrote an e-commerce system (from scratch which I'll never do again but won't complain since I was paid pretty good for it) using ASP. The items they are selling are shippable items and class registrations which needed recurring payments to enable a deposit and balance payment two weeks before the class starts. To handle both types of items, I make two types of payments for the order during checkout... Recurring payment(s) and Authorize payment for the shippable items. My shipping tool on the backend enables the store manager to mark an item as shipped which automatically sends a Delayed Capture type payment. Not sure how you would handle it with Ubercart but I need to have this functionality for another client's site.

Here's the url for the class registration site...
www.trackerschool.com

--

Chisholm Technologies, Inc.
Custom software development since 1999!
www.chisholmtech.com

Posts: 10
Joined: 04/04/2008

Ryan, Is there any way to set the number of billing cycles so that it's indefinite? I'm using Chad's Authorize CIM module and was wondering about this.

--

Chisholm Technologies, Inc.
Custom software development since 1999!
www.chisholmtech.com

Posts: 9
Joined: 03/04/2008

Thanks for the help.
I did find out, because of your help, that if you set the billin cycles to nothing, it makes it indefinite. Hope that helps a little.