Code:
<?php
/**
* IPSP Billing DirectAPI payment module
*
* @package ipsp billing
* @copyright Copyright 2016 IPSP Billing Team
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version Author: Mario New in v1.0.0
*/
/**
* IPSP Billing DirectAPI Payment module class
*/
class ipsp_billing_directapi extends base {
/**
* $code determines the internal 'code' name used to designate "this" payment module
*
* @var string
*/
var $code;
/**
* $moduleVersion is the plugin version number
*/
var $moduleVersion = '1.0.0';
/**
* $title is the displayed name for this payment method
*
* @var string
*/
var $title;
/**
* $description is admin-display details for this payment method
*
* @var string
*/
var $description;
/**
* $enabled determines whether this module shows or not... in catalog.
*
* @var boolean
*/
var $enabled;
/**
* $sort_order determines the display-order of this module to customers
*/
var $sort_order;
/**
* $commError and $commErrNo are CURL communication error details for debug purposes
*/
var $commError, $commErrNo;
/**
* transaction vars hold the IDs of the completed payment
*/
var $transaction_id, $transaction_messages, $auth_code, $acs_URL, $responsecode;
/**
* internal vars
*/
private $avs_codes, $cvv_codes;
/**
* Constructor
*/
function __construct() {
global $order;
$this->code = 'ipsp_billing_directapi';
$this->title = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CATALOG_TITLE; // Payment module title in Catalog
if (IS_ADMIN_FLAG === true) {
$this->title = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_ADMIN_TITLE;
if (MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE == 'xxxxxxxxxxxxxxxx')
$this->title .= '<span class="alert"> (not configured; API details needed)</span>';
if (MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS == 'Sandbox')
$this->title .= '<span class="alert"> (Sandbox mode)</span>';
$new_version_details = plugin_version_check_for_updates(2050, $this->moduleVersion);
if ($new_version_details !== false) {
$this->title .= '<span class="alert">' . ' - NOTE: A NEW VERSION OF THIS PLUGIN IS AVAILABLE. <a href="' . $new_version_details['link'] . '" target="_blank">[Details]</a>' . '</span>';
}
}
$this->description = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_DESCRIPTION;
$this->enabled = ((MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS == 'True') ? true : false);
$this->sort_order = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_SORT_ORDER;
// determine order-status for transactions
if ((int) MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID > 0) {
$this->order_status = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID;
}
if ($this->responsecode == '116' && MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS == 'Yes') {
$this->form_action_url = $this->acs_URL;
}
$this->_logDir = DIR_FS_LOGS;
}
function update_status() {
}
function javascript_validation() {
return '';
}
function selection() {
global $order;
for ($i = 1; $i < 13; $i++) {
$expires_month[] = array('id' => sprintf('%02d', $i), 'text' => strftime('%B - (%m)', mktime(0, 0, 0, $i, 1, 2000)));
}
$today = getdate();
for ($i = $today['year']; $i < $today['year'] + 15; $i++) {
$expires_year[] = array('id' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)), 'text' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)));
}
// helper for auto-selecting the radio-button next to this module so the user doesn't have to make that choice
$onFocus = ' onfocus="methodSelect(\'pmt-' . $this->code . '\')"';
$selection = array(
'id' => $this->code,
'module' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CATALOG_TITLE,
'fields' => array(
array(
'title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_NUMBER,
'field' => zen_draw_input_field($this->code . '_cc_number', '', 'payeezy-data="cc_number" id="' . $this->code . '_cc-number"' . $onFocus . ' autocomplete="off"'),
'tag' => $this->code . '_cc-number'
),
array(
'title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_EXPIRES,
'field' => zen_draw_pull_down_menu($this->code . '_cc_expires_month', $expires_month, strftime('%m'), 'payeezy-data="exp_month" id="' . $this->code . '_cc-expires-month"' . $onFocus) . ' ' .
zen_draw_pull_down_menu($this->code . '_cc_expires_year', $expires_year, '', 'payeezy-data="exp_year" id="' . $this->code . '_cc-expires-year"' . $onFocus),
'tag' => $this->code . '_cc-expires-month'
),
array(
'title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CVV,
'field' => zen_draw_input_field($this->code . '_cc_cvv', '', 'size="4" maxlength="4"' . 'payeezy-data="cvv_code" id="' . $this->code . '_cc-cvv"' . $onFocus . ' autocomplete="off"'),
'tag' => $this->code . '_cc-cvv'
),
)
);
return $selection;
}
function pre_confirmation_check() {
global $messageStack;
if (!isset($_POST[$this->code . '_cc_number']) || trim($_POST[$this->code . '_cc_number']) == '' || !isset($_POST[$this->code . '_cc_cvv']) || trim($_POST[$this->code . '_cc_cvv']) == '') {
$messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ERROR_MISSING_FDTOKEN, 'error');
zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
}
}
function confirmation() {
$confirmation = array('fields' => array(
array('title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_NUMBER,
'field' => zen_output_string_protected($_POST[$this->code . '_cc_number'])),
array('title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_EXPIRES,
'field' => strftime('%B, %Y', mktime(0, 0, 0, $_POST[$this->code . '_cc_expires_month'], 1, $_POST[$this->code . '_cc_expires_year']))),
));
return $confirmation;
}
function process_button() {
$process_button_string = zen_draw_hidden_field('cc_number', zen_output_string_protected($_POST[$this->code . '_cc_number']));
$process_button_string .= zen_draw_hidden_field('cc_expires_month', (int) $_POST[$this->code . '_cc_expires_month']);
$process_button_string .= zen_draw_hidden_field('cc_expires_year', (int) $_POST[$this->code . '_cc_expires_year']);
$process_button_string .= zen_draw_hidden_field('cc_cvv', zen_output_string_protected($_POST[$this->code . '_cc_cvv']));
return $process_button_string;
}
function before_process() {
global $db, $messageStack, $order, $currencies;
// Calculate the next expected order id
$result = $db->Execute("select max(orders_id)+1 as orders_id from " . TABLE_ORDERS . " order by orders_id");
$next_order_id = $result->fields['orders_id'];
// add randomized suffix to order id to produce uniqueness ... since it's unwise to submit the same order-number twice to the gateway, and this order is not yet committed
$next_order_id = (string) $next_order_id . '-' . zen_create_random_value(6, 'chars');
//$customer_ip = $_SERVER["REMOTE_ADDR"];
$xml = '<?xml version="1.0" encoding="utf-8"?>
<Request type="AuthorizeCapture">
<AccountID>' . MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ACC_ID . '</AccountID>
<AccountAuth>' . MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE . '</AccountAuth>
<Transaction>
<Reference>' . $next_order_id . '</Reference>
<Amount>' . number_format($order->info['total'], 2) . '</Amount>
<Currency>' . strtoupper($order->info['currency']) . '</Currency>
<Email>' . $order->customer['email_address'] . '</Email>
<IPAddress>' . '175.45.134.67' . '</IPAddress>
<Phone>' . $order->customer['telephone'] . '</Phone>
<FirstName>' . $order->billing['firstname'] . '</FirstName>
<LastName>' . $order->billing['lastname'] . '</LastName>
<Address>' . $order->billing['street_address'] . '</Address>
<City>' . $order->billing['city'] . '</City>
<State>' . $order->billing['state'] . '</State>
<PostCode>' . $order->billing['postcode'] . '</PostCode>
<Country>' . $order->billing['country']['iso_code_2'] . '</Country>
<CardNumber>' . $_POST['cc_number'] . '</CardNumber>
<CardExpMonth>' . $_POST['cc_expires_month'] . '</CardExpMonth>
<CardExpYear>' . $_POST['cc_expires_year'] . '</CardExpYear>
<CardCVV>' . $_POST['cc_cvv'] . '</CardCVV>
</Transaction>
</Request>';
$this->logTransactionData($xml);
$result = $this->send_request(MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_GATEWAY_URL, $xml);
$this->logTransactionData($result);
$response = $this->get_responsestatus($result);
// log the response data
$this->logTransactionData($response);
if ($response === FALSE) {
$messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ERROR_DECLINED, 'error');
zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
} else {
if ($response['responsecode'] == '100' || $response['responsecode'] == '110') {
$this->transaction_id = $response['txid'];
$this->transaction_messages = $response['msg'];
return true;
} elseif ($response['responsecode'] == '116' && MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS == 'Yes') {
$ACSURL = $response['ACSURL'];
$PaReq = $response['PaReq'];
$MD = $response['MD'];
$html = '<html><head><title>Three DS Verification</title></head><body>';
$html.= '<form action='.$ACSURL.' method="post" id="threeds_direct">'
. '<input type="hidden" name="PaReq" value='.$PaReq.'>'
. '<input type="hidden" name="MD" value='.$MD.'>'
. '<input type="hidden" name="TermUrl" value="http://magento1.chetu.local/index.php?main_page=checkout_payment/">'
. '</form>';
$html.= '<div style="text-align:center;">You will be redirected for 3DS verification. Please do not refresh page!!!<br/><br/>
<img title="Loading next step..." alt="Loading next step..." ></div>';
$html.= '<script type="text/javascript">document.getElementById("threeds_direct").submit();</script></body></html>';
echo $html;
//zen_redirect(zen_href_link($response['ACSURL'], '', 'SSL', true, false));
} else {
$messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ERROR_PAYMNET_GATEWAY, 'error');
zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
}
}
}
/**
* Post-process activities. Updates the order-status history data with the auth code from the transaction.
*
* @return boolean
*/
function after_process() {
global $insert_id, $db, $order;
$sql = "insert into " . TABLE_ORDERS_STATUS_HISTORY . " (comments, orders_id, orders_status_id, customer_notified, date_added) values (:orderComments, :orderID, :orderStatus, 1, now() )";
$sql = $db->bindVars($sql, ':orderComments', 'Credit Card payment. TransID: ' . $this->transaction_id . ' - ' . $this->transaction_messages, 'string');
$sql = $db->bindVars($sql, ':orderID', $insert_id, 'integer');
$sql = $db->bindVars($sql, ':orderStatus', $this->order_status, 'integer');
$db->Execute($sql);
return false;
}
function check() {
global $db;
if (!isset($this->_check)) {
$check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS'");
$this->_check = $check_query->RecordCount();
}
return $this->_check;
}
function install() {
global $db;
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable IPSP Billing DirectAPI Module', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS', 'True', 'Check true to enable this payment method.', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_SORT_ORDER', '0', 'Sort order of displaying payment options to the customer. Lowest is displayed first.', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Order Status', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID', '2', 'Set the status of orders made with this payment module to this value', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Account ID', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ACC_ID', 'xxxxxxxx', 'This is your 8 digit account ID.', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Authentication Code', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE', 'xxxxxxxxxxxxxxxx', 'This is your 16 character authentication code.', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Payment gateway URL', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_GATEWAY_URL', '', 'The payment gateway URL.', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Notification URL', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_NOTIFICATION_URL', '', 'Notification URL for payment status.', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable 3DS', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS', 'No', 'For 3DS only', '6', '0', 'zen_cfg_select_option(array(\'Yes\', \'No\'), ', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Term URL', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TERM_URL', '', 'For 3DS only.', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable log', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_LOGGING', 'True', 'Check true to enable log.', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
}
function remove() {
global $db;
$db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
}
function keys() {
return array(
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_SORT_ORDER',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ACC_ID',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_GATEWAY_URL',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_NOTIFICATION_URL',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TERM_URL',
'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_LOGGING',
);
}
private function send_request($url, $xml) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
private function get_responsestatus($result) {
$xmlresult = simplexml_load_string($result);
// Simple display of the end result
if (isset($xmlresult->ResponseCode)) {
$status['responsecode'] = $xmlresult->ResponseCode;
}
if (isset($xmlresult->Description)) {
$status['msg'] = $xmlresult->Description;
}
if (isset($xmlresult->Reference)) {
$status['reference'] = $xmlresult->Reference;
}
if (isset($xmlresult->TransactionID)) {
$status['txid'] = $xmlresult->TransactionID;
}
if (isset($xmlresult->ProcessingTime)) {
$status['processingtime'] = $xmlresult->ProcessingTime;
}
if (isset($xmlresult->StatusCode)) {
$status['statuscode'] = $xmlresult->StatusCode;
}
if (isset($xmlresult->StatusDescription)) {
$status['statusdescription'] = $xmlresult->StatusDescription;
}
if (isset($xmlresult->ThreeDS->ACSURL)) {
$status['ACSURL'] = $xmlresult->ThreeDS->ACSURL;
}
if (isset($xmlresult->ThreeDS->PaReq)) {
$status['PaReq'] = $xmlresult->ThreeDS->PaReq;
}
if (isset($xmlresult->ThreeDS->MD)) {
$status['MD'] = $xmlresult->ThreeDS->MD;
}
if (isset($xmlresult->RefTrxID)) {
$status['RefTrxID'] = $xmlresult->RefTrxID;
}
if (isset($status['responsecode'])) {
return $status;
} else {
return FALSE;
}
}
/**
* Log transaction errors if enabled
*/
private function logTransactionData($response) {
global $db;
$logMessage = date('M-d-Y h:i:s') .
"\n=================================\n\n" .
'' . $response . "\n";
if (strstr(MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_LOGGING, 'True')) {
$todayDate = date('Y-m-d');
$file = $this->_logDir . '/' . 'IPSP_Billing_' . $todayDate . '.log';
if ($fp = @fopen($file, 'a')) {
fwrite($fp, $logMessage);
fclose($fp);
}
}
}
}
Bookmarks