/** * Update contribution status - this is only called from one place in the code & * it is unclear whether it is a function on the way in or on the way out * * @param unknown_type $params * @return void|Ambigous <value, unknown, array> */ function updateContributionStatus(&$params) { // get minimum required values. $statusId = CRM_Utils_Array::value('contribution_status_id', $params); $componentId = CRM_Utils_Array::value('component_id', $params); $componentName = CRM_Utils_Array::value('componentName', $params); $contributionId = CRM_Utils_Array::value('contribution_id', $params); if (!$contributionId || !$componentId || !$componentName || !$statusId) { return; } $input = $ids = $objects = array(); //get the required ids. $ids['contribution'] = $contributionId; if (!($ids['contact'] = CRM_Utils_Array::value('contact_id', $params))) { $ids['contact'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'contact_id'); } if ($componentName == 'Event') { $name = 'event'; $ids['participant'] = $componentId; if (!($ids['event'] = CRM_Utils_Array::value('event_id', $params))) { $ids['event'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $componentId, 'event_id'); } } if ($componentName == 'Membership') { $name = 'contribute'; $ids['membership'] = $componentId; } $ids['contributionPage'] = NULL; $ids['contributionRecur'] = NULL; $input['component'] = $name; $baseIPN = new CRM_Core_Payment_BaseIPN(); $transaction = new CRM_Core_Transaction(); // reset template values. $template = CRM_Core_Smarty::singleton(); $template->clearTemplateVars(); if (!$baseIPN->validateData($input, $ids, $objects, FALSE)) { CRM_Core_Error::fatal(); } $contribution =& $objects['contribution']; $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $input['skipComponentSync'] = CRM_Utils_Array::value('skipComponentSync', $params); if ($statusId == array_search('Cancelled', $contributionStatuses)) { $baseIPN->cancelled($objects, $transaction, $input); $transaction->commit(); return $statusId; } elseif ($statusId == array_search('Failed', $contributionStatuses)) { $baseIPN->failed($objects, $transaction, $input); $transaction->commit(); return $statusId; } // status is not pending if ($contribution->contribution_status_id != array_search('Pending', $contributionStatuses)) { $transaction->commit(); return; } //set values for ipn code. foreach (array('fee_amount', 'check_number', 'payment_instrument_id') as $field) { if (!($input[$field] = CRM_Utils_Array::value($field, $params))) { $input[$field] = $contribution->{$field}; } } if (!($input['trxn_id'] = CRM_Utils_Array::value('trxn_id', $params))) { $input['trxn_id'] = $contribution->invoice_id; } if (!($input['amount'] = CRM_Utils_Array::value('total_amount', $params))) { $input['amount'] = $contribution->total_amount; } $input['is_test'] = $contribution->is_test; $input['net_amount'] = $contribution->net_amount; if (CRM_Utils_Array::value('fee_amount', $input) && CRM_Utils_Array::value('amount', $input)) { $input['net_amount'] = $input['amount'] - $input['fee_amount']; } //complete the contribution. $baseIPN->completeTransaction($input, $ids, $objects, $transaction, FALSE); // reset template values before processing next transactions $template->clearTemplateVars(); return $statusId; }
/** * 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($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); } // @todo required for base ipn but problematic as api layer handles this $transaction = new CRM_Core_Transaction(); $ipn = new CRM_Core_Payment_BaseIPN(); $ipn->completeTransaction($input, $ids, $objects, $transaction, !empty($contribution->contribution_recur_id)); return $params; }
/** * Update contribution status. * * @deprecated * This is only called from one place in the code & * it is unclear whether it is a function on the way in or on the way out * * @param array $params * * @return NULL|int */ public static function updateContributionStatus($params) { // get minimum required values. $statusId = CRM_Utils_Array::value('contribution_status_id', $params); $componentId = CRM_Utils_Array::value('component_id', $params); $componentName = CRM_Utils_Array::value('componentName', $params); $contributionId = CRM_Utils_Array::value('contribution_id', $params); if (!$contributionId || !$componentId || !$componentName || !$statusId) { return NULL; } $input = $ids = $objects = array(); //get the required ids. $ids['contribution'] = $contributionId; if (!($ids['contact'] = CRM_Utils_Array::value('contact_id', $params))) { $ids['contact'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'contact_id'); } if ($componentName == 'Event') { $name = 'event'; $ids['participant'] = $componentId; if (!($ids['event'] = CRM_Utils_Array::value('event_id', $params))) { $ids['event'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $componentId, 'event_id'); } } if ($componentName == 'Membership') { $name = 'contribute'; $ids['membership'] = $componentId; } $ids['contributionPage'] = NULL; $ids['contributionRecur'] = NULL; $input['component'] = $name; $baseIPN = new CRM_Core_Payment_BaseIPN(); $transaction = new CRM_Core_Transaction(); // reset template values. $template = CRM_Core_Smarty::singleton(); $template->clearTemplateVars(); if (!$baseIPN->validateData($input, $ids, $objects, FALSE)) { CRM_Core_Error::fatal(); } $contribution =& $objects['contribution']; $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array('labelColumn' => 'name', 'flip' => 1)); $input['IAmAHorribleNastyBeyondExcusableHackInTheCRMEventFORMTaskClassThatNeedsToBERemoved'] = CRM_Utils_Array::value('IAmAHorribleNastyBeyondExcusableHackInTheCRMEventFORMTaskClassThatNeedsToBERemoved', $params); if ($statusId == $contributionStatuses['Cancelled']) { $baseIPN->cancelled($objects, $transaction, $input); $transaction->commit(); return $statusId; } elseif ($statusId == $contributionStatuses['Failed']) { $baseIPN->failed($objects, $transaction, $input); $transaction->commit(); return $statusId; } // status is not pending if ($contribution->contribution_status_id != $contributionStatuses['Pending']) { $transaction->commit(); return; } //set values for ipn code. foreach (array('fee_amount', 'check_number', 'payment_instrument_id') as $field) { if (!($input[$field] = CRM_Utils_Array::value($field, $params))) { $input[$field] = $contribution->{$field}; } } if (!($input['trxn_id'] = CRM_Utils_Array::value('trxn_id', $params))) { $input['trxn_id'] = $contribution->invoice_id; } if (!($input['amount'] = CRM_Utils_Array::value('total_amount', $params))) { $input['amount'] = $contribution->total_amount; } $input['is_test'] = $contribution->is_test; $input['net_amount'] = $contribution->net_amount; if (!empty($input['fee_amount']) && !empty($input['amount'])) { $input['net_amount'] = $input['amount'] - $input['fee_amount']; } //complete the contribution. $baseIPN->completeTransaction($input, $ids, $objects, $transaction, FALSE); // reset template values before processing next transactions $template->clearTemplateVars(); return $statusId; }
/** * process the form after the input has been submitted and validated * * @access public * * @return None */ public function postProcess() { $params = $this->controller->exportValues($this->_name); $statusID = CRM_Utils_Array::value('contribution_status_id', $params); $baseIPN = new CRM_Core_Payment_BaseIPN(); $transaction = new CRM_Core_Transaction(); // get the missing pieces for each contribution $contribIDs = implode(',', $this->_contributionIds); $details = self::getDetails($contribIDs); $template = CRM_Core_Smarty::singleton(); // for each contribution id, we just call the baseIPN stuff foreach ($this->_rows as $row) { $input = $ids = $objects = array(); $input['component'] = $details[$row['contribution_id']]['component']; $ids['contact'] = $row['contact_id']; $ids['contribution'] = $row['contribution_id']; $ids['contributionRecur'] = NULL; $ids['contributionPage'] = NULL; $ids['membership'] = CRM_Utils_Array::value('membership', $details[$row['contribution_id']]); $ids['participant'] = CRM_Utils_Array::value('participant', $details[$row['contribution_id']]); $ids['event'] = CRM_Utils_Array::value('event', $details[$row['contribution_id']]); if (!$baseIPN->validateData($input, $ids, $objects, FALSE)) { CRM_Core_Error::fatal(); } $contribution =& $objects['contribution']; $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); if ($statusID == array_search('Cancelled', $contributionStatuses)) { $baseIPN->cancelled($objects, $transaction); $transaction->commit(); continue; } elseif ($statusID == array_search('Failed', $contributionStatuses)) { $baseIPN->failed($objects, $transaction); $transaction->commit(); continue; } // status is not pending if ($contribution->contribution_status_id != array_search('Pending', $contributionStatuses)) { $transaction->commit(); continue; } // set some fake input values so we can reuse IPN code $input['amount'] = $contribution->total_amount; $input['is_test'] = $contribution->is_test; $input['fee_amount'] = $params["fee_amount_{$row['contribution_id']}"]; $input['check_number'] = $params["check_number_{$row['contribution_id']}"]; $input['payment_instrument_id'] = $params["payment_instrument_id_{$row['contribution_id']}"]; $input['net_amount'] = $contribution->total_amount - $input['fee_amount']; if (!empty($params["trxn_id_{$row['contribution_id']}"])) { $input['trxn_id'] = trim($params["trxn_id_{$row['contribution_id']}"]); } else { $input['trxn_id'] = $contribution->invoice_id; } $input['trxn_date'] = CRM_Utils_Date::processDate($params["trxn_date_{$row['contribution_id']}"]); $baseIPN->completeTransaction($input, $ids, $objects, $transaction, FALSE); // reset template values before processing next transactions $template->clearTemplateVars(); } CRM_Core_Session::setStatus(ts('Contribution status has been updated for selected record(s).')); }
/** * Complete an existing (pending) transaction, updating related entities (participant, membership, pledge etc) * and taking any complete actions from the contribution page (e.g. send receipt) * * @todo - most of this should live in the BAO layer but as we want it to be an addition * to 4.3 which is already stable we should add it to the api layer & re-factor into the BAO layer later * * @param array $params input parameters * {@getfields Contribution_completetransaction} * @return array Api result array * @static void * @access public * */ function civicrm_api3_contribution_completetransaction(&$params) { $input = $ids = array(); $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $params['id']; $contribution->find(TRUE); if (!$contribution->id == $params['id']) { throw new API_Exception('A valid contribution ID is required', 'invalid_data'); } try { if (!$contribution->loadRelatedObjects($input, $ids, FALSE, TRUE)) { throw new API_Exception('failed to load related objects'); } $objects = $contribution->_relatedObjects; $objects['contribution'] =& $contribution; $input['component'] = $contribution->_component; $input['is_test'] = $contribution->is_test; $input['trxn_id'] = $contribution->trxn_id; $input['amount'] = $contribution->total_amount; if (isset($params['is_email_receipt'])) { $input['is_email_receipt'] = $params['is_email_receipt']; } // @todo required for base ipn but problematic as api layer handles this $transaction = new CRM_Core_Transaction(); $ipn = new CRM_Core_Payment_BaseIPN(); $ipn->completeTransaction($input, $ids, $objects, $transaction); } catch (Exception $e) { throw new API_Exception('failed to load related objects' . $e->getMessage() . "\n" . $e->getTraceAsString()); } }