Skip to content

Commit

Permalink
Move recurring handling to recur function in PaypalIPN
Browse files Browse the repository at this point in the history
The recur() call has some wranling leading into it that prepares the variables
for the function. This moves that wrangling to the recur() function.
  • Loading branch information
eileenmcnaughton committed Jun 18, 2023
1 parent 8efccf9 commit 25bcecf
Showing 1 changed file with 46 additions and 63 deletions.
109 changes: 46 additions & 63 deletions CRM/Core/Payment/PayPalIPN.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,22 @@ public function retrieve($name, $type, $abort = TRUE) {
*
* @throws \CRM_Core_Exception
*/
public function recur($input, $recur, $contribution, $first) {

public function recur($input, $contribution) {
$contributionRecur = new CRM_Contribute_BAO_ContributionRecur();
$contributionRecur->id = $this->getContributionRecurID();
if (!$contributionRecur->find(TRUE)) {
throw new CRM_Core_Exception('Could not find contribution contributionRecur record');
}
// check if first contribution is completed, else complete first contribution
$first = TRUE;
$completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed');
if ($contribution->contribution_status_id == $completedStatusId) {
$first = FALSE;
}
// make sure the invoice ids match
// make sure the invoice is valid and matches what we have in the contribution record
if ($recur->invoice_id != $input['invoice']) {
Civi::log()->debug('PayPalIPN: Invoice values dont match between database and IPN request (RecurID: ' . $recur->id . ').');
if ($contributionRecur->invoice_id != $input['invoice']) {
Civi::log()->debug('PayPalIPN: Invoice values dont match between database and IPN request (RecurID: ' . $contributionRecur->id . ').');
throw new CRM_Core_Exception("Failure: Invoice values dont match between database and IPN request");
}

Expand All @@ -83,43 +93,55 @@ public function recur($input, $recur, $contribution, $first) {
$contributionStatuses = array_flip(CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate'));
switch ($this->getTrxnType()) {
case 'subscr_signup':
$recur->create_date = $now;
$contributionRecur->create_date = $now;
// sometimes subscr_signup response come after the subscr_payment and set to pending mode.

$statusID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionRecur',
$recur->id, 'contribution_status_id'
$contributionRecur->id, 'contribution_status_id'
);
if ($statusID != $contributionStatuses['In Progress']) {
$recur->contribution_status_id = $contributionStatuses['Pending'];
$contributionRecur->contribution_status_id = $contributionStatuses['Pending'];
}
$recur->processor_id = $this->retrieve('subscr_id', 'String');
$recur->trxn_id = $recur->processor_id;
$recur->save();
$contributionRecur->processor_id = $this->retrieve('subscr_id', 'String');
$contributionRecur->trxn_id = $contributionRecur->processor_id;
$contributionRecur->save();
//send recurring Notification email for user
CRM_Contribute_BAO_ContributionPage::recurringNotify(
$this->getContributionID(),
CRM_Core_Payment::RECURRING_PAYMENT_START,
$contributionRecur
);
return;

case 'subscr_eot':
if ($recur->contribution_status_id != $contributionStatuses['Cancelled']) {
$recur->contribution_status_id = $contributionStatuses['Completed'];
if ($contributionRecur->contribution_status_id != $contributionStatuses['Cancelled']) {
$contributionRecur->contribution_status_id = $contributionStatuses['Completed'];
}
$recur->end_date = $now;
$recur->save();
$contributionRecur->end_date = $now;
$contributionRecur->save();
//send recurring Notification email for user
CRM_Contribute_BAO_ContributionPage::recurringNotify(
$this->getContributionID(),
CRM_Core_Payment::RECURRING_PAYMENT_END,
$contributionRecur
);
return;

case 'subscr_cancel':
$recur->contribution_status_id = $contributionStatuses['Cancelled'];
$recur->cancel_date = $now;
$recur->save();
$contributionRecur->contribution_status_id = $contributionStatuses['Cancelled'];
$contributionRecur->cancel_date = $now;
$contributionRecur->save();
return;

case 'subscr_failed':
$recur->contribution_status_id = $contributionStatuses['Failed'];
$recur->modified_date = $now;
$recur->save();
$contributionRecur->contribution_status_id = $contributionStatuses['Failed'];
$contributionRecur->modified_date = $now;
$contributionRecur->save();
break;

case 'subscr_modify':
Civi::log()->debug('PayPalIPN: We do not handle modifications to subscriptions right now (RecurID: ' . $recur->id . ').');
echo "Failure: We do not handle modifications to subscriptions right now<p>";
Civi::log()->debug('PayPalIPN: We do not handle modifications to subscriptions right now (RecurID: ' . $contributionRecur->id . ').');
echo 'Failure: We do not handle modifications to subscriptions right now<p>';
return;

}
Expand Down Expand Up @@ -152,7 +174,7 @@ public function recur($input, $recur, $contribution, $first) {
// Also consider accepting 'Failed' like other processors.
$input['contribution_status_id'] = $contributionStatuses['Completed'];
$input['original_contribution_id'] = $contribution->id;
$input['contribution_recur_id'] = $recur->id;
$input['contribution_recur_id'] = $contributionRecur->id;

civicrm_api3('Contribution', 'repeattransaction', $input);
return;
Expand Down Expand Up @@ -223,26 +245,7 @@ public function main() {
$input['payment_processor_id'] = $paymentProcessorID;

if ($this->getContributionRecurID()) {
$contributionRecur = new CRM_Contribute_BAO_ContributionRecur();
$contributionRecur->id = $this->getContributionRecurID();
if (!$contributionRecur->find(TRUE)) {
throw new CRM_Core_Exception('Could not find contribution recur record');
}
// check if first contribution is completed, else complete first contribution
$first = TRUE;
$completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed');
if ($contribution->contribution_status_id == $completedStatusId) {
$first = FALSE;
}
$this->recur($input, $contributionRecur, $contribution, $first);
if ($this->getFirstOrLastInSeriesStatus()) {
//send recurring Notification email for user
CRM_Contribute_BAO_ContributionPage::recurringNotify(
$contributionID,
$this->getFirstOrLastInSeriesStatus(),
$contributionRecur
);
}
$this->recur($input, $contribution);
return;
}

Expand Down Expand Up @@ -379,26 +382,6 @@ protected function getTrxnType() {
return $this->retrieve('txn_type', 'String');
}

/**
* Get status code for first or last recurring in the series.
*
* If this is the first or last then return the status code, else
* null.
*
* @return string|null
* @throws \CRM_Core_Exception
*/
protected function getFirstOrLastInSeriesStatus(): ?string {
$subscriptionPaymentStatus = NULL;
if ($this->getTrxnType() === 'subscr_signup') {
return CRM_Core_Payment::RECURRING_PAYMENT_START;
}
if ($this->getTrxnType() === 'subscr_eot') {
return CRM_Core_Payment::RECURRING_PAYMENT_END;
}
return NULL;
}

/**
* Get the recurring contribution ID.
*
Expand Down

0 comments on commit 25bcecf

Please sign in to comment.