Ejemplo n.º 1
0
 /**
  * Process recurring contributions
  * @param array $input
  * @param array $ids
  * @param array $objects
  * @param boolean $first
  * @return void|boolean
  */
 function recur(&$input, &$ids, &$objects, $first)
 {
     if (!isset($input['txnType'])) {
         CRM_Core_Error::debug_log_message("Could not find txn_type in input request");
         echo "Failure: Invalid parameters<p>";
         return FALSE;
     }
     if ($input['txnType'] == 'recurring_payment' && $input['paymentStatus'] != 'Completed') {
         CRM_Core_Error::debug_log_message("Ignore all IPN payments that are not completed");
         echo "Failure: Invalid parameters<p>";
         return FALSE;
     }
     $recur =& $objects['contributionRecur'];
     // 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']) {
         CRM_Core_Error::debug_log_message("Invoice values dont match between database and IPN request recur is " . $recur->invoice_id . " input is " . $input['invoice']);
         echo "Failure: Invoice values dont match between database and IPN request recur is " . $recur->invoice_id . " input is " . $input['invoice'];
         return FALSE;
     }
     $now = date('YmdHis');
     // fix dates that already exist
     $dates = array('create', 'start', 'end', 'cancel', 'modified');
     foreach ($dates as $date) {
         $name = "{$date}_date";
         if ($recur->{$name}) {
             $recur->{$name} = CRM_Utils_Date::isoToMysql($recur->{$name});
         }
     }
     $sendNotification = FALSE;
     $subscriptionPaymentStatus = NULL;
     //List of Transaction Type
     /*
      recurring_payment_profile_created          RP Profile Created
      recurring_payment           RP Sucessful Payment
      recurring_payment_failed                               RP Failed Payment
      recurring_payment_profile_cancel           RP Profile Cancelled
      recurring_payment_expired         RP Profile Expired
      recurring_payment_skipped        RP Profile Skipped
      recurring_payment_outstanding_payment      RP Sucessful Outstanding Payment
      recurring_payment_outstanding_payment_failed          RP Failed Outstanding Payment
      recurring_payment_suspended        RP Profile Suspended
      recurring_payment_suspended_due_to_max_failed_payment  RP Profile Suspended due to Max Failed Payment
     */
     //set transaction type
     $txnType = $this->retrieve('txn_type', 'String');
     //Changes for paypal pro recurring payment
     $contributionStatuses = civicrm_api3('contribution', 'getoptions', array('field' => 'contribution_status_id'));
     $contributionStatuses = $contributionStatuses['values'];
     switch ($txnType) {
         case 'recurring_payment_profile_created':
             if (in_array($recur->contribution_status_id, array(array_search('Pending', $contributionStatuses), array_search('In Progress', $contributionStatuses))) && !empty($recur->processor_id)) {
                 echo "already handled";
                 return;
             }
             $recur->create_date = $now;
             $recur->contribution_status_id = 2;
             $recur->processor_id = $this->retrieve('recurring_payment_id', 'String');
             $recur->trxn_id = $recur->processor_id;
             $subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_START;
             $sendNotification = TRUE;
             break;
         case 'recurring_payment':
             if ($first) {
                 $recur->start_date = $now;
             } else {
                 $recur->modified_date = $now;
             }
             //contribution installment is completed
             if ($this->retrieve('profile_status', 'String') == 'Expired') {
                 if (!empty($recur->end_date)) {
                     echo "already handled";
                     return;
                 }
                 $recur->contribution_status_id = 1;
                 $recur->end_date = $now;
                 $sendNotification = TRUE;
                 $subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_END;
             }
             // make sure the contribution status is not done
             // since order of ipn's is unknown
             if ($recur->contribution_status_id != 1) {
                 $recur->contribution_status_id = 5;
             }
             break;
     }
     $recur->save();
     if ($sendNotification) {
         $autoRenewMembership = FALSE;
         if ($recur->id && isset($ids['membership']) && $ids['membership']) {
             $autoRenewMembership = TRUE;
         }
         //send recurring Notification email for user
         CRM_Contribute_BAO_ContributionPage::recurringNotify($subscriptionPaymentStatus, $ids['contact'], $ids['contributionPage'], $recur, $autoRenewMembership);
     }
     if ($txnType != 'recurring_payment') {
         return;
     }
     if (!$first) {
         //check if this contribution transaction is already processed
         //if not create a contribution and then get it processed
         $contribution = new CRM_Contribute_BAO_Contribution();
         $contribution->trxn_id = $input['trxn_id'];
         if ($contribution->trxn_id && $contribution->find()) {
             CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
             echo "Success: Contribution has already been handled<p>";
             return TRUE;
         }
         $contribution->contact_id = $recur->contact_id;
         $contribution->financial_type_id = $objects['contributionType']->id;
         $contribution->contribution_page_id = $ids['contributionPage'];
         $contribution->contribution_recur_id = $ids['contributionRecur'];
         $contribution->currency = $objects['contribution']->currency;
         $contribution->payment_instrument_id = $objects['contribution']->payment_instrument_id;
         $contribution->amount_level = $objects['contribution']->amount_level;
         $contribution->campaign_id = $objects['contribution']->campaign_id;
         $objects['contribution'] =& $contribution;
     }
     // CRM-13737 - am not aware of any reason why payment_date would not be set - this if is a belt & braces
     $objects['contribution']->receive_date = !empty($input['payment_date']) ? date('YmdHis', strtotime($input['payment_date'])) : $now;
     $this->single($input, $ids, $objects, TRUE, $first);
 }
Ejemplo n.º 2
0
 /**
  * @param $input
  * @param $ids
  * @param $objects
  * @param $first
  *
  * @return bool
  */
 public function recur(&$input, &$ids, &$objects, $first)
 {
     if (!isset($input['txnType'])) {
         CRM_Core_Error::debug_log_message("Could not find txn_type in input request");
         echo "Failure: Invalid parameters<p>";
         return FALSE;
     }
     if ($input['txnType'] == 'subscr_payment' && $input['paymentStatus'] != 'Completed') {
         CRM_Core_Error::debug_log_message("Ignore all IPN payments that are not completed");
         echo "Failure: Invalid parameters<p>";
         return FALSE;
     }
     $recur =& $objects['contributionRecur'];
     // 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']) {
         CRM_Core_Error::debug_log_message("Invoice values dont match between database and IPN request");
         echo "Failure: Invoice values dont match between database and IPN request<p>";
         return FALSE;
     }
     $now = date('YmdHis');
     // fix dates that already exist
     $dates = array('create', 'start', 'end', 'cancel', 'modified');
     foreach ($dates as $date) {
         $name = "{$date}_date";
         if ($recur->{$name}) {
             $recur->{$name} = CRM_Utils_Date::isoToMysql($recur->{$name});
         }
     }
     $sendNotification = FALSE;
     $subscriptionPaymentStatus = NULL;
     //set transaction type
     $txnType = $_POST['txn_type'];
     switch ($txnType) {
         case 'subscr_signup':
             $recur->create_date = $now;
             //some times 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');
             if ($statusID != 5) {
                 $recur->contribution_status_id = 2;
             }
             $recur->processor_id = $_POST['subscr_id'];
             $recur->trxn_id = $recur->processor_id;
             $sendNotification = TRUE;
             $subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_START;
             break;
         case 'subscr_eot':
             if ($recur->contribution_status_id != 3) {
                 $recur->contribution_status_id = 1;
             }
             $recur->end_date = $now;
             $sendNotification = TRUE;
             $subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_END;
             break;
         case 'subscr_cancel':
             $recur->contribution_status_id = 3;
             $recur->cancel_date = $now;
             break;
         case 'subscr_failed':
             $recur->contribution_status_id = 4;
             $recur->modified_date = $now;
             break;
         case 'subscr_modify':
             CRM_Core_Error::debug_log_message("We do not handle modifications to subscriptions right now");
             echo "Failure: We do not handle modifications to subscriptions right now<p>";
             return FALSE;
         case 'subscr_payment':
             if ($first) {
                 $recur->start_date = $now;
             } else {
                 $recur->modified_date = $now;
             }
             // make sure the contribution status is not done
             // since order of ipn's is unknown
             if ($recur->contribution_status_id != 1) {
                 $recur->contribution_status_id = 5;
             }
             break;
     }
     $recur->save();
     if ($sendNotification) {
         $autoRenewMembership = FALSE;
         if ($recur->id && isset($ids['membership']) && $ids['membership']) {
             $autoRenewMembership = TRUE;
         }
         //send recurring Notification email for user
         CRM_Contribute_BAO_ContributionPage::recurringNotify($subscriptionPaymentStatus, $ids['contact'], $ids['contributionPage'], $recur, $autoRenewMembership);
     }
     if ($txnType != 'subscr_payment') {
         return;
     }
     if (!$first) {
         //check if this contribution transaction is already processed
         //if not create a contribution and then get it processed
         $contribution = new CRM_Contribute_BAO_Contribution();
         $contribution->trxn_id = $input['trxn_id'];
         if ($contribution->trxn_id && $contribution->find()) {
             CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
             echo "Success: Contribution has already been handled<p>";
             return TRUE;
         }
         $contribution->contact_id = $ids['contact'];
         $contribution->financial_type_id = $objects['contributionType']->id;
         $contribution->contribution_page_id = $ids['contributionPage'];
         $contribution->contribution_recur_id = $ids['contributionRecur'];
         $contribution->receive_date = $now;
         $contribution->currency = $objects['contribution']->currency;
         $contribution->payment_instrument_id = $objects['contribution']->payment_instrument_id;
         $contribution->amount_level = $objects['contribution']->amount_level;
         $contribution->campaign_id = $objects['contribution']->campaign_id;
         $objects['contribution'] =& $contribution;
     }
     $this->single($input, $ids, $objects, TRUE, $first);
 }
 public function doDirectPayment(&$params)
 {
     if (!defined('CURLOPT_SSLCERT')) {
         CRM_Core_Error::fatal(ts('eWAY - Gateway requires curl with SSL support'));
     }
     /*
      * OPTIONAL: If TEST Card Number force an Override of URL and CustomerID.
      * During testing CiviCRM once used the LIVE URL.
      * This code can be uncommented to override the LIVE URL that if CiviCRM does that again.
      * if ( ( $gateway_URL == "https://www.eway.com.au/gateway_cvn/xmlpayment.asp")
      *   && ( $params['credit_card_number'] == "4444333322221111" ) ) {
      *   $ewayCustomerID = "87654321";
      *   $gateway_URL    = "https://www.eway.com.au/gateway/rebill/test/Upload_test.aspx";
      * }
      */
     // Was the recurring payment check box checked?
     if (isset($params['is_recur']) && $params['is_recur'] == 1) {
         // Create the customer via the API.
         try {
             $result = $this->createToken($this->_paymentProcessor, $params);
         } catch (Exception $e) {
             return self::errorExit(9010, $e->getMessage());
         }
         // We've created the customer successfully.
         $managed_customer_id = $result;
         try {
             $initialPayment = civicrm_api3('ewayrecurring', 'payment', array('invoice_id' => $params['invoiceID'], 'amount_in_cents' => round((double) $params['amount'] * 100), 'managed_customer_id' => $managed_customer_id, 'description' => $params['description'] . ts('first payment'), 'payment_processor_id' => $this->_paymentProcessor['id']));
             // Here we compensate for the fact core accepts 0 as a valid frequency
             // interval and set it.
             $extra = array();
             if (empty($params['frequency_interval'])) {
                 $params['frequency_interval'] = 1;
                 $extra['frequency_interval'] = 1;
             }
             $params['trxn_id'] = $initialPayment['values'][$managed_customer_id]['trxn_id'];
             $params['contribution_status_id'] = 1;
             $params['payment_status_id'] = 1;
             // If there's only one installment, then the recurring contribution is now complete
             if (isset($params['installments']) && $params['installments'] == 1) {
                 $status = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name');
             } else {
                 $status = CRM_Core_OptionGroup::getValue('contribution_status', 'In Progress', 'name');
             }
             // Save the eWay customer token in the recurring contribution's processor_id field.
             civicrm_api3('contribution_recur', 'create', array_merge(array('id' => $params['contributionRecurID'], 'processor_id' => $managed_customer_id, 'contribution_status_id' => $status, 'next_sched_contribution_date' => CRM_Utils_Date::isoToMysql(date('Y-m-d 00:00:00', strtotime('+' . $params['frequency_interval'] . ' ' . $params['frequency_unit'])))), $extra));
             // Send recurring Notification email for user.
             $recur = new CRM_Contribute_BAO_ContributionRecur();
             $recur->id = $params['contributionRecurID'];
             $recur->find(TRUE);
             // If none found then effectively FALSE.
             $autoRenewMembership = civicrm_api3('membership', 'getcount', array('contribution_recur_id' => $recur->id));
             if (!empty($params['selectMembership']) || !empty($params['membership_type_id']) && !empty($params['auto_renew'])) {
                 $autoRenewMembership = TRUE;
             }
             CRM_Contribute_BAO_ContributionPage::recurringNotify(CRM_Core_Payment::RECURRING_PAYMENT_START, $params['contactID'], CRM_Utils_Array::value('contributionPageID', $params), $recur, $autoRenewMembership);
         } catch (CiviCRM_API3_Exception $e) {
             return self::errorExit(9014, 'Initial payment not processed' . $e->getMessage());
         }
     } else {
         try {
             $result = $this->processSinglePayment($params);
             $params = array_merge($params, $result);
         } catch (CRM_Core_Exception $e) {
             return self::errorExit(9001, $e->getMessage());
         }
     }
     return $params;
 }
Ejemplo n.º 4
0
 /**
  * Send start or end notification for recurring payments.
  *
  * @param array $ids
  * @param CRM_Contribute_BAO_ContributionRecur $recur
  * @param bool $isFirstOrLastRecurringPayment
  */
 public static function sendRecurringStartOrEndNotification($ids, $recur, $isFirstOrLastRecurringPayment)
 {
     if ($isFirstOrLastRecurringPayment) {
         $autoRenewMembership = FALSE;
         if ($recur->id && isset($ids['membership']) && $ids['membership']) {
             $autoRenewMembership = TRUE;
         }
         //send recurring Notification email for user
         CRM_Contribute_BAO_ContributionPage::recurringNotify($isFirstOrLastRecurringPayment, $ids['contact'], $ids['contributionPage'], $recur, $autoRenewMembership);
     }
 }
 function completeRecur($input, $ids, $objects)
 {
     if ($ids['contributionRecur']) {
         $recur =& $objects['contributionRecur'];
         $contributionCount = CRM_Core_DAO::singleValueQuery("\nSELECT count(*)\nFROM   civicrm_contribution\nWHERE  contribution_recur_id = {$ids['contributionRecur']}\n");
         $autoRenewMembership = FALSE;
         if ($recur->id && isset($ids['membership']) && $ids['membership']) {
             $autoRenewMembership = TRUE;
         }
         if ($recur->installments && $contributionCount >= $recur->installments) {
             $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
             $recur->create_date = CRM_Utils_Date::isoToMysql($recur->create_date);
             $recur->start_date = CRM_Utils_Date::isoToMysql($recur->start_date);
             $recur->cancel_date = CRM_Utils_Date::isoToMysql($recur->cancel_date);
             $recur->end_date = date('YmdHis');
             $recur->modified_date = date('YmdHis');
             $recur->contribution_status_id = array_search('Completed', $contributionStatus);
             $recur->trnx_id = $dataRoot['google-order-number']['VALUE'];
             $recur->save();
             //send recurring Notification email for user
             CRM_Contribute_BAO_ContributionPage::recurringNotify(CRM_Core_Payment::RECURRING_PAYMENT_END, $ids['contact'], $ids['contributionPage'], $recur, $autoRenewMembership);
         } elseif ($contributionCount == 1) {
             CRM_Contribute_BAO_ContributionPage::recurringNotify(CRM_Core_Payment::RECURRING_PAYMENT_START, $ids['contact'], $ids['contributionPage'], $recur, $autoRenewMembership);
         }
     }
 }
 function recur(&$input, &$ids, &$objects, $first)
 {
     $recur =& $objects['contributionRecur'];
     // do a subscription check
     if ($recur->processor_id != $input['subscription_id']) {
         CRM_Core_Error::debug_log_message("Unrecognized subscription.");
         echo "Failure: Unrecognized subscription<p>";
         return FALSE;
     }
     // At this point $object has first contribution loaded.
     // Lets do a check to make sure this payment has the amount same as that of first contribution.
     if ($objects['contribution']->total_amount != $input['amount']) {
         CRM_Core_Error::debug_log_message("Subscription amount mismatch.");
         echo "Failure: Subscription amount mismatch<p>";
         return FALSE;
     }
     $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     $transaction = new CRM_Core_Transaction();
     $now = date('YmdHis');
     // fix dates that already exist
     $dates = array('create_date', 'start_date', 'end_date', 'cancel_date', 'modified_date');
     foreach ($dates as $name) {
         if ($recur->{$name}) {
             $recur->{$name} = CRM_Utils_Date::isoToMysql($recur->{$name});
         }
     }
     //load new contribution object if required.
     if (!$first) {
         // create a contribution and then get it processed
         $contribution = new CRM_Contribute_BAO_Contribution();
         $contribution->contact_id = $ids['contact'];
         $contribution->financial_type_id = $objects['contributionType']->id;
         $contribution->contribution_page_id = $ids['contributionPage'];
         $contribution->contribution_recur_id = $ids['contributionRecur'];
         $contribution->receive_date = $now;
         $contribution->currency = $objects['contribution']->currency;
         $contribution->payment_instrument_id = $objects['contribution']->payment_instrument_id;
         $contribution->amount_level = $objects['contribution']->amount_level;
         $contribution->address_id = $objects['contribution']->address_id;
         $contribution->campaign_id = $objects['contribution']->campaign_id;
         $objects['contribution'] =& $contribution;
     }
     $objects['contribution']->invoice_id = md5(uniqid(rand(), TRUE));
     $objects['contribution']->total_amount = $input['amount'];
     $objects['contribution']->trxn_id = $input['trxn_id'];
     // since we have processor loaded for sure at this point,
     // check and validate gateway MD5 response if present
     $this->checkMD5($ids, $input);
     $sendNotification = FALSE;
     if ($input['response_code'] == 1) {
         // Approved
         if ($first) {
             $recur->start_date = $now;
             $recur->trxn_id = $recur->processor_id;
             $sendNotification = TRUE;
             $subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_START;
         }
         $statusName = 'In Progress';
         if ($recur->installments > 0 && $input['subscription_paynum'] >= $recur->installments) {
             // this is the last payment
             $statusName = 'Completed';
             $recur->end_date = $now;
             $sendNotification = TRUE;
             $subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_END;
         }
         $recur->modified_date = $now;
         $recur->contribution_status_id = array_search($statusName, $contributionStatus);
         $recur->save();
     } else {
         // Declined
         // failed status
         $recur->contribution_status_id = array_search('Failed', $contributionStatus);
         $recur->cancel_date = $now;
         $recur->save();
         CRM_Core_Error::debug_log_message("Subscription payment failed - '{$input['response_reason_text']}'");
         // the recurring contribution has declined a payment or has failed
         // so we just fix the recurring contribution and not change any of
         // the existing contribiutions
         // CRM-9036
         return TRUE;
     }
     // check if contribution is already completed, if so we ignore this ipn
     if ($objects['contribution']->contribution_status_id == 1) {
         $transaction->commit();
         CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
         echo "Success: Contribution has already been handled<p>";
         return TRUE;
     }
     $this->completeTransaction($input, $ids, $objects, $transaction, $recur);
     if ($sendNotification) {
         $autoRenewMembership = FALSE;
         if ($recur->id && isset($ids['membership']) && $ids['membership']) {
             $autoRenewMembership = TRUE;
         }
         //send recurring Notification email for user
         CRM_Contribute_BAO_ContributionPage::recurringNotify($subscriptionPaymentStatus, $ids['contact'], $ids['contributionPage'], $recur, $autoRenewMembership);
     }
 }
Ejemplo n.º 7
0
 /**
  * This is the counterpart to the doDirectPayment method. This method creates
  * partial mandates, where the subsequent payment processess produces a payment.
  *
  * This function here should be called after the payment process was completed.
  * It will process all the PARTIAL mandates and connect them with created contributions.
  */
 public static function processPartialMandates()
 {
     // load all the PARTIAL mandates
     $partial_mandates = civicrm_api3('SepaMandate', 'get', array('version' => 3, 'status' => 'PARTIAL', 'option.limit' => 9999));
     foreach ($partial_mandates['values'] as $mandate_id => $mandate) {
         if ($mandate['type'] == 'OOFF') {
             // in the OOFF case, we need to find the contribution, and connect it
             $contribution = civicrm_api('Contribution', 'getsingle', array('version' => 3, 'trxn_id' => $mandate['reference']));
             if (empty($contribution['is_error'])) {
                 // check collection date
                 $ooff_notice = (int) CRM_Sepa_Logic_Settings::getSetting("batching.OOFF.notice", $mandate['creditor_id']);
                 $first_collection_date = strtotime("+{$ooff_notice} days");
                 $collection_date = strtotime($contribution['receive_date']);
                 if ($collection_date < $first_collection_date) {
                     // adjust collection date to the earliest possible one
                     $collection_date = $first_collection_date;
                 }
                 // FOUND! Update the contribution...
                 $contribution_bao = new CRM_Contribute_BAO_Contribution();
                 $contribution_bao->get('id', $contribution['id']);
                 $contribution_bao->is_pay_later = 0;
                 $contribution_bao->receive_date = date('YmdHis', $collection_date);
                 $contribution_bao->contribution_status_id = (int) CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
                 $contribution_bao->payment_instrument_id = (int) CRM_Core_OptionGroup::getValue('payment_instrument', 'OOFF', 'name');
                 $contribution_bao->save();
                 // ...and connect it to the mandate
                 $mandate_update = array();
                 $mandate_update['id'] = $mandate['id'];
                 $mandate_update['entity_id'] = $contribution['id'];
                 $mandate_update['type'] = $mandate['type'];
                 if (empty($mandate['contact_id'])) {
                     // this happens when the payment gets created AFTER the doDirectPayment method
                     $mandate_update['contact_id'] = $contribution_bao->contact_id;
                 }
                 // initialize according to the creditor settings
                 CRM_Sepa_BAO_SEPACreditor::initialiseMandateData($mandate['creditor_id'], $mandate_update);
                 // finally, write the changes to the mandate
                 civicrm_api3('SepaMandate', 'create', $mandate_update);
             } else {
                 // if NOT FOUND or error, delete the partial mandate
                 civicrm_api3('SepaMandate', 'delete', array('id' => $mandate_id));
             }
         } elseif ($mandate['type'] == 'RCUR') {
             // in the RCUR case, we also need to find the contribution, and connect it
             // load the contribution AND the associated recurring contribution
             $contribution = civicrm_api('Contribution', 'getsingle', array('version' => 3, 'trxn_id' => $mandate['reference']));
             $rcontribution = civicrm_api('ContributionRecur', 'getsingle', array('version' => 3, 'trxn_id' => $mandate['reference']));
             if (empty($contribution['is_error']) && empty($rcontribution['is_error'])) {
                 // we need to set the receive date to the correct collection date, otherwise it will be created again (w/o)
                 $rcur_notice = (int) CRM_Sepa_Logic_Settings::getSetting("batching.RCUR.notice", $mandate['creditor_id']);
                 $now = strtotime(date('Y-m-d', strtotime("now +{$rcur_notice} days")));
                 // round to full day
                 $collection_date = CRM_Sepa_Logic_Batching::getNextExecutionDate($rcontribution, $now);
                 // fix contribution
                 $contribution_bao = new CRM_Contribute_BAO_Contribution();
                 $contribution_bao->get('id', $contribution['id']);
                 $contribution_bao->is_pay_later = 0;
                 $contribution_bao->contribution_status_id = (int) CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
                 $contribution_bao->payment_instrument_id = (int) CRM_Core_OptionGroup::getValue('payment_instrument', 'FRST', 'name');
                 $contribution_bao->receive_date = date('YmdHis', strtotime($collection_date));
                 $contribution_bao->save();
                 // fix recurring contribution
                 $rcontribution_bao = new CRM_Contribute_BAO_ContributionRecur();
                 $rcontribution_bao->get('id', $rcontribution['id']);
                 $rcontribution_bao->start_date = date('YmdHis', strtotime($rcontribution_bao->start_date));
                 $rcontribution_bao->create_date = date('YmdHis', strtotime($rcontribution_bao->create_date));
                 $rcontribution_bao->modified_date = date('YmdHis', strtotime($rcontribution_bao->modified_date));
                 $rcontribution_bao->contribution_status_id = (int) CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
                 $rcontribution_bao->payment_instrument_id = (int) CRM_Core_OptionGroup::getValue('payment_instrument', 'FRST', 'name');
                 $rcontribution_bao->save();
                 // ...and connect it to the mandate
                 $mandate_update = array();
                 $mandate_update['id'] = $mandate['id'];
                 $mandate_update['entity_id'] = $rcontribution['id'];
                 $mandate_update['type'] = $mandate['type'];
                 if (empty($mandate['contact_id'])) {
                     $mandate_update['contact_id'] = $contribution['contact_id'];
                     $mandate['contact_id'] = $contribution['contact_id'];
                 }
                 //NO: $mandate_update['first_contribution_id'] = $contribution['id'];
                 // initialize according to the creditor settings
                 CRM_Sepa_BAO_SEPACreditor::initialiseMandateData($mandate['creditor_id'], $mandate_update);
                 // finally, write the changes to the mandate
                 civicrm_api3('SepaMandate', 'create', $mandate_update);
                 // ...and trigger notification
                 // FIXME: WORKAROUND, see https://github.com/Project60/org.project60.sepa/issues/296)
                 CRM_Contribute_BAO_ContributionPage::recurringNotify(CRM_Core_Payment::RECURRING_PAYMENT_START, $mandate['contact_id'], $contribution_bao->contribution_page_id, $rcontribution_bao);
             } else {
                 // something went wrong, delete partial
                 error_log("org.project60.sepa: deleting partial mandate " . $mandate['reference']);
                 civicrm_api3('SepaMandate', 'delete', array('id' => $mandate_id));
             }
         }
     }
 }
 public function createSimpleContribution($contactID, $params, $isTest, $creditInfo)
 {
     $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', array(), 'validate');
     $bltID = array_search('Billing', $locationTypes);
     $settings = civicrm_api3('Setting', 'get', array('domain_id' => $domainID, 'return' => "simple_donation_page"));
     $donatePageID = $settings['values'][$domainID]['simple_donation_page'];
     $donateConfig = $donatePage = civicrm_api3('ContributionPage', 'getsingle', array('id' => $donatePageID));
     $contributionparams = array();
     $isrecur = $params['recur'];
     $contributionparams = array("billing_first_name" => $params['first_name'], "first_name" => $params['first_name'], "billing_middle_name" => $params['middle_name'], "middle_name" => $params['middle_name'], "billing_last_name" => $params['last_name'], "last_name" => $params['last_name'], "billing_street_address-{$bltID}" => $params['address'], "street_address" => $params['address'], "billing_city-{$bltID}" => $params['city'], "city" => $params['city'], "billing_country_id-{$bltID}" => $params['country'], "country_id" => $params['country'], "billing_state_province_id-{$bltID}" => $params['state'], "state_province_id" => $params['state'], "state_province" => CRM_Core_PseudoConstant::stateProvince($params['state']), "billing_postal_code-{$bltID}" => $params['zip'], "postal_code" => $params['zip'], "year" => "20" . substr($params['cardExpiry'], 2, 3), "month" => substr($params['cardExpiry'], 0, 2), "email" => $params['email'], "contribution_page_id" => $donatePageID, "payment_processor_id" => CRM_Utils_Array::value('payment_processor', $params), "is_test" => $isTest, "is_pay_later" => $params['is_pay_later'], "total_amount" => $params['amount'], "financial_type_id" => $donateConfig['financial_type_id'], "currencyID" => $donateConfig['currency'], "currency" => $donateConfig['currency'], "skipLineItem" => 0, "skipRecentView" => 1, 'is_email_receipt' => 1, "contact_id" => $contactID, "source" => "Online Contribution: {$donateConfig['title']}");
     if ($params['is_pay_later']) {
         $contributionparams["contribution_status_id"] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
         $contributionparams["payment_processor_id"] = 1;
     }
     if (!empty($params['creditType'])) {
         $contributionparams['credit_card_number'] = $creditInfo['credit_card_number'];
         $contributionparams['cvv2'] = $creditInfo['cvv2'];
         $contributionparams['credit_card_type'] = $creditInfo['credit_card_type'];
     }
     if (!empty($params['debitType'])) {
         $contributionparams['bank_identification_number'] = $creditInfo['bank_identification_number'];
         $contributionparams['bank_name'] = $creditInfo['bank_name'];
         $contributionparams['bank_account_number'] = $creditInfo['bank_account_number'];
         $contributionparams['payment_type'] = $creditInfo['payment_type'];
         $contributionparams['account_holder'] = $creditInfo['account_holder'];
     }
     //unset the billing parameters if it is pay later mode
     //to avoid creation of billing location
     if ($params['is_pay_later']) {
         $billingFields = array('billing_first_name', 'billing_middle_name', 'billing_last_name', "billing_street_address-{$bltID}", "billing_city-{$bltID}", "billing_state_province-{$bltID}", "billing_state_province_id-{$bltID}", "billing_postal_code-{$bltID}", "billing_country-{$bltID}", "billing_country_id-{$bltID}");
         foreach ($billingFields as $value) {
             unset($contributionparams[$value]);
         }
     }
     //check for recurring contribution
     if ($isrecur) {
         $recurParams = array('contact_id' => $contactID);
         $recurParams['amount'] = $params['amount'];
         $recurParams['auto_renew'] = 1;
         $recurParams['frequency_unit'] = 'month';
         $recurParams['frequency_interval'] = 1;
         $recurParams['financial_type_id'] = $donateConfig['financial_type_id'];
         $recurParams['is_test'] = $isTest;
         $recurParams['start_date'] = $recurParams['create_date'] = $recurParams['modified_date'] = date('YmdHis');
         $recurParams['invoice_id'] = $recurParams['trxn_id'] = md5(uniqid(rand(), TRUE));
         $recurParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
         $recurParams['payment_processor_id'] = CRM_Utils_Array::value('payment_processor_id', $contributionparams);
         $recurParams['is_email_receipt'] = 1;
         //create recurring contribution record
         $recurring = CRM_Contribute_BAO_ContributionRecur::add($recurParams);
         $recurContriID = $recurring->id;
         $contributionparams['contributionRecurID'] = $recurContriID;
         //$contribution->id;
         $contributionparams['contribution_recur_id'] = $recurContriID;
         //$contribution->id;
     }
     //call transact api
     try {
         $result = civicrm_api3('Contribution', 'transact', $contributionparams);
     } catch (CiviCRM_API3_Exception $e) {
         $error = $e->getMessage();
         $errorList['error'] = $error;
         return $errorList;
     }
     if ($result['error']) {
         //make sure to cleanup db for recurring case.
         if ($recurContriID) {
             CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($recurContriID);
         }
         return $result['error'];
     } else {
         if ($result) {
             $contributionID = $result['id'];
             // Send receipt
             // send recurring Notification email for user
             if ($recurContriID) {
                 CRM_Contribute_BAO_ContributionPage::recurringNotify(CRM_Core_Payment::RECURRING_PAYMENT_START, $contactID, $donatePageID, $recurring);
             }
             civicrm_api3('contribution', 'sendconfirmation', array('id' => $contributionID) + $donateConfig);
             return $result;
         }
     }
 }