コード例 #1
0
 /**
  * Performs an action on authorize.net and updates/inserts records. If record update fails,
  * sends email to admin.
  *
  * @param object &$order Which transaction data will be sent. See enrol_authorize table.
  * @param string &$message Information about error message.
  * @param object &$extra Extra data that used for refunding and credit card information.
  * @param int $action Which action will be performed. See AN_ACTION_*
  * @param string $cctype Used internally to configure credit types automatically.
  * @return int AN_APPROVED Transaction was successful, AN_RETURNZERO otherwise. Use $message for reason.
  */
 public static function process(&$order, &$message, &$extra, $action = AN_ACTION_NONE, $cctype = NULL)
 {
     global $CFG, $DB;
     static $constpd = array();
     require_once $CFG->libdir . '/filelib.php';
     $mconfig = get_config('enrol_authorize');
     if (empty($constpd)) {
         $mconfig = get_config('enrol_authorize');
         $constpd = array('x_version' => '3.1', 'x_delim_data' => 'True', 'x_delim_char' => self::AN_DELIM, 'x_encap_char' => self::AN_ENCAP, 'x_relay_response' => 'FALSE', 'x_login' => $mconfig->an_login);
         if (!empty($mconfig->an_tran_key)) {
             $constpd['x_tran_key'] = $mconfig->an_tran_key;
         } else {
             $constpd['x_password'] = $mconfig->an_password;
         }
     }
     if (empty($order) or empty($order->id)) {
         $message = "Check order->id!";
         return AN_RETURNZERO;
     }
     $method = $order->paymentmethod;
     if (empty($method)) {
         $method = AN_METHOD_CC;
     } elseif ($method != AN_METHOD_CC && $method != AN_METHOD_ECHECK) {
         $message = "Invalid method: {$method}";
         return AN_RETURNZERO;
     }
     $action = intval($action);
     if ($method == AN_METHOD_ECHECK) {
         if ($action != AN_ACTION_AUTH_CAPTURE && $action != AN_ACTION_CREDIT) {
             $message = "Please perform AUTH_CAPTURE or CREDIT for echecks";
             return AN_RETURNZERO;
         }
     }
     $pd = $constpd;
     $pd['x_method'] = $method;
     $test = !empty($mconfig->an_test);
     $pd['x_test_request'] = $test ? 'TRUE' : 'FALSE';
     switch ($action) {
         case AN_ACTION_AUTH_ONLY:
         case AN_ACTION_CAPTURE_ONLY:
         case AN_ACTION_AUTH_CAPTURE:
             if ($order->status != AN_STATUS_NONE) {
                 $message = "Order status must be AN_STATUS_NONE(0)!";
                 return AN_RETURNZERO;
             } elseif (empty($extra)) {
                 $message = "Need extra fields!";
                 return AN_RETURNZERO;
             } elseif ($action == AN_ACTION_CAPTURE_ONLY and empty($extra->x_auth_code)) {
                 $message = "x_auth_code is required for capture only transactions!";
                 return AN_RETURNZERO;
             }
             $ext = (array) $extra;
             $pd['x_type'] = $action == AN_ACTION_AUTH_ONLY ? 'AUTH_ONLY' : ($action == AN_ACTION_CAPTURE_ONLY ? 'CAPTURE_ONLY' : 'AUTH_CAPTURE');
             foreach ($ext as $k => $v) {
                 $pd[$k] = $v;
             }
             break;
         case AN_ACTION_PRIOR_AUTH_CAPTURE:
             if ($order->status != AN_STATUS_AUTH) {
                 $message = "Order status must be authorized!";
                 return AN_RETURNZERO;
             }
             if (self::expired($order)) {
                 $message = "Transaction must be captured within 30 days. EXPIRED!";
                 return AN_RETURNZERO;
             }
             $pd['x_type'] = 'PRIOR_AUTH_CAPTURE';
             $pd['x_trans_id'] = $order->transid;
             break;
         case AN_ACTION_CREDIT:
             if ($order->status != AN_STATUS_AUTHCAPTURE) {
                 $message = "Order status must be authorized/captured!";
                 return AN_RETURNZERO;
             }
             if (!self::settled($order)) {
                 $message = "Order must be settled. Try VOID, check Cut-Off time if it fails!";
                 return AN_RETURNZERO;
             }
             if (empty($extra->amount)) {
                 $message = "No valid amount!";
                 return AN_RETURNZERO;
             }
             $timenowsettle = self::getsettletime(time());
             $timediff = $timenowsettle - 120 * 3600 * 24;
             if ($order->settletime < $timediff) {
                 $message = "Order must be credited within 120 days!";
                 return AN_RETURNZERO;
             }
             $pd['x_type'] = 'CREDIT';
             $pd['x_trans_id'] = $order->transid;
             $pd['x_currency_code'] = $order->currency;
             $pd['x_invoice_num'] = $extra->orderid;
             $pd['x_amount'] = $extra->amount;
             if ($method == AN_METHOD_CC) {
                 $pd['x_card_num'] = sprintf("%04d", intval($order->refundinfo));
             } elseif ($method == AN_METHOD_ECHECK && empty($order->refundinfo)) {
                 $message = "Business checkings can be refunded only.";
                 return AN_RETURNZERO;
             }
             break;
         case AN_ACTION_VOID:
             if (self::expired($order) || self::settled($order)) {
                 $message = "The transaction cannot be voided due to the fact that it is expired or settled.";
                 return AN_RETURNZERO;
             }
             $pd['x_type'] = 'VOID';
             $pd['x_trans_id'] = $order->transid;
             break;
         default:
             $message = "Invalid action: {$action}";
             return AN_RETURNZERO;
     }
     $headers = array('Connection' => 'close');
     if (!(empty($mconfig->an_referer) || $mconfig->an_referer == "http://")) {
         $headers['Referer'] = $mconfig->an_referer;
     }
     @ignore_user_abort(true);
     if (intval(ini_get('max_execution_time')) > 0) {
         @set_time_limit(300);
     }
     $host = $test ? 'test.authorize.net' : 'secure.authorize.net';
     $data = download_file_content("https://{$host}:443/gateway/transact.dll", $headers, $pd, false, 300, 60, true);
     if (!$data) {
         $message = "No connection to https://{$host}:443";
         return AN_RETURNZERO;
     }
     $response = explode(self::AN_ENCAP . self::AN_DELIM . self::AN_ENCAP, $data);
     if ($response === false) {
         $message = "response error";
         return AN_RETURNZERO;
     }
     $rcount = count($response) - 1;
     if ($response[0][0] == self::AN_ENCAP) {
         $response[0] = substr($response[0], 1);
     }
     if (substr($response[$rcount], -1) == self::AN_ENCAP) {
         $response[$rcount] = substr($response[$rcount], 0, -1);
     }
     $responsecode = intval($response[0]);
     if ($responsecode == AN_APPROVED || $responsecode == AN_REVIEW) {
         $transid = floatval($response[6]);
         if ($test || $transid == 0) {
             return $responsecode;
             // don't update original transaction in test mode.
         }
         switch ($action) {
             case AN_ACTION_AUTH_ONLY:
             case AN_ACTION_CAPTURE_ONLY:
             case AN_ACTION_AUTH_CAPTURE:
             case AN_ACTION_PRIOR_AUTH_CAPTURE:
                 $order->transid = $transid;
                 if ($method == AN_METHOD_CC) {
                     if ($action == AN_ACTION_AUTH_ONLY || $responsecode == AN_REVIEW) {
                         $order->status = AN_STATUS_AUTH;
                     } else {
                         $order->status = AN_STATUS_AUTHCAPTURE;
                         $order->settletime = self::getsettletime(time());
                     }
                 } elseif ($method == AN_METHOD_ECHECK) {
                     $order->status = AN_STATUS_UNDERREVIEW;
                 }
                 $DB->update_record('enrol_authorize', $order);
                 break;
             case AN_ACTION_CREDIT:
                 // Credit generates new transaction id.
                 // So, $extra must be updated, not $order.
                 $extra->status = AN_STATUS_CREDIT;
                 $extra->transid = $transid;
                 $extra->settletime = self::getsettletime(time());
                 $extra->id = $DB->insert_record('enrol_authorize_refunds', $extra);
                 break;
             case AN_ACTION_VOID:
                 $tableupdate = 'enrol_authorize';
                 if ($order->status == AN_STATUS_CREDIT) {
                     $tableupdate = 'enrol_authorize_refunds';
                     unset($order->paymentmethod);
                 }
                 $order->status = AN_STATUS_VOID;
                 $DB->update_record($tableupdate, $order);
                 break;
         }
     } else {
         $reasonno = $response[2];
         $reasonstr = "reason" . $reasonno;
         $message = get_string($reasonstr, "enrol_authorize");
         if ($message == '[[' . $reasonstr . ']]') {
             $message = isset($response[3]) ? $response[3] : 'unknown error';
         }
         if ($method == AN_METHOD_CC && !empty($mconfig->an_avs) && $response[5] != "P") {
             $avs = "avs" . strtolower($response[5]);
             $stravs = get_string($avs, "enrol_authorize");
             $message .= "<br />" . get_string("avsresult", "enrol_authorize", $stravs);
         }
         if (!$test) {
             // Autoconfigure :)
             switch ($reasonno) {
                 // Credit card type isn't accepted
                 case self::AN_REASON_NOCCTYPE:
                 case self::AN_REASON_NOCCTYPE2:
                     if (!empty($cctype)) {
                         $ccaccepts = get_list_of_creditcards();
                         unset($ccaccepts[$cctype]);
                         set_config("an_acceptcc_{$cctype}", 0, 'enrol_authorize');
                         foreach ($ccaccepts as $key => $val) {
                             set_config("an_acceptcc_{$key}", 1, 'enrol_authorize');
                         }
                         message_to_admin("{$message} ({$cctype}) This is new config(an_acceptccs):", $ccaccepts);
                     }
                     break;
                     // Echecks only
                 // Echecks only
                 case self::AN_REASON_ACHONLY:
                     set_config("an_acceptmethod_" . AN_METHOD_ECHECK, 1, 'enrol_authorize');
                     message_to_admin("{$message} This is new config(an_acceptmethods):", array(AN_METHOD_ECHECK));
                     break;
                     // Echecks aren't accepted
                 // Echecks aren't accepted
                 case self::AN_REASON_NOACH:
                     set_config("an_acceptmethod_" . AN_METHOD_CC, 1, 'enrol_authorize');
                     message_to_admin("{$message} This is new config(an_acceptmethods):", array(AN_METHOD_CC));
                     break;
                     // This echeck type isn't accepted
                 // This echeck type isn't accepted
                 case self::AN_REASON_NOACHTYPE:
                 case self::AN_REASON_NOACHTYPE2:
                     if (!empty($extra->x_echeck_type)) {
                         switch ($extra->x_echeck_type) {
                             // CCD=BUSINESSCHECKING
                             case 'CCD':
                                 set_config('an_acceptecheck_CHECKING', 1, 'enrol_authorize');
                                 set_config('an_acceptecheck_SAVINGS', 1, 'enrol_authorize');
                                 message_to_admin("{$message} This is new config(an_acceptechecktypes):", array('CHECKING', 'SAVINGS'));
                                 break;
                                 // WEB=CHECKING or SAVINGS
                             // WEB=CHECKING or SAVINGS
                             case 'WEB':
                                 set_config('an_acceptecheck_BUSINESSCHECKING', 1, 'enrol_authorize');
                                 message_to_admin("{$message} This is new config(an_acceptechecktypes):", array('BUSINESSCHECKING'));
                                 break;
                         }
                     }
                     break;
             }
         }
     }
     return $responsecode;
 }
コード例 #2
0
ファイル: enrol.php プロジェクト: ajv/Offline-Caching
 /**
  * The user submitted echeck form.
  *
  * @param object $form Form parameters
  * @param object $course Course info
  * @return string NULL if ok, error message otherwise.
  * @access private
  */
 private function echeck_submit($form, $course)
 {
     global $CFG, $USER, $SESSION, $DB;
     prevent_double_paid($course);
     $useripno = getremoteaddr();
     $curcost = get_course_cost($course);
     $isbusinesschecking = $form->acctype == 'BUSINESSCHECKING';
     // NEW ECHECK ORDER
     $timenow = time();
     $order = new stdClass();
     $order->paymentmethod = AN_METHOD_ECHECK;
     $order->refundinfo = $isbusinesschecking ? 1 : 0;
     $order->ccname = $form->firstname . ' ' . $form->lastname;
     $order->courseid = $course->id;
     $order->userid = $USER->id;
     $order->status = AN_STATUS_NONE;
     // it will be changed...
     $order->settletime = 0;
     // cron changes this.
     $order->transid = 0;
     // Transaction Id
     $order->timecreated = $timenow;
     $order->amount = $curcost['cost'];
     $order->currency = $curcost['currency'];
     $order->id = $DB->insert_record("enrol_authorize", $order);
     if (!$order->id) {
         message_to_admin("Error while trying to insert new data", $order);
         return "Insert record error. Admin has been notified!";
     }
     $extra = new stdClass();
     $extra->x_bank_aba_code = $form->abacode;
     $extra->x_bank_acct_num = $form->accnum;
     $extra->x_bank_acct_type = $form->acctype;
     $extra->x_echeck_type = $isbusinesschecking ? 'CCD' : 'WEB';
     $extra->x_bank_name = $form->bankname;
     $extra->x_currency_code = $curcost['currency'];
     $extra->x_amount = $curcost['cost'];
     $extra->x_first_name = $form->firstname;
     $extra->x_last_name = $form->lastname;
     $extra->x_country = $USER->country;
     $extra->x_address = $USER->address;
     $extra->x_city = $USER->city;
     $extra->x_state = '';
     $extra->x_zip = '';
     $extra->x_invoice_num = $order->id;
     $extra->x_description = $course->shortname;
     $extra->x_cust_id = $USER->id;
     $extra->x_email = $USER->email;
     $extra->x_customer_ip = $useripno;
     $extra->x_email_customer = empty($CFG->enrol_mailstudents) ? 'FALSE' : 'TRUE';
     $extra->x_phone = '';
     $extra->x_fax = '';
     $message = '';
     if (AN_REVIEW == AuthorizeNet::process($order, $message, $extra, AN_ACTION_AUTH_CAPTURE)) {
         $SESSION->ccpaid = 1;
         // security check: don't duplicate payment
         redirect($CFG->wwwroot, get_string("reviewnotify", "enrol_authorize"), '30');
         return NULL;
     } else {
         message_to_admin($message, $order);
         return $message;
     }
 }