Permalink
Browse files

New authorize.net module is more powerful. :)

- Review order:

   Review order before processing the credit card.

- Auto-Capture:
   If auto-capture enabled the credit card will be captured
   after an_review_day later, then student will be enrolled
   to course, otherwise it will be expired or
   admin must accept/deny payment.

   NOTE: Set-up Transaction Cut-Off Time correctly.
         When the last transaction is picked up for settlement?

- Payment Management:

   Accept/Deny/Refund payments: cvs:/moodle/enrol/authorize/index.php

- TO DO: Batch upload: It will sync authorize.net and moodle from csv file.
  • Loading branch information...
ethem
ethem committed Dec 26, 2005
1 parent 8cb3ad1 commit 62d98252ac1b865038ad640c95be6588e274464a
Showing with 578 additions and 77 deletions.
  1. +6 −9 enrol/authorize/action.php
  2. +121 −68 enrol/authorize/enrol.php
  3. +451 −0 enrol/authorize/index.php
View
@@ -46,9 +46,6 @@
define('AN_ACTION_VOID', 0x08);
-define('AN_REASON_NONE', 0);
-define('AN_REASON_TRAN_NOT_FOUND', 16);
-
/**
* Gets settlement date and time
*
@@ -82,26 +79,25 @@ function settled($order)
static $timenow;
if (!isset($timenow)) {
- $timenow = time();
+ $timenow = time();
}
return (($order->status == AN_STATUS_AUTHCAPTURE || $order->status == AN_STATUS_CREDIT)
- && $order->settletime < $timenow && $order->settletime > 0);
+ && $order->settletime > 0 && $order->settletime < $timenow );
}
/**
* Performs an action on authorize.net
*
* @param object &$order Which transaction data will be send. See enrol_authorize table.
* @param string &$message Information about error messages.
- * @param int &$reason Reason subcode
* @param object &$extra Extra transaction data.
* @param int $action Which action will be performed. See AN_ACTION_*
* @return bool true, transaction was successful, false otherwise.
* @author Ethem Evlice <ethem a.t evlice d.o.t com>
* @uses $CFG
*/
-function authorizenet_action(&$order, &$message, &$reason, &$extra, $action=AN_ACTION_NONE)
+function authorizenet_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE)
{
global $CFG;
static $conststring;
@@ -297,10 +293,11 @@ function authorizenet_action(&$order, &$message, &$reason, &$extra, $action=AN_A
$response[$rcount] = substr($response[$rcount], 0, -1);
}
- $reason = intval($response[2]);
-
if ($response[0] == AN_APPROVED)
{
+ if ($an_test || intval($response[6]) == 0) {
+ return true; // don't update original transaction in test mode.
+ }
switch ($action) {
case AN_ACTION_AUTH_ONLY:
case AN_ACTION_AUTH_CAPTURE:
View
@@ -163,6 +163,11 @@ function cc_submit($form, $course)
return;
}
+ if (!empty($CFG->an_test)) {
+ error("Credit card module cannot be present because of test mode");
+ return;
+ }
+
$this->prevent_double_paid($course);
$exp_date = ($form->ccexpiremm < 10) ? strval('0'.$form->ccexpiremm) : strval($form->ccexpiremm);
@@ -221,21 +226,40 @@ function cc_submit($form, $course)
$extra->x_description = $course->shortname;
$message = '';
- $reason = AN_REASON_NONE;
$an_review = !empty($CFG->an_review);
$action = $an_review ? AN_ACTION_AUTH_ONLY : AN_ACTION_AUTH_CAPTURE;
- $success = authorizenet_action($order, $message, $reason, $extra, $action);
+ $success = authorizenet_action($order, $message, $extra, $action);
if (!$success) {
$this->email_to_admin($message, $order);
$this->ccerrormsg = $message;
return;
}
+ if (intval($order->transid) == 0) { // I know it is test mode. :)
+ error("Credit card module cannot be present because of test mode");
+ return;
+ }
+
$SESSION->ccpaid = 1; // security check: don't duplicate payment
if ($an_review) { // review enabled, inform admin and redirect to main page.
if (update_record("enrol_authorize", $order)) {
- // notification: new transaction (AUTH_ONLY)
- // see order details: index.php?order=$order->id
+ $a->url = "$CFG->wwwroot/enrol/authorize/index.php?order=$order->id";
+ $a->orderid = $order->id;
+ $a->transid = $order->transid;
+ $a->amount = "$order->currency $order->amount";
+ $a->expireon = getsettletime($timenow + (30 * 3600 * 24));
+ $a->captureon = getsettletime($timenow + (intval($CFG->an_review_day) * 3600 * 24));
+ $a->course = $course->fullname;
+ $a->user = fullname($USER);
+ $a->acstatus = ($CFG->an_review_day > 0) ? get_string('yes') : get_string('no');
+ $emailmessage = get_string('adminneworder', 'enrol_authorize', $a);
+ $a->course = $course->shortname;
+ $a->orderid = $order->id;
+ $emailsubject = get_string('adminnewordersubject', 'enrol_authorize', $a);
+ $admins = get_admins();
+ foreach ($admins as $admin) {
+ email_to_user($admin, $USER, $emailsubject, $emailmessage);
+ }
}
else {
$this->email_to_admin("Error while trying to update data. Please edit manually this record: " .
@@ -404,7 +428,8 @@ function config_form($frm)
if (!(empty($frm->an_review) || $frm->an_review_day < 1)) {
// ++ENABLED++
// Cron must be runnig!!! Check last cron...
- $lastcron = get_field_sql('SELECT max(lastcron) FROM ' . $CFG->prefix . 'modules');
+ $mconfig = get_config('enrol/authorize');
+ $lastcron = intval($mconfig->an_lastcron);
if (time() - $lastcron > 3600 * 24) {
// Cron must be enabled if you want to use autocapture feature.
// Setup cron or disable an_review again...
@@ -480,8 +505,9 @@ function process_config($config)
if ($review_day_val < 0) $review_day_val = 0;
elseif ($review_day_val > 29) $review_day_val = 29;
if ($review_day_val > 0) {
- // cron is required.
- $lastcron = get_field_sql('SELECT max(lastcron) FROM ' . $CFG->prefix . 'modules');
+ // Cron must change an_lastcron. :))
+ $mconfig = get_config('enrol/authorize');
+ $lastcron = intval($mconfig->an_lastcron);
if (time() - $lastcron > 3600 * 24) {
// No!!! I am not lucky. No changes please...
return false;
@@ -525,17 +551,16 @@ function prevent_double_paid($course)
{
global $CFG, $SESSION, $USER;
+ if ($rec = get_record('enrol_authorize', 'userid', $USER->id, 'courseid', $course->id, 'status', AN_STATUS_AUTH, 'id')) {
+ $a->orderid = $rec->id;
+ redirect($CFG->wwwroot, get_string("paymentpending", "enrol_authorize", $a), '20');
+ return;
+ }
if (isset($SESSION->ccpaid)) {
unset($SESSION->ccpaid);
redirect($CFG->wwwroot . '/login/logout.php');
return;
}
-
- if ($rec = get_record('enrol_authorize', 'userid',$USER->id, 'courseid',$course->id, 'status',AN_STATUS_AUTH, 'id')) {
- $a->orderid = $rec->id;
- redirect($CFG->wwwroot, get_string("paymentpending", "enrol_authorize", $a), '20');
- return;
- }
}
@@ -560,78 +585,106 @@ function cron()
parent::cron();
require_once("$CFG->dirroot/enrol/authorize/action.php");
- srand((double)microtime() * 10000000);
- $random100 = rand(0, 100);
$timenow = time();
$timenowsettle = getsettletime($timenow);
$timediff30 = $timenowsettle - (30 * 3600 * 24);
+ // These 2 lines must be HERE and must be EXUCUTED. See process_config.
+ // We use an_lastcron when processing AUTOCAPTURE feature.
+ // Order is important. 1. get_config 2. set_config
+ $mconfig = get_config('enrol/authorize'); // MUST be 1st.
+ set_config('an_lastcron', $timenow, 'enrol/authorize'); // MUST be 2nd.
- if ($random100 < 15) { // delete very old records: status=AN_STATUS_NONE & timecreated=-60day.
- // no credit card transaction is made in status AN_STATUS_NONE.
- $timediff60 = $timenowsettle - (60 * 3600 * 24);
- $select = "(status = '" .AN_STATUS_NONE. "') AND (timecreated < '$timediff60')";
- if (count_records_select('enrol_authorize', $select)) {
- mtrace("Deleting records in authorize table older than 60 days (status=AN_STATUS_NONE).");
- delete_records_select('enrol_authorize', $select);
- }
+ $random100 = mt_rand(0, 100);
+
+ if ($random100 < 33) {
+ $select = "(status = '" .AN_STATUS_NONE. "') AND (timecreated < '$timediff30')";
+ delete_records_select('enrol_authorize', $select);
+ }
+ elseif ($random100 > 66) {
+ $select = "(status = '" .AN_STATUS_AUTH. "') AND (timecreated < '$timediff30')";
+ execute_sql("UPDATE {$CFG->prefix}enrol_authorize SET status = '" .AN_STATUS_EXPIRE. "' WHERE $select", false);
}
- elseif ($random100 > 80) { // EXPIRED: Transactions with auth_only will be expired 30 days later.
- $select = "(status = '" .AN_STATUS_AUTH. "') AND (settletime = '0') AND (timecreated < '$timediff30')";
- execute_sql("UPDATE {$CFG->prefix}enrol_authorize SET settletime = '$timenowsettle', status = '" .AN_STATUS_EXPIRE. "' WHERE $select", false);
+ else {
+ $timediff60 = $timenowsettle - (60 * 3600 * 24);
+ $select = "(status = '" .AN_STATUS_EXPIRE. "') AND (timecreated < '$timediff60')";
+ delete_records_select('enrol_authorize', $select);
}
+ if (!empty($CFG->an_test)) {
+ return; // AUTOCAPTURE doesn't work in test mode.
+ }
if (empty($CFG->an_review) || empty($CFG->an_review_day) || $CFG->an_review_day < 1) {
- // AUTOCAPTURE disabled. admin, teacher review it manually
- return;
+ return; // AUTOCAPTURE disabled. admin, teacher review it manually
}
- // AUTO-CAPTURE: it must be captured within 30 days. Otherwise it will expired.
+ // AUTO-CAPTURE: Transaction must be captured within 30 days. Otherwise it will expired.
$timediffcnf = $timenowsettle - (intval($CFG->an_review_day) * 3600 * 24);
- $select = "(status = '" . AN_STATUS_AUTH . "') AND (settletime = '0') AND (timecreated < '$timediffcnf') AND (timecreated > '$timediff30')";
- if ($orders = get_records_select('enrol_authorize', $select)) {
- $this->log = "AUTHORIZE.NET AUTOCAPTURE CRON: " . userdate($timenow) . "\n";
- @set_time_limit(0);
- $faults = '';
- foreach ($orders as $order) {
- $message = NULL;
- $extra = NULL;
- $reason = AN_REASON_NONE;
- $success = authorizenet_action($order, $message, $reason, $extra, AN_ACTION_PRIOR_AUTH_CAPTURE);
- if ($success) {
- if (!update_record("enrol_authorize", $order)) {
- $this->email_to_admin("Error while trying to update data. Please edit manually this record: " .
- "ID=$order->id in enrol_authorize table.", $order);
- }
- $timestart = $timeend = 0;
- if ($course = get_record_sql("SELECT enrolperiod FROM {$CFG->prefix}course WHERE id='$order->courseid'")) {
- if ($course->enrolperiod) {
- $timestart = $timenow;
- $timeend = $timestart + $course->enrolperiod;
- }
- }
- if (enrol_student($order->userid, $order->courseid, $timestart, $timeend, 'authorize')) {
- $this->log .= "User($order->userid) has been enrolled to course($order->courseid).\n";
- }
- else {
- $faults .= "Error while trying to enrol ".fullname($USER)." in '$course->fullname' \n";
- foreach ($order as $okey => $ovalue) {
- $faults .= " $okey = $ovalue\n";
- }
+ $select = "status = '" .AN_STATUS_AUTH. "' AND timecreated < '$timediffcnf' AND timecreated > '$timediff30'";
+ if (!$orders = get_records('enrol_authorize', $select)) {
+ return;
+ }
+
+ // Calculate connection speed for each transaction. Default: 3 secs.
+ $everyconnection = empty($mconfig->an_eachconnsecs) ? 3 : intval($mconfig->an_eachconnsecs);
+ $ordercount = count((array)$orders);
+ $maxsecs = $everyconnection * $ordercount;
+ if ($maxsecs + intval($mconfig->an_lastcron) > $timenow) {
+ return; // autocapture runs every eachconnsecs*count.
+ }
+
+ $faults = '';
+ $elapsed = time();
+ @set_time_limit(0);
+ $this->log = "AUTHORIZE.NET AUTOCAPTURE CRON: " . userdate($timenow) . "\n";
+ foreach ($orders as $order) {
+ $message = '';
+ $extra = NULL;
+ $oldstatus = $order->status;
+ $success = authorizenet_action($order, $message, $extra, AN_ACTION_PRIOR_AUTH_CAPTURE);
+ if ($success) {
+ if (!update_record("enrol_authorize", $order)) {
+ $this->email_to_admin("Error while trying to update data. Please edit manually this record: " .
+ "ID=$order->id in enrol_authorize table.", $order);
+ }
+ $timestart = $timeend = 0;
+ if ($course = get_record_sql("SELECT enrolperiod FROM {$CFG->prefix}course WHERE id='$order->courseid'")) {
+ if ($course->enrolperiod) {
+ $timestart = $timenow;
+ $timeend = $timestart + $course->enrolperiod;
}
}
- else { // not success
- $this->log .= $message . "\n";
+ if (enrol_student($order->userid, $order->courseid, $timestart, $timeend, 'authorize')) {
+ $this->log .= "User($order->userid) has been enrolled to course($order->courseid).\n";
+ }
+ else {
+ $faults .= "Error while trying to enrol ".fullname($USER)." in '$course->fullname' \n";
+ foreach ($order as $okey => $ovalue) {
+ $faults .= " $okey = $ovalue\n";
+ }
}
}
- $this->log .= "AUTHORIZE.NET CRON FINISHED: " . userdate(time());
- $adminuser = get_admin();
- if (!empty($faults)) {
- email_to_user($adminuser, $adminuser, "AUTHORIZE.NET CRON FAULTS", $faults);
- }
- if (!empty($CFG->enrol_mailadmins)) {
- email_to_user($adminuser, $adminuser, "AUTHORIZE.NET CRON LOG", $this->log);
+ else { // not success
+ $this->log .= "Order $order->id: " . $message . "\n";
+ if ($order->status != $oldstatus) { //expired
+ update_record("enrol_authorize", $order);
+ }
}
}
+
+ $timenow = time();
+ $elapsed = $timenow - $elapsed;
+ $everyconnection = ceil($elapsed / $ordercount);
+ set_config('an_eachconnsecs', $everyconnection, 'enrol/authorize');
+
+ $this->log .= "AUTHORIZE.NET CRON FINISHED: " . userdate($timenow);
+
+ $adminuser = get_admin();
+ if (!empty($faults)) {
+ email_to_user($adminuser, $adminuser, "AUTHORIZE.NET CRON FAULTS", $faults);
+ }
+ if (!empty($CFG->enrol_mailadmins)) {
+ email_to_user($adminuser, $adminuser, "AUTHORIZE.NET CRON LOG", $this->log);
+ }
}
}
?>
Oops, something went wrong.

0 comments on commit 62d9825

Please sign in to comment.