Page MenuHomePhabricator

Recurring contributions can be incorrectly marked as failing, resulting in double charges
Open, MediumPublic

Description

This seems to be affecting a small number of donors. For example, cid 10448807 had a recurring processed on Jan 15. At that point, the recurring was marked as failing and so the next scheduled contribution date was set to 24 hours in the future. That second donation was processed 24 hours later, resetting the recurring status to In Progress as normal. Net result is the donor was charged twice in two days for their recurring donation.

Relevant log entries:

Jan 15 12:44:51 civi1002 civicrm.wmf[243921]: civicrm.wmf.INFO: Error: 1000011 invoice_id:238491027.4 [] []

civi1002 SmashPig-Gravy-QueueJobRunner: SPCID-1878534593 | (corr_id-gravy-238491027.4) Could not find donor details for authorization Reference '5d625e9a-4c9b-459a-acaf-bc41fd70502d' and order ID '238491027.4'. | |

Raw response: {"type":"error","code":"server_error","status":500,"message":"Request could not be processed","details":[]}

Looks like this is coming from the catch in CRM_Core_Payment_SmashPigRecurringProcessor::run, which is covering a lot of code. Not sure how we want to handle this specific case, but in general maybe we shouldn't be moving the next scheduled date to tomorrow for exceptions that happen anywhere in there, as they could potentially be other issues?

Other affected cids from the first half of January: 11387385, 69254563, 48042218, 33996709, 68966936, 40702630, 12852049
There also appears to be a worse related issue, where the recurring is cancelled even though the actual contributions did not fail and we charged them twice, see cids 29466083, 69242387, 69258334
Many of these appear to have happened with Venmo, particularly on Jan 4, but they aren't exclusively Venmo.

SK used to find these (adjusting dates).

Event Timeline

@Ejegg has a solution for the first case. In the second case, where we have already cancelled the recurring contribution itself, we should make sure we are clearing cancel reason, end date, etc when we are un-cancelling.

Interestingly, we had 11 of these in January, but only ~6 in the rest of the fiscal year (fairly evenly distributed).

This takes ~15 minutes, but gives a list of relevant donations (ignore the ones that are for Fr-tech staff):

SELECT
`a`.`id` AS `id`,
`Contact_Contribution_contact_id_01`.`id`,
`Contact_Contribution_contact_id_01`.`receive_date`,
`Contact_Contribution_contact_id_02`.`id`,
`Contact_Contribution_contact_id_02`.`receive_date`
FROM `civicrm_contact` a
INNER JOIN (`civicrm_contribution` `Contact_Contribution_contact_id_01`)
ON `a`.`id` = `Contact_Contribution_contact_id_01`.`contact_id`
AND `Contact_Contribution_contact_id_01`.`receive_date` >= "20250701000000"
AND `Contact_Contribution_contact_id_01`.`contribution_recur_id` IS NOT NULL
AND `Contact_Contribution_contact_id_01`.`is_template` = 0
AND `Contact_Contribution_contact_id_01`.`contribution_status_id` = "1"
INNER JOIN (`civicrm_contribution` `Contact_Contribution_contact_id_02`)
ON `a`.`id` = `Contact_Contribution_contact_id_02`.`contact_id`
AND `Contact_Contribution_contact_id_02`.`total_amount` = `Contact_Contribution_contact_id_01`.`total_amount`
AND `Contact_Contribution_contact_id_02`.`contribution_recur_id` = `Contact_Contribution_contact_id_01`.`contribution_recur_id`
AND `Contact_Contribution_contact_id_02`.`receive_date` <= DATE_ADD(`Contact_Contribution_contact_id_01`.`receive_date`, INTERVAL 3 DAY)
AND `Contact_Contribution_contact_id_02`.`id` != `Contact_Contribution_contact_id_01`.`id`
AND `Contact_Contribution_contact_id_02`.`receive_date` > `Contact_Contribution_contact_id_01`.`receive_date`
AND `Contact_Contribution_contact_id_02`.`is_template` = 0
AND `Contact_Contribution_contact_id_02`.`contribution_status_id` = "1";

Group TEMP - T417088 Contacts with doubled recurring payments this FY has the affected contacts

Turns out a number of these were really failed, but added as completed in Civi by audit, see Slack

XenoRyet triaged this task as Medium priority.Feb 17 2026, 9:05 PM