Skip to content

Commit

Permalink
Merge pull request #22475 from eileenmcnaughton/ipn
Browse files Browse the repository at this point in the history
Revert membership debug handling in IPN
  • Loading branch information
colemanw authored Feb 23, 2022
2 parents 72d90df + 19d9044 commit 00b4e46
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 102 deletions.
33 changes: 0 additions & 33 deletions CRM/Contribute/BAO/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -967,27 +967,6 @@ protected static function getRelatedMemberships(int $contributionID): array {
])['values'];
}

/**
* It is possible to override the membership id that is updated from the payment processor.
*
* Historically Paypal does this & it still does if it determines data is messed up - see
* https://lab.civicrm.org/dev/membership/issues/13
*
* Read the comment block on repeattransaction for more information
* about how things should work.
*
* @param int $contributionID
* @param array $input
*
* @throws \CiviCRM_API3_Exception
*/
protected static function handleMembershipIDOverride($contributionID, $input) {
if (!empty($input['membership_id'])) {
Civi::log()->debug('The related membership id has been overridden - this may impact data - see https://github.com/civicrm/civicrm-core/pull/15053');
civicrm_api3('MembershipPayment', 'create', ['contribution_id' => $contributionID, 'membership_id' => $input['membership_id']]);
}
}

/**
* Get transaction information about the contribution.
*
Expand Down Expand Up @@ -2210,17 +2189,6 @@ public static function contributionCount($contactId, $includeSoftCredit = TRUE)
* 2) repeattransaction code is current munged into completeTransaction code for historical bad coding reasons
* 3) Repeat transaction duplicates rather than calls Order.create
* 4) Use of payment.create still limited - completetransaction is more common.
* 6) the determination of the membership to be linked is tricksy. The prioritised method is
* to load the membership(s) referred to via line items in the template transactions. Any other
* method is likely to lead to incorrect line items & related entities being created (as the line_item
* link is a required part of 'correct data'). However there are 3 other methods to determine it
* - membership_payment record
* - civicrm_membership.contribution_recur_id
* - input override.
* Passing in an input override WILL ensure the membership is extended to prevent regressions
* of historical processors since this has been handled 'forever' - specifically for paypal.
* albeit by an even nastier mechanism than the current input override.
* The count is out on how correct related entities wind up in this case.
*/
protected static function repeatTransaction(array $input, array $contributionParams) {
$templateContribution = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution(
Expand All @@ -2246,7 +2214,6 @@ protected static function repeatTransaction(array $input, array $contributionPar
$createContribution = civicrm_api3('Contribution', 'create', $contributionParams);
$temporaryObject = new CRM_Contribute_BAO_Contribution();
$temporaryObject->copyCustomFields($templateContribution['id'], $createContribution['id']);
self::handleMembershipIDOverride($createContribution['id'], $input);
// Add new soft credit against current $contribution.
CRM_Contribute_BAO_ContributionRecur::addrecurSoftCredit($contributionParams['contribution_recur_id'], $createContribution['id']);
return $createContribution;
Expand Down
26 changes: 0 additions & 26 deletions CRM/Core/Payment/PayPalIPN.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,37 +229,11 @@ public function main() {
$input['component'] = $component;

$contributionID = $this->getContributionID();
$membershipID = $this->retrieve('membershipID', 'Integer', FALSE);

$this->getInput($input);

$paymentProcessorID = $this->getPayPalPaymentProcessorID($input, $this->getContributionRecurID());

Civi::log()->debug('PayPalIPN: Received (ContactID: ' . $this->getContactID() . '; trxn_id: ' . $input['trxn_id'] . ').');

// Debugging related to possible missing membership linkage
if ($this->getContributionRecurID() && $this->retrieve('membershipID', 'Integer', FALSE)) {
$templateContribution = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($this->getContributionRecurID());
$membershipPayment = civicrm_api3('MembershipPayment', 'get', [
'contribution_id' => $templateContribution['id'],
'membership_id' => $membershipID,
]);
$lineItems = civicrm_api3('LineItem', 'get', [
'contribution_id' => $templateContribution['id'],
'entity_id' => $membershipID,
'entity_table' => 'civicrm_membership',
]);
Civi::log()->debug('PayPalIPN: Received payment for membership ' . (int) $membershipID
. '. Original contribution was ' . (int) $contributionID . '. The template for this contribution is '
. $templateContribution['id'] . ' it is linked to ' . $membershipPayment['count']
. 'payments for this membership. It has ' . $lineItems['count'] . ' line items linked to this membership.'
. ' it is expected the original contribution will be linked by both entities to the membership.'
);
if (empty($membershipPayment['count']) && empty($lineItems['count'])) {
Civi::log()->debug('PayPalIPN: Will attempt to compensate');
$input['membership_id'] = $this->retrieve('membershipID', 'Integer', FALSE);
}
}
$contribution = $this->getContribution();

$input['payment_processor_id'] = $paymentProcessorID;
Expand Down
1 change: 0 additions & 1 deletion api/v3/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,6 @@ function civicrm_api3_contribution_repeattransaction($params) {
'fee_amount',
'financial_type_id',
'contribution_status_id',
'membership_id',
'payment_processor_id',
];
$input = array_intersect_key($params, array_fill_keys($passThroughParams, NULL));
Expand Down
42 changes: 0 additions & 42 deletions tests/phpunit/CRM/Core/Payment/PayPalIPNTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,48 +198,6 @@ public function testIPNPaymentMembershipRecurSuccess(): void {
$this->callAPISuccessGetSingle('membership_payment', ['contribution_id' => $contribution['values'][1]['id']]);
}

/**
* Test IPN that we can force membership when the membership payment has been deleted.
*
* https://lab.civicrm.org/dev/membership/issues/13
*
* In this scenario the membership payment record was deleted (or not created) for the first contribution but we
* 'recover' by using the input membership id.
*
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
public function testIPNPaymentInputMembershipRecurSuccess(): void {
$durationUnit = 'year';
$this->setupMembershipRecurringPaymentProcessorTransaction(['duration_unit' => $durationUnit, 'frequency_unit' => $durationUnit]);
$membershipPayment = $this->callAPISuccessGetSingle('membership_payment', []);
$paypalIPN = new CRM_Core_Payment_PayPalIPN(array_merge($this->getPaypalRecurTransaction(), ['membershipID' => $membershipPayment['membership_id']]));
$paypalIPN->main();
$membershipEndDate = $this->callAPISuccessGetValue('membership', ['return' => 'end_date']);
CRM_Core_DAO::executeQuery('DELETE FROM civicrm_membership_payment WHERE id = ' . $membershipPayment['id']);
CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item SET entity_table = 'civicrm_contribution' WHERE entity_table = 'civicrm_membership'");

$paypalIPN = new CRM_Core_Payment_PaypalIPN(array_merge($this->getPaypalRecurSubsequentTransaction(), ['membershipID' => $membershipPayment['membership_id']]));
$paypalIPN->main();
$renewedMembershipEndDate = $this->membershipRenewalDate($durationUnit, $membershipEndDate);
$this->assertEquals($renewedMembershipEndDate, $this->callAPISuccessGetValue('membership', ['return' => 'end_date']));
$contribution = $this->callAPISuccess('contribution', 'get', [
'contribution_recur_id' => $this->_contributionRecurID,
'sequential' => 1,
]);
$this->assertEquals(2, $contribution['count']);
$this->assertEquals('secondone', $contribution['values'][1]['trxn_id']);
$this->callAPISuccessGetCount('line_item', [
'entity_id' => $this->ids['membership'],
'entity_table' => 'civicrm_membership',
], 1);
$this->callAPISuccessGetSingle('line_item', [
'contribution_id' => $contribution['values'][1]['id'],
'entity_table' => 'civicrm_membership',
]);
$this->callAPISuccessGetSingle('membership_payment', ['contribution_id' => $contribution['values'][1]['id']]);
}

/**
* Get IPN style details for an incoming recurring transaction.
*/
Expand Down

0 comments on commit 00b4e46

Please sign in to comment.