I use recurring payments to renew my members' subscriptions.

I moved my site from ServerA to ServerB last week. The site sat on ServerB for one week and then, due to ServerB being fairly awful, I but the bullet and took a dedicated server at SoftLayer, ServerC.

Now, no renewals were scheduled to process during this time. However, when the site arrived onto ServerC I had three renewals the following day.

Disaster, all three renewals processed THREE times. After a lot of testing and trying to get to the bottom of it I suddenly realized that the site was running on all three servers and even though I had migrated the domain to the new server the old ones still had cron jobs running. So, three servers each had cron hitting DOMAIN.com/cron.php.

I would have expected that when the first one ran, the renewal would occur and it would have been flagged as PAID but I think the issue is that cron runs at the exact same time(?) on each server.

I removed the old cron jobs, did some testing and all is now fine.

So, in summary it appears that having multiple cron jobs running will result in multiple renewals.

Server B proved to be a p

CommentFileSizeAuthor
#5 uc_recurring-1045508.patch1.3 KBunivate

Comments

univate’s picture

Category: bug » support

Correct, not sure how this is a bug though? Each site will have its own database and there is no way it can know there is another site.

There is an option in the admin settings under recurring payments to disable renewals on cron runs.

There is also a method stated in the readme file:

If need to take snapshots of live databases with recurring fees setup ensure
that cron is not running on your test site or recurring payments may be
triggered from your test and live installs.

A simple way to ensure recurring payments are not triggered on cron runs is to
add the following php to your test sites settings.php

<?php
// disable ubercart recurring payments
$conf['uc_recurring_trigger_renewals'] = FALSE;
?>

paulcoghlan’s picture

univate, thanks for taking the time to reply. I guess as a user I just wanted to raise the flag in case it was considered an issue.

It seems that anyone could cause problems on my site then by repeatedly hitting mydomain/cron.php. I thought that maybe the first transaction (i.e. the first cron to pick up the renewal) would block off that renewal so that other processes wouldn't replicate the payment.

Paul

tinker’s picture

The CRON script only executed once on each server and running CRON multiple times on one server is not the same thing. There are conditional measures in place that make sure that transactions are only processed once on a server even though CRON can run multiple times a day.

paulcoghlan’s picture

tinker, sorry but I think that is incorrect.

All three servers had a cron job as below:

wget -q -O - http://www.MYDOMAIN.com/cron.php

So, all three servers were pointed at the same server, the new one as that is where DOMAIN.com pointed.

Hence, the new server would have had three instances of the cron script running.

univate’s picture

Title: Double billing on recurring payments » Add a lock to the renewal process and limit execution time to 30seconds
Category: support » feature
Status: Active » Needs review
StatusFileSize
new1.3 KB

I guess its possible if cron was triggered at exactly the same time this could happen. Although I am curious as to whether these multiple orders are showing up in the same drupal site, are there three new orders in the site or is the multiple payments showing up in the payment gateway?

I have had a TODO in the code, where I have wanted to limit the number of renewals processed on a cron run. We probably could also add a lock into this function as well to ensure the renewals in cron can only be executed by one process.

paulcoghlan’s picture

Thanks univate.

I am by NO means a technical person but having worked with financial institutions and databases in the past I would humbly suggest that the instant one process starts a transaction that record placed in a locked state so no other process can accidentally duplicate the work effort. This should also cater for a machine failure in the middle of a transaction. It might sound unlikely but you never know...

I am just a luddite user trying to help.

Paul

univate’s picture

Would help to know...

Although I am curious as to whether these multiple orders are showing up in the same drupal site, are there three new orders in the site or is the multiple payments showing up in the payment gateway?

univate’s picture

Status: Needs review » Fixed

I have committed that lock fix above.

paulcoghlan’s picture

Apologies, I realize now I ignored a request in your prior message.

The three orders all appeared in the new server. I think that makes sense as the three servers would all hit the cron on the new server.

Paul

Status: Fixed » Closed (fixed)
Issue tags: -cron, -Ubercart, -renewals

Automatically closed -- issue fixed for 2 weeks with no activity.