Details
-
Type: Improvement
-
Status: Done/Fixed
-
Priority: Minor
-
Resolution: Fixed/Completed
-
Affects Version/s: 3.3.5
-
Fix Version/s: 3.4.alpha
-
Component/s: CiviContribute
-
Labels:None
Description
When PayPal is unable to charge a user for a payment in a subscription, a subscr_failed IPN is sent. CiviCRM currently handles this by setting the recur.contribution_status_id to 4 (Failed), and setting recur.cancel_date. Setting the status to 4 is okay, but it's not correct to set the recur.cancel_date, because PayPal will continue to try to charge the contributor 2 more times after the first subscr_failed IPN, and it's very likely that the user will react to the failure, since presumably PayPal notifies them as well, and they update their credit card information, for example, so that the next attempt by PayPal goes through. In that case, we don't want recur.cancel_date set. recur.cancel_date should only be set when a subscr_cancelled IPN is sent. For how this is currently handled see:
./CRM/Core/Payment/PayPalIPN.php:129
In the case where a subscription payment utterly fails, PayPal will work like this:
1) subscription payment fails
2) send subscr_failed IPN, wait 3 or 4 days
3) try payment again, if it fails, send another subscr_failed IPN, wait 3 or 4 days
4) try payment again, if it fails, send a subscr_cancelled IPN, and also a subscr_eot IPN
This brings up another issue. On line 117 of the above file a subscr_eot IPN automatically sets the contribution_status_id to 1 (Completed), but in the case of a failure this is incorrect, since the contribution was cancelled by PayPal. Why PayPal sends a subscr_cancelled and then a subscr_eot, I have no idea, but they do. If the subscription is already in a cancelled state then the subscr_eot IPN probably shouldn't do anything at all, else the database will show it was completed when it has really been cancelled. Side note: $sendNotification is set to true for subscr_eot IPN, but this may not be categorically the correct action if the payment failed and the subscription was cancelled.
The attached trivial, untested patch will likely fix this. Since we don't use CiviCRM to process IPN I have no way to test. Someone should also review how failed payments are handled and whether $sendNotification should be set when a subscription payment fails and a subscr_eot IPN is received.