protected function processCreditCardCustomer($values)
 {
     // generate another recurring contribution, matching our recurring template with submitted value
     $total_amount = $values['amount'];
     $contribution_template = _iats_civicrm_getContributionTemplate(array('contribution_recur_id' => $values['crid']));
     $contact_id = $values['cid'];
     $hash = md5(uniqid(rand(), true));
     $contribution_recur_id = $values['crid'];
     $payment_processor_id = $values['paymentProcessorId'];
     $type = _iats_civicrm_is_iats($payment_processor_id);
     $subtype = substr($type, 11);
     $source = "iATS Payments {$subtype} Recurring Contribution (id={$contribution_recur_id})";
     $receive_date = date("YmdHis", time());
     // i.e. now
     $contribution = array('version' => 3, 'contact_id' => $contact_id, 'receive_date' => $receive_date, 'total_amount' => $total_amount, 'contribution_recur_id' => $contribution_recur_id, 'invoice_id' => $hash, 'source' => $source, 'contribution_status_id' => 2, 'payment_processor' => $payment_processor_id, 'is_test' => $values['is_test']);
     foreach (array('payment_instrument_id', 'currency', 'financial_type_id') as $key) {
         $contribution[$key] = $contribution_template[$key];
     }
     $options = array('is_email_receipt' => 0, 'customer_code' => $values['customerCode'], 'subtype' => $subtype);
     // now all the hard work in this function, recycled from the original recurring payment job
     $result = _iats_process_contribution_payment($contribution, $options);
     return $result;
 }
Exemplo n.º 2
0
/**
 * hook_civicrm_pre
 *
 * Handle special cases of creating contribution (regular and recurring) records when using IATS Payments
 *
 * 1. CiviCRM assumes all recurring contributions need to be confirmed using the IPN mechanism. This is not true for iATS recurring contributions.
 * So when creating a contribution that is part of a recurring series, test for status = 2, and set to status = 1 instead, unless we're using the fixed day feature
 * Do this only for the initial contribution record.
 * The (subsequent) recurring contributions' status id is set explicitly in the job that creates it, this modification breaks that process.
 *
 * 2. For ACH/EFT, we also have the opposite problem - all contributions will need to verified by iATS and only later set to status success or
 * failed via the acheft verify job. We also want to modify the payment instrument from CC to ACH/EFT
 *
 * TODO: update this code with constants for the various id values of 1 and 2.
 * TODO: CiviCRM should have nicer ways to handle this.
 */
function iats_civicrm_pre($op, $objectName, $objectId, &$params)
{
    // since this function gets called a lot, quickly determine if I care about the record being created
    if ('create' == $op && ('Contribution' == $objectName || 'ContributionRecur' == $objectName) && !empty($params['contribution_status_id'])) {
        // watchdog('iats_civicrm','hook_civicrm_pre for Contribution <pre>@params</pre>',array('@params' => print_r($params));
        // figure out the payment processor id, not nice
        $version = CRM_Utils_System::version();
        $payment_processor_id = 'ContributionRecur' == $objectName ? $params['payment_processor_id'] : (!empty($params['payment_processor']) ? $params['payment_processor'] : (!empty($params['contribution_recur_id']) ? _iats_civicrm_get_payment_processor_id($params['contribution_recur_id']) : 0));
        if ($type = _iats_civicrm_is_iats($payment_processor_id)) {
            $settings = CRM_Core_BAO_Setting::getItem('iATS Payments Extension', 'iats_settings');
            $allow_days = empty($settings['days']) ? array('-1') : $settings['days'];
            switch ($type . $objectName) {
                case 'iATSServiceContribution':
                    // cc contribution, test if it's been set to status 2 on a recurring contribution
                // cc contribution, test if it's been set to status 2 on a recurring contribution
                case 'iATSServiceSWIPEContribution':
                    // for civi version before 4.6.6, we had to force the status to 1
                    if (2 == $params['contribution_status_id'] && !empty($params['contribution_recur_id']) && max($allow_days) <= 0 && version_compare($version, '4.6.6') < 0) {
                        // but only for the first one
                        $count = civicrm_api('Contribution', 'getcount', array('version' => 3, 'contribution_recur_id' => $params['contribution_recur_id']));
                        if (is_array($count) && empty($count['result']) || empty($count)) {
                            // watchdog('iats_civicrm','hook_civicrm_pre updating status_id for objectName @id, count <pre>!count</pre>, params <pre>!params</pre>, ',array('@id' => $objectName, '!count' => print_r($count,TRUE),'!params' => print_r($params,TRUE)));
                            $params['contribution_status_id'] = 1;
                        }
                    }
                    break;
                case 'iATSServiceContributionRecur':
                    // cc/swipe/ACHEFT recurring contribution record
                // cc/swipe/ACHEFT recurring contribution record
                case 'iATSServiceSWIPEContributionRecur':
                case 'iATSServiceACHEFTContributionRecur':
                    // the next scheduled contribution date field name is civicrm version dependent
                    $field_name = _iats_civicrm_nscd_fid();
                    // when creating a recurring contribution record via a civicrm contribution form
                    // we've already taken the first payment, so calculate the next one (core assumes the intial contribution is pending)
                    // we set this to 'in-progress' even for ACH/EFT if the first one hasn't been verified, because we still want to be attempting later ones
                    // this condition helps avoid mangling records being imported from a csv file
                    if (5 != $params['contribution_status_id'] && empty($params[$field_name])) {
                        $params['contribution_status_id'] = 5;
                        $params['trxn_id'] = NULL;
                        // civi wants to put the returned trxn_id in here
                        $next = strtotime('+' . $params['frequency_interval'] . ' ' . $params['frequency_unit']);
                        $params[$field_name] = date('YmdHis', $next);
                    }
                    if ($type == 'iATSServiceACHEFT') {
                        // fix the payment type for ACH/EFT
                        $params['payment_instrument_id'] = 2;
                    }
                    break;
                case 'iATSServiceACHEFTContribution':
                    // ach/eft contribution: update the payment instrument
                    $params['payment_instrument_id'] = 2;
                    // and push the status to 2 if civicrm thinks it's 1, i.e. for one-time contributions
                    // in other words, never create ach/eft contributions as complete, always push back to pending and verify
                    if ($params['contribution_status_id'] == 1) {
                        $params['contribution_status_id'] = 2;
                    }
                    break;
                case 'iATSServiceUKDDContribution':
                    // UK DD contribution: update the payment instrument, fix the receive date
                    $params['payment_instrument_id'] = 2;
                    if ($start_date = strtotime($_POST['payer_validate_start_date'])) {
                        $params['receive_date'] = date('Ymd', $start_date) . '120000';
                    }
                    break;
                case 'iATSServiceUKDDContributionRecur':
                    // UK DD recurring contribution record: update the payment instrument, fix the start_date
                    $params['payment_instrument_id'] = 2;
                    if ($start_date = strtotime($_POST['payer_validate_start_date'])) {
                        $params['start_date'] = date('Ymd', $start_date) . '120000';
                    }
                    break;
            }
            if ($type != 'iATSServiceUKDD' && $objectName == 'Contribution') {
                // new, non-UKDD contribution records in a schedule are forced to comply with any restrictions
                if (0 < max($allow_days)) {
                    $from_time = _iats_contributionrecur_next(strtotime($params['receive_date']), $allow_days);
                    $params['receive_date'] = date('Ymd', $from_time) . '030000';
                }
            }
        }
        // watchdog('iats_civicrm','ignoring hook_civicrm_pre for objectName @id',array('@id' => $objectName));
    }
    // if I've set fixed monthly recurring dates, force any iats (non uk dd) recurring contribution schedule records to comply
    // it's a bit draconian, and you likely want to give administrators the ability to modify these schedules
    // this is separate from the above because I want to deal with both create and edit possibilities
    if ('ContributionRecur' == $objectName && ('create' == $op || 'edit' == $op)) {
        if ($type = _iats_civicrm_is_iats($params['payment_processor_id'])) {
            if ($type != 'iATSServiceUKDD' && !empty($params['next_sched_contribution_date'])) {
                $settings = CRM_Core_BAO_Setting::getItem('iATS Payments Extension', 'iats_settings');
                $allow_days = empty($settings['days']) ? array('-1') : $settings['days'];
                if (0 < max($allow_days)) {
                    // force one of the fixed days, and set the cycle_day at the same time
                    $init_time = 'create' == $op ? time() : strtotime($params['next_sched_contribution_date']);
                    $from_time = _iats_contributionrecur_next($init_time, $allow_days);
                    $params['next_sched_contribution_date'] = date('YmdHis', $from_time);
                    $params['cycle_day'] = date('j', $from_time);
                    // day of month without leading 0
                }
            }
            if (empty($params['installments'])) {
                // fix a civi bug while I'm here
                $params['installments'] = '0';
            }
        }
    }
}
Exemplo n.º 3
0
/**
 * hook_civicrm_pre
 *
 * Handle special cases of creating contribution (regular and recurring) records when using IATS Payments
 *
 * 1. CiviCRM assumes all recurring contributions need to be confirmed using the IPN mechanism. This is not true for iATS recurring contributions.
 * So when creating a contribution that is part of a recurring series, test for status = 2, and set to status = 1 instead.
 * Do this only for the initial contribution record.
 * The (subsequent) recurring contributions' status id is set explicitly in the job that creates it, this modification breaks that process.
 *
 * 2. For ACH/EFT, we also have the opposite problem - all contributions will need to verified by iATS and only later set to status success or
 * failed via the acheft verify job. We also want to modify the payment instrument from CC to ACH/EFT
 *
 * TODO: update this code with constants for the various id values of 1 and 2.
 * TODO: CiviCRM should have nicer ways to handle this.
 */
function iats_civicrm_pre($op, $objectName, $objectId, &$params)
{
    // since this function gets called a lot, quickly determine if I care about the record being created
    if ('create' == $op && ('Contribution' == $objectName || 'ContributionRecur' == $objectName) && !empty($params['contribution_status_id'])) {
        // watchdog('iats_civicrm','hook_civicrm_pre for Contribution <pre>@params</pre>',array('@params' => print_r($params));
        // figure out the payment processor id, not nice
        $version = CRM_Utils_System::version();
        $payment_processor_id = 'ContributionRecur' == $objectName ? $params['payment_processor_id'] : (!empty($params['payment_processor']) ? $params['payment_processor'] : (!empty($params['contribution_recur_id']) ? _iats_civicrm_get_payment_processor_id($params['contribution_recur_id']) : 0));
        if ($type = _iats_civicrm_is_iats($payment_processor_id)) {
            switch ($type . $objectName) {
                case 'iATSServiceContribution':
                    // cc contribution, test if it's been set to status 2 on a recurring contribution
                // cc contribution, test if it's been set to status 2 on a recurring contribution
                case 'iATSServiceSWIPEContribution':
                    // for civi version before 4.6.6, we had to force the status to 1
                    if (2 == $params['contribution_status_id'] && !empty($params['contribution_recur_id']) && version_compare($version, '4.6.6') < 0) {
                        // but only for the first one
                        $count = civicrm_api('Contribution', 'getcount', array('version' => 3, 'contribution_recur_id' => $params['contribution_recur_id']));
                        if (is_array($count) && empty($count['result']) || empty($count)) {
                            // watchdog('iats_civicrm','hook_civicrm_pre updating status_id for objectName @id, count <pre>!count</pre>, params <pre>!params</pre>, ',array('@id' => $objectName, '!count' => print_r($count,TRUE),'!params' => print_r($params,TRUE)));
                            $params['contribution_status_id'] = 1;
                        }
                    }
                    break;
                case 'iATSServiceContributionRecur':
                    // cc/swipe/ACHEFT recurring contribution record
                // cc/swipe/ACHEFT recurring contribution record
                case 'iATSServiceSWIPEContributionRecur':
                case 'iATSServiceACHEFTContributionRecur':
                    // the next scheduled contribution date field name is civicrm version dependent
                    $field_name = _iats_civicrm_nscd_fid();
                    // when creating a recurring contribution record via a civicrm contribution form
                    // we've already taken the first payment, so calculate the next one (core assumes the intial contribution is pending)
                    // we set this to 'in-progress' even for ACH/EFT if the first one hasn't been verified, because we still want to be attempting later ones
                    // this condition helps avoid mangling records being imported from a csv file
                    if (5 != $params['contribution_status_id'] && empty($params[$field_name])) {
                        $params['contribution_status_id'] = 5;
                        $params['trxn_id'] = NULL;
                        $next = strtotime('+' . $params['frequency_interval'] . ' ' . $params['frequency_unit']);
                        $params[$field_name] = date('YmdHis', $next);
                    }
                    if ($type == 'iATSServiceACHEFT') {
                        // fix the payment type for ACH/EFT
                        $params['payment_instrument_id'] = 2;
                    }
                    break;
                case 'iATSServiceACHEFTContribution':
                    // ach/eft contribution: update the payment instrument
                    $params['payment_instrument_id'] = 2;
                    // and push the status to 2 if civicrm thinks it's 1, i.e. for one-time contributions
                    // in other words, never create ach/eft contributions as complete, always push back to pending and verify
                    if ($params['contribution_status_id'] == 1) {
                        $params['contribution_status_id'] = 2;
                    }
                    break;
                case 'iATSServiceUKDDContribution':
                    // UK DD contribution: update the payment instrument, fix the receive date
                    $params['payment_instrument_id'] = 2;
                    if ($start_date = strtotime($_POST['payer_validate_start_date'])) {
                        $params['receive_date'] = date('Ymd', $start_date) . '120000';
                    }
                    break;
                case 'iATSServiceUKDDContributionRecur':
                    // UK DD recurring contribution record: update the payment instrument, fix the start_date
                    $params['payment_instrument_id'] = 2;
                    if ($start_date = strtotime($_POST['payer_validate_start_date'])) {
                        $params['start_date'] = date('Ymd', $start_date) . '120000';
                    }
                    break;
            }
        }
        // watchdog('iats_civicrm','ignoring hook_civicrm_pre for objectName @id',array('@id' => $objectName));
    }
}