/** * Calls IPN complete transaction for completing or repeating a transaction. * * The IPN function is overloaded with two purposes - this is simply a wrapper for that * when separating them in the api layer. * * @param array $params * @param CRM_Contribute_BAO_Contribution $contribution * @param array $input * * @param array $ids * * @param CRM_Contribute_BAO_Contribution $firstContribution * * @return mixed */ function _ipn_process_transaction(&$params, $contribution, $input, $ids, $firstContribution = NULL) { $objects = $contribution->_relatedObjects; $objects['contribution'] =& $contribution; if ($firstContribution) { $objects['first_contribution'] = $firstContribution; } $input['component'] = $contribution->_component; $input['is_test'] = $contribution->is_test; $input['amount'] = empty($input['total_amount']) ? $contribution->total_amount : $input['total_amount']; if (isset($params['is_email_receipt'])) { $input['is_email_receipt'] = $params['is_email_receipt']; } if (!empty($params['trxn_date'])) { $input['trxn_date'] = $params['trxn_date']; } if (empty($contribution->contribution_page_id)) { static $domainFromName; static $domainFromEmail; if (empty($domainFromEmail) && (empty($params['receipt_from_name']) || empty($params['receipt_from_email']))) { list($domainFromName, $domainFromEmail) = CRM_Core_BAO_Domain::getNameAndEmail(TRUE); } $input['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $params, $domainFromName); $input['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', $params, $domainFromEmail); } $transaction = new CRM_Core_Transaction(); CRM_Contribute_BAO_Contribution::completeOrder($input, $ids, $objects, $transaction, !empty($contribution->contribution_recur_id), $contribution, FALSE, FALSE); return $params; }
/** * Jumbled up function. * * The purpose of this function is to transition a pending transaction to Completed including updating any * related entities. * * It has been overloaded to also add recurring transactions to the database, cloning the original transaction and * updating related entities. * * It is recommended to avoid calling this function directly and call the api functions: * - contribution.completetransaction * - contribution.repeattransaction * * These functions are the focus of testing efforts and more accurately reflect the division of roles * (the job of the IPN class is to determine the outcome, transaction id, invoice id & to validate the source * and from there it should be possible to pass off transaction management.) * * This function has been problematic for some time but there are now several tests via the api_v3_Contribution test * and the Paypal & Authorize.net IPN tests so any refactoring should be done in conjunction with those. * * This function needs to have the 'body' moved to the CRM_Contribution_BAO_Contribute class and to undergo * refactoring to separate the complete transaction and repeat transaction functionality into separate functions with * a shared function that updates related components. * * Note that it is not necessary payment processor extension to implement an IPN class now. In general the code on the * IPN class is better accessed through the api which de-jumbles it a bit. * * e.g the payment class can have a function like (based on Omnipay extension): * * public function handlePaymentNotification() { * $response = $this->getValidatedOutcome(); * if ($response->isSuccessful()) { * try { * // @todo check if it is a repeat transaction & call repeattransaction instead. * civicrm_api3('contribution', 'completetransaction', array('id' => $this->transaction_id)); * } * catch (CiviCRM_API3_Exception $e) { * if (!stristr($e->getMessage(), 'Contribution already completed')) { * $this->handleError('error', $this->transaction_id . $e->getMessage(), 'ipn_completion', 9000, 'An error may * have occurred. Please check your receipt is correct'); * $this->redirectOrExit('success'); * } * elseif ($this->transaction_id) { * civicrm_api3('contribution', 'create', array('id' => $this->transaction_id, 'contribution_status_id' => * 'Failed')); * } * * @param array $input * @param array $ids * @param array $objects * @param CRM_Core_Transaction $transaction * @param bool $recur */ public function completeTransaction(&$input, &$ids, &$objects, &$transaction, $recur = FALSE) { $isRecurring = $this->_isRecurring; $isFirstOrLastRecurringPayment = $this->_isFirstOrLastRecurringPayment; $contribution =& $objects['contribution']; CRM_Contribute_BAO_Contribution::completeOrder($input, $ids, $objects, $transaction, $recur, $contribution, $isRecurring, $isFirstOrLastRecurringPayment); }