File: /home/confeduphaar/backip-old-files/plugins/vmpayment/paybox/paybox/helpers/paybox.php
<?php
/**
*
* Paybox payment plugin
*
* @author Valérie Isaksen
* @version $Id$
* @package VirtueMart
* @subpackage payment
* @copyright Copyright (c) 2004 - 2018 VirtueMart Team. All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
*
* http://virtuemart.net
*/
defined('_JEXEC') or die('Restricted access');
class PayboxHelperPaybox {
const PBX_MAX_URL_LEN = 150;
const RESPONSE_SUCCESS = '00000';
const TYPEPAIEMENT_CARTE = 'CARTE';
const TYPECARTE_CB = 'CB';
const TYPE_DIRECT_AUTHORIZATION_ONLY = '00001';
const TYPE_DIRECT_CAPTURE = '00002';
const TYPE_DIRECT_AUTHORIZATION_CAPTURE = '00003';
function __construct ($method, $plugin, $plugin_name) {
$this->_method = $method;
$this->_method->site_id = trim($this->_method->site_id) ;
$this->_method->rang = trim($this->_method->rang) ;
$this->_method->identifiant = trim($this->_method->identifiant) ;
$this->_method->key = trim($this->_method->key) ;
$this->plugin = $plugin;
$this->plugin_name=$plugin_name;
}
/**
* @param $cart
* @param $order
* @return bool
*/
function confirmedOrder ($cart, $order) {
if (!class_exists('VirtueMartModelOrders')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'orders.php');
}
if (!class_exists('VirtueMartModelCurrency')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'currency.php');
}
$this->plugin->getPaymentCurrency($this->_method);
$q = 'SELECT `currency_numeric_code` FROM `#__virtuemart_currencies` WHERE `virtuemart_currency_id`="' . $this->_method->payment_currency . '" ';
$db = JFactory::getDBO();
$db->setQuery($q);
$currency_numeric_code = $db->loadResult();
$totalInPaymentCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total, $this->_method->payment_currency);
$orderTotalVendorCurrency = $order['details']['BT']->order_total;
$pbxOrderTotalInPaymentCurrency = $this->getPbxAmount($totalInPaymentCurrency['value']);
$email_currency = $this->plugin->getEmailCurrency($this->_method);
// If the file is not there anylonger, just create it
//$this->plugin->createRootFile($this->_method->virtuemart_paymentmethod_id);
if (!$this->getPayboxServerUrl()) {
$this->redirectToCart();
return false;
}
if (!($payboxReturnUrls = $this->getPayboxReturnUrls())) {
$this->redirectToCart();
return false;
}
$post_variables = Array(
"PBX_SITE" => $this->_method->site_id,
"PBX_RANG" => $this->_method->rang,
"PBX_IDENTIFIANT" => $this->_method->identifiant,
"PBX_TOTAL" => $this->getPbxTotal($pbxOrderTotalInPaymentCurrency),
"PBX_DEVISE" => $currency_numeric_code,
"PBX_CMD" => $order['details']['BT']->order_number,
"PBX_PORTEUR" => $order['details']['BT']->email,
"PBX_RETOUR" => $this->getReturn(),
"PBX_HASH" => $this->getHashAlgo(),
"PBX_TIME" => $this->getTime(),
"PBX_LANGUE" => $this->getLangue(),
//"PBX_TYPEPAIEMENT" => $this->getTypePaiement(),
//"PBX_TYPECARTE" => $this->getTypeCarte(),
"PBX_EFFECTUE" => $payboxReturnUrls['url_effectue'],
// "PBX_ATTENTE" => $payboxReturnUrls['url_attente'],
"PBX_ANNULE" => $payboxReturnUrls['url_annule'],
"PBX_REFUSE" => $payboxReturnUrls['url_refuse'],
"PBX_ERREUR" => $payboxReturnUrls['url_erreur'],
"PBX_REPONDRE_A" => $payboxReturnUrls['url_notification'],
"PBX_RUF1" => 'POST',
);
if ($this->_method->debit_type == 'authorization_only') {
$post_variables["PBX_DIFF"] = str_pad($this->_method->diff, 2, '0', STR_PAD_LEFT);
}
// min_amount_3dsecure is in vendor currency
if (!($this->isActivate3ds($orderTotalVendorCurrency) )) {
$post_variables["PBX_3DS"] = 'N';
}
jimport('joomla.environment.browser');
$browser = JBrowser::getInstance();
if ($browser->isMobile()) {
$post_variables["PBX_SOURCE"] = 'XHTML';
}
$subscribe = array();
$recurring = array();
$post_variables["PBX_CMD"] = $order['details']['BT']->order_number;
if ($this->_method->integration == "recurring" ) {
$recurring = $this->getRecurringPayments($pbxOrderTotalInPaymentCurrency);
// PBX_TOTAL will be replaced in the array_merge.
$post_variables = array_merge($post_variables, $recurring);
} else {
if ($this->_method->integration == "subscribe") {
$subscribe_data = $this->getSubscribePayments($cart, $this->getPbxAmount($orderTotalVendorCurrency));
if ($subscribe_data) {
// PBX_TOTAL is the order total in this case
$post_variables["PBX_TOTAL"] = $subscribe_data["PBX_TOTAL"];
$post_variables["PBX_CMD"] .= $subscribe_data['PBX_CMD'];
}
}
}
$post_variables["PBX_HMAC"] = $this->getHmac($post_variables, $this->_method->key);
// Prepare data that should be stored in the database
$dbValues['order_number'] = $order['details']['BT']->order_number;
$dbValues['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id;
$dbValues['payment_name'] = $this->plugin->renderPluginName($this->_method);
$dbValues['virtuemart_paymentmethod_id'] = $cart->virtuemart_paymentmethod_id;
$dbValues['paybox_custom'] = $this->getContext();
$dbValues['cost_per_transaction'] = $this->_method->cost_per_transaction;
$dbValues['cost_percent_total'] = $this->_method->cost_percent_total;
$dbValues['payment_currency'] = $this->_method->payment_currency;
$dbValues['email_currency'] = $email_currency;
$dbValues['payment_order_total'] = $post_variables["PBX_TOTAL"];
if (!empty($recurring)) {
$dbValues['recurring'] = json_encode($recurring);
$dbValues['recurring_number'] = $this->_method->recurring_number;
$dbValues['recurring_periodicity'] = $this->_method->recurring_periodicity;
} else {
$dbValues['recurring'] = NULL;
}
if (!empty($subscribe)) {
$dbValues['subscribe'] = json_encode($subscribe);
//$dbValues['recurring_number'] = $this->_method->recurring_number;
//$dbValues['recurring_periodicity'] = $this->_method->recurring_periodicity;
} else {
$dbValues['subscribe'] = NULL;
}
$dbValues['tax_id'] = $this->_method->tax_id;
$this->plugin->storePSPluginInternalData($dbValues);
$html = $this->getConfirmedHtml($post_variables, $this);
// 2 = don't delete the cart, don't send email and don't redirect
$cart->_confirmDone = FALSE;
$cart->_dataValidated = FALSE;
$cart->setCartIntoSession();
vRequest::setVar('display_title', false);
vRequest::setVar('html', $html);
return;
}
function isActivate3ds($orderTotalVendorCurrency) {
return $this->_method->activate_3dsecure=='active' OR ($this->_method->activate_3dsecure=='selective' AND ($orderTotalVendorCurrency > $this->_method->min_amount_3dsecure));
}
/**
* @param $paybox_data
* @return bool
*/
function paymentResponseReceived ($paybox_data) {
if ($payboxResponseValid = $this->isPayboxResponseValid( $paybox_data, false, true)) {
// we don't do anything actually, it is probably an invalid signature.
// we do not update order status and let IPN do his job
}
$order_number = $this->getOrderNumber($paybox_data['R']);
if (empty($order_number)) {
$this->plugin->debugLog($order_number, 'getOrderNumber not correct' . $paybox_data['R'], 'debug', false);
return FALSE;
}
if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) {
return FALSE;
}
if (!($payments = $this->plugin->getPluginDatasByOrderId($virtuemart_order_id))) {
$this->plugin->debugLog('no payments found', 'getDatasByOrderId', 'debug', false);
$this->redirectToCart();
return FALSE;
}
$orderModel = VmModel::getModel('orders');
$order = $orderModel->getOrder($virtuemart_order_id);
$paybox_data = $this->unsetNonPayboxData($paybox_data);
$success = ($paybox_data['E'] == self::RESPONSE_SUCCESS);
$extra_comment = "";
// The order status is nly updated if the validation is ok
if ($payboxResponseValid) {
if (count($payments) == 1) {
// NOTIFY not received
$order_history = $this->updateOrderStatus( $paybox_data, $order, $payments);
if (isset($order_history['extra_comment'])) {
$extra_comment = $order_history['extra_comment'];
}
}
}
$html = $this->plugin->getResponseHTML($order, $paybox_data, $success, $extra_comment);
$cart = VirtueMartCart::getCart();
$cart->emptyCart();
return $html;
}
/**
* @param $virtuemart_order_id
* @return string
*/
function showOrderBEPayment ($virtuemart_order_id) {
$db = JFactory::getDBO();
$q = 'SELECT * FROM `' . $this->plugin->getTablename() . '` WHERE ';
$q .= ' `virtuemart_order_id` = ' . $virtuemart_order_id;
$db->setQuery($q);
$payments = $db->loadObjectList();
$html = '<table class="adminlist table">' . "\n";
$html .= $this->plugin->getHtmlHeaderBE();
$first = TRUE;
$lang = JFactory::getLanguage();
foreach ($payments as $payment) {
$html .= '<tr class="row1"><td>' . vmText::_('VMPAYMENT_' . $this->plugin_name . '_DATE') . '</td><td align="left">' . $payment->created_on . '</td></tr>';
// Now only the first entry has this data when creating the order
if ($first) {
$html .= $this->plugin->getHtmlRowBE($this->plugin_name . '_PAYMENT_NAME', $payment->payment_name);
// keep that test to have it backwards compatible. Old version was deleting that column when receiving an IPN notification
if ($payment->payment_order_total and $payment->payment_order_total != 0.00) {
$html .= $this->plugin->getHtmlRowBE($this->plugin_name . '_PAYMENT_ORDER_TOTAL', ($payment->payment_order_total * 0.01) . " " . shopFunctions::getCurrencyByID($payment->payment_currency, 'currency_code_3'));
}
if ($payment->email_currency and $payment->email_currency != 0) {
//$html .= $this->getHtmlRowBE($this->_name.'_PAYMENT_EMAIL_CURRENCY', shopFunctions::getCurrencyByID($payment->email_currency, 'currency_code_3'));
}
if ($payment->recurring) {
$recurring_html = '<table class="adminlist table">' . "\n";
$recurring = json_decode($payment->recurring);
$recurring_html .= $this->plugin->getHtmlRowBE($this->plugin_name . '_CONF_RECURRING_PERIODICTY', $payment->recurring_periodicity);
$recurring_html .= $this->plugin->getHtmlRowBE($this->plugin_name . '_CONF_RECURRING_NUMBER', $payment->recurring_number);
//$recurring_html .= $this->getHtmlRowBE(VmText::_('VMPAYMENT_'.$this->_name.'_CONF_RECURRING_PERIODICTY').' '. $payment->recurring_periodicity, VmText::_('VMPAYMENT_'.$this->_name.'_CONF_RECURRING_NUMBER').' '. $payment->recurring_number);
for ($i = 1; $i < $payment->recurring_number; $i++) {
$index_mont = "PBX_2MONT" . $i;
$index_date = "PBX_DATE" . $i;
$text_mont = vmText::_('VMPAYMENT_' . $this->plugin_name . '_PAYMENT_RECURRING_2MONT') . " " . $i;
$text_date = vmText::_('VMPAYMENT_' . $this->plugin_name . '_PAYMENT_RECURRING_DATE') . " " . $i;
//$recurring_html .= $this->getHtmlRowBE($text_date, $recurring->$index_date);
//$recurring_html .= $this->getHtmlRowBE($text_mont, ($recurring->$index_mont * 0.01) . " " . shopFunctions::getCurrencyByID($payment->payment_currency, 'currency_code_3'));
$recurring_html .= $this->plugin->getHtmlRowBE($recurring->$index_date, ($recurring->$index_mont * 0.01) . " " . shopFunctions::getCurrencyByID($payment->payment_currency, 'currency_code_3'));
}
$recurring_html .= '</table>' . "\n";
$html .= $this->plugin->getHtmlRowBE($this->plugin_name . '_RECURRING', $recurring_html);
}
$first = FALSE;
} else {
if (!empty($payment->paybox_fullresponse)) {
$paybox_data = json_decode($payment->paybox_fullresponse);
$showOrderBEFields = $this->getOrderBEFields();
$prefix = $this->plugin_name . '_RESPONSE_';
foreach ($showOrderBEFields as $showOrderBEField) {
if (isset($paybox_data->$showOrderBEField) and !empty($paybox_data->$showOrderBEField)) {
$key = $prefix . $showOrderBEField;
if (method_exists($this, 'getValueBE_' . $showOrderBEField)) {
$function = 'getValueBE_' . $showOrderBEField;
$paybox_data->$showOrderBEField = $this->$function($paybox_data->$showOrderBEField);
}
$html .= $this->plugin->getHtmlRowBE($key, $paybox_data->$showOrderBEField);
}
}
$html .= '<tr><td></td><td>
<a href="#" class="PayboxLogOpener" rel="' . $payment->id . '" >
<div style="background-color: white; z-index: 100; right:0; display: none; border:solid 2px; padding:10px;" class="vm-absolute" id="PayboxLog_' . $payment->id . '">';
foreach ($paybox_data as $key => $value) {
$langKey = 'VMPAYMENT_' . $prefix . $key;
if ($lang->hasKey($langKey)) {
$label = vmText::_($langKey);
} else {
$label = $key;
}
$html .= ' <b>' . $label . '</b>: ' . wordwrap($value, 50, "\n", true) . '<br />';
}
$html .= ' </div>
<span class="icon-nofloat vmicon vmicon-16-xml"></span> ';
$html .= vmText::_('VMPAYMENT_' . $this->plugin_name . '_VIEW_TRANSACTION_LOG');
$html .= ' </a>';
$html .= ' </td></tr>';
}
}
}
$html .= '</table>' . "\n";
$doc = JFactory::getDocument();
$js = "
jQuery().ready(function($) {
$('.PayboxLogOpener').click(function() {
var logId = $(this).attr('rel');
$('#PayboxLog_'+logId).toggle();
return false;
});
});";
$doc->addScriptDeclaration($js);
return $html;
}
/**
* @param $post_variables
* @return string
*/
function getConfirmedHtml ($post_variables) {
$pbxServer = $this->getPayboxServerUrl();
// add spin image
$html='';
if ($this->_method->debug) {
$html .= '<form action="' . $pbxServer . '" method="post" name="vm_paybox_form" target="paybox">';
} else {
if (vmconfig::get('css')) {
$msg = vmText::_('VMPAYMENT_PAYBOX_REDIRECT_MESSAGE', true);
} else {
$msg='';
}
vmJsApi::addJScript('vm.paymentFormAutoSubmit', '
jQuery(document).ready(function($){
jQuery("body").addClass("vmLoading");
var msg="'.$msg.'";
jQuery("body").append("<div class=\"vmLoadingDiv\"><div class=\"vmLoadingDivMsg\">"+msg+"</div></div>");
jQuery("#vmPaymentForm").submit();
})
');
$html .= '<form action="' . $pbxServer . '" method="post" name="vm_paybox_form" id="vmPaymentForm">';
}
foreach ($post_variables as $name => $value) {
$html .= '<input type="hidden" name="' . $name . '" value="' . $value . '" />';
}
if ($this->_method->debug) {
$this->plugin->debugLog($this->_method->virtuemart_paymentmethod_id, 'sendPostRequest: payment method', 'debug');
$this->plugin->debugLog($pbxServer, 'sendPostRequest: Server', 'debug');
$html .= '<div style="background-color:red;color:white;padding:10px;">
<input type="submit" value="The method is in debug mode. Click here to be redirected to Paybox" />
</div>';
$this->plugin->debugLog($post_variables, 'sendPostRequest:', 'debug');
}else {
$html .= '<input type="submit" value="' . vmText::_('VMPAYMENT_PAYBOX_REDIRECT_MESSAGE') . '" />';
}
$html .= '</form>';
return $html;
}
private function getContext () {
$session = JFactory::getSession();
return $session->getId();
}
/**
* @param $paybox_data
* @param bool $checkIps
* @param bool $useQuery
* @return bool
*/
function isPayboxResponseValid ( $paybox_data, $checkIps = false, $useQuery = false) {
$unsetNonPayboxData = true;
if ($this->checkSignature($paybox_data, $unsetNonPayboxData, $useQuery) != 1) {
$msg = 'Got a Paybox request with invalid signature';
$this->plugin->debugLog($msg, 'checkSignature', 'error', false);
return FALSE;
} else {
$this->plugin->debugLog('Got a Paybox request VALID signature', 'checkSignature', 'debug', false);
}
return true;
}
/**
* @param $paybox_data
* @param bool $unsetNonPayboxData
* @param bool $useQuery
* @return bool
*/
private function checkSignature ( $paybox_data, $unsetNonPayboxData = true, $useQuery = true) {
if (!$useQuery) {
//
// some SEF components changes the variable order !!!!!!!
$paybox_data = $this->getVariablesInPbxOrder( $paybox_data);
if ($unsetNonPayboxData) {
$paybox_data = $this->unsetNonPayboxData($paybox_data);
}
$query_string = $this->stringifyArray($paybox_data);
} else {
//$this->plugin->debugLog('TAKE QUERY' ,'checkSignature', 'debug');
parse_str($_SERVER['QUERY_STRING'], $paybox_data);
$paybox_data = $this->getVariablesInPbxOrder( $paybox_data);
$query_string = $this->stringifyArray($paybox_data);
$query_string=$_SERVER['QUERY_STRING'];
}
//$this->plugin->debugLog('checkSignature query:' . $query_string, 'debug');
$keyFile = $this->getKeyFileName();
//$this->plugin->debugLog('checkSignature :' . $keyFile, 'debug');
$pbxIsValidSignature = $this->pbxIsValidSignature($keyFile, $query_string);
if (!$useQuery and !$pbxIsValidSignature) {
// only send an error message if the error does not come from PBX_EFFECTUE
//$msg .= ' ' . 'sig ' . $sig . '<br />';
// we cannot send an error at this stage because may be the signature is not valid from the
$this->plugin->debugLog(vmText::_('VMPAYMENT_'.$this->plugin_name.'_ERROR_SIGNATURE_INVALID'),'pbxIsValidSignature', 'error');
}
$this->plugin->debugLog('pbxIsValidSignature :' . $pbxIsValidSignature,'checkSignature', 'debug');
return $pbxIsValidSignature;
}
/**
* @return string
*/
function getKeyFileName () {
$path=VMPATH_ROOT . DS. 'plugins'.DS.'vmpayment'.DS.$this->plugin_name.DS.$this->plugin_name.DS.'key' .DS;
return $path .'pubkey.pem';
}
/**
* Display amount as decimal value
* @param $value
* @return mixed
*/
function getValueBE_M ($value) {
return $value * 0.01;
}
/**
* display date
* @param $value
* @return string
*/
function getValueBE_D ($value) {
return substr($value, 0, -2) . "/" . substr($value, -2);
}
function getOrderBEFields () {
$fields = array(
'M',
//'R',
//'T',
'E',
// 'A',
'B',
'P',
'C',
'S',
//'Y',
'N',
'J',
'D',
//'H',
'G',
'O',
'F',
// 'W',
// 'Z',
// 'K', // MUST BE THE LAST ONE
);
return $fields;
}
/**
* @param $this
* @param $paybox_data
* @param $order
* @return bool
*/
function updateOrderStatus ( $paybox_data, $order, $payments) {
$success = ($paybox_data['E'] == self::RESPONSE_SUCCESS);
if ($success) {
$order_history = $this->getOrderHistory($paybox_data, $order, $payments);
} else {
$order_history['comments'] = vmText::sprintf('VMPAYMENT_' . $this->plugin_name . '_PAYMENT_STATUS_CANCELLED', $order['details']['BT']->order_number);
$order_history['order_status'] = $this->_method->status_canceled;
$order_history['customer_notified'] = true;
}
//$this->plugin->debugLog($success, 'updateOrderStatus', 'error', false);
$db_values['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id;
$db_values['order_number'] = $order['details']['BT']->order_number;
$db_values['virtuemart_paymentmethod_id'] = $this->_method->virtuemart_paymentmethod_id;
// get all know columns of the table
$db = JFactory::getDBO();
$tablename= $this->plugin->getTablename();
$query = 'SHOW COLUMNS FROM `' . $tablename . '` ';
$db->setQuery($query);
$columns = $db->loadColumn(0);
foreach ($paybox_data as $key => $value) {
$table_key = $this->plugin_name . '_response_' . $key;
if (in_array($table_key, $columns)) {
$db_values[$table_key] = $value;
}
}
$db_values[$this->plugin_name . '_fullresponse'] = json_encode($paybox_data);
$this->plugin->debugLog('updateOrderStatus storePSPluginInternalData:' . var_export($db_values, true), 'debug');
$this->plugin->storePSPluginInternalData($db_values);
$modelOrder = VmModel::getModel('orders');
$modelOrder->updateStatusForOneOrder($order['details']['BT']->virtuemart_order_id, $order_history, TRUE);
return $order_history;
}
/**
* URLS sent to Paybox must be less than 250 characters
* @param $this
* @return bool
*/
function getPayboxReturnUrls () {
$urlLength = true;
$url_cancelled = JURI::root() . 'index.php?option=com_virtuemart&view=cart&lang=' . vRequest::getCmd('lang', '') . '&Itemid=' . vRequest::getInt('Itemid');
$payboxURLs['url_annule'] = $url_cancelled;
$payboxURLs['url_refuse'] = $url_cancelled;
$payboxURLs['url_erreur'] = $url_cancelled;
$payboxURLs['url_notification'] = JURI::root() . 'index.php?option=com_virtuemart&format=raw&view=pluginresponse&task=pluginnotification&tmpl=component&pm=' . $this->_method->virtuemart_paymentmethod_id;
$payboxURLs['url_effectue'] = $this->getUrlOk();
foreach ($payboxURLs as $payboxURL) {
//$this->plugin->debugLog($payboxURL, 'getPayboxReturnUrls','debug');
if (!$this->checkURLsLength($payboxURL)) {
$urlLength = false;
}
}
if ($urlLength) {
return $payboxURLs;
} else {
$this->plugin->debugLog('FALSE', 'getPayboxReturnUrls', 'debug');
return false;
}
}
function checkURLsLength ($url) {
$public_msg = "";
if (strlen($url) > self::PBX_MAX_URL_LEN) {
$msg = 'checking URL length<br />Your URL:' . $url . ' has ' . strlen($url) . ' characters.';
$msg .= 'The maximum allowed by the payment is ' . self::PBX_MAX_URL_LEN;
$msg .= 'Please contact your payment provider';
$this->pbxError($msg);
$this->plugin->debugLog($msg, 'checkURLsLength FALSE', 'debug');
return false;
}
return true;
}
function getUrlOk () {
$urlOkParms = $this->getUrlOkParms();
$query = $this->stringifyArray($urlOkParms);
$urlOk = JURI::root() . 'index.php?' . $query;
return $urlOk;
}
/**
* $url_ok = JURI::root() . 'index.php?option=com_virtuemart&view=vmplg&task=pluginresponsereceived&pm=' . $order['details']['BT']->virtuemart_paymentmethod_id . '&Itemid=' . vRequest::getInt('Itemid');
* @return array
*/
function getUrlOkParms () {
$urlOkParms = array(
"option" => "com_virtuemart",
"view" => "pluginresponse",
"task" => "pluginresponsereceived",
"pm" => $this->_method->virtuemart_paymentmethod_id,
"lang" => vRequest::uWord('lang', ''),
"Itemid" => vRequest::getInt('Itemid'),
);
return $urlOkParms;
}
/**
*
*/
private function redirectToCart () {
$app = JFactory::getApplication();
$app->redirect(JRoute::_('index.php?option=com_virtuemart&view=cart&lg=&Itemid=' . vRequest::getInt('Itemid'), false), vmText::_('VMPAYMENT_PAYBOX_ERROR_TRY_AGAIN'));
}
public function getReturnFields () {
$fields = array(
'M',
'R',
'T',
'A',
'B',
'P',
'C',
'S',
'Y',
'E',
'D',
'I',
'N',
'J',
'H',
'G',
'O',
'F',
'W',
'Z',
'K', // MUST BE THE LAST ONE
);
return $fields;
}
/**
* some SEF components changes the variable order !!!!!!! ^
* we need to have them in the same order as they are recieved to check the signature
* @param $paybox_data
* @return mixed
*/
private function getVariablesInPbxOrder ($paybox_data) {
$this->plugin->debugLog('getVariablesInPbxOrder :' . var_export($paybox_data, true), 'debug');
$paybox_data_ordered = array();
$urlOkParms = $this->getUrlOkParms();
foreach ($urlOkParms as $key => $urlOkParm) {
$paybox_data_ordered[$key] = $paybox_data[$key];
}
$returnFields = $this->getReturnFields();
foreach ($returnFields as $returnField) {
if (isset($paybox_data[$returnField])) {
$paybox_data_ordered[$returnField] = $paybox_data[$returnField];
}
}
$this->plugin->debugLog('getVariablesInPbxOrder PBX order:' . var_export($paybox_data_ordered, true), 'debug');
return $paybox_data_ordered;
}
public function setOrder ($order) {
$this->order = $order;
}
public function unsetNonPayboxData ($paybox_data) {
$returnFields = $this->getReturnFields();
foreach ($paybox_data as $key => $value) {
if (!in_array($key, $returnFields)) {
unset($paybox_data[$key]);
}
}
return $paybox_data;
}
public function getReturn () {
$returnFieldsString = '';
$returnFields = $this->getReturnFields();
foreach ($returnFields as $returnField) {
$returnFieldsString .= $returnField . ":" . $returnField . ';';
}
return substr($returnFieldsString, 0, -1);
}
public function getType () {
switch ($this->_method->type) {
case 'authorization_capture':
return self::TYPE_DIRECT_AUTHORIZATION_CAPTURE;
break;
case 'authorization_only':
default:
return self::TYPE_DIRECT_AUTHORIZATION_ONLY;
break;
}
}
function getPbxAmount ($amount) {
return round($amount * 100);
}
/**
* @param $total
* @return string
*/
function getPbxTotal ($total) {
return str_pad($total, 3, "0", STR_PAD_LEFT);
}
/**
* @param $value
* @return string
*/
function getUniqueId ($value) {
return $value . '-' . time();
}
/**
* @param $post
* @param $payboxKey
* @return string
*/
function getHmac ($post, $payboxKey) {
$msg = '';
$msg = $this->stringifyArray($post);
$hmac = $this->generateHMAC($msg, $payboxKey);
return $hmac;
}
function stringifyArray ($array) {
$string = '';
foreach ($array as $key => $value) {
$string .= trim($key) . "=" . trim($value) . '&';
}
return substr($string, 0, -1);
}
/**
* @return string
*/
function getHashAlgo () {
return "SHA512";
}
private function generateHMAC ($msg, $payboxKey) {
$binKey = pack("H*", $payboxKey);
$hmac = strtoupper(hash_hmac($this->getHashAlgo(), $msg, $binKey));
return $hmac;
}
function getLangue () {
$langPaybox = array(
'fr' => 'FRA',
'en' => 'GBR',
'es' => 'ESP',
'it' => 'ITA',
'de' => 'DEU',
'nl' => 'NLD',
'se' => 'SWE',
'pt' => 'PRT',
);
$lang = JFactory::getLanguage();
$tag = strtolower(substr($lang->get('tag'), 0, 2));
if (array_key_exists($tag, $langPaybox)) {
return $langPaybox[$tag];
} else {
return $langPaybox['en'];
}
}
function getTypePaiement () {
return self::TYPEPAIEMENT_CARTE;
}
function getTypeCarte () {
return self::TYPECARTE_CB;
}
function getTime () {
return date("c");
}
/**
* Returns Paybox available server URLS
* @return string
*/
function getPayboxServerUrl () {
if ($this->_method->shop_mode == 'test') {
$url = 'https://preprod-tpeweb.paybox.com/php/';
} else {
if (isset($this->_method->check_server_available)) {
if ($this->_method->check_server_available) {
$url = 'https://' . $this->getPayboxServerAvailable() . '/php/';
} else {
$url = 'https://tpeweb.paybox.com/php/';
}
} else {
$url = 'https://' . $this->getPayboxServerAvailable() . '/php/';
}
}
return $url;
}
private function getPayboxServerAvailable () {
$servers = array(
'tpeweb.paybox.com', //serveur primaire
'tpeweb1.paybox.com' //serveur secondaire
);
static $c = null;
if(isset($c)) return $c;
foreach ($servers as $server) {
$doc = new DOMDocument();
$doc->loadHTMLFile('https://' . $server . '/load.html');
$server_status = "";
$element = $doc->getElementById('server_status');
if ($element) {
$server_status = $element->textContent;
}
if ($server_status == "OK") {
$c = $server;
return $server;
}
}
$c = FALSE;
$this->plugin->debugLog('getPayboxServerAvailable : no server are available' . var_export($servers, true), 'error');
return FALSE;
}
/**
* @param $paybox_data
* @return mixed
*/
function getOrderNumber ($order_number) {
return $order_number;
}
/**
* @return array
*/
function getExtraPluginNameInfo () {
return false;
}
/**
* @param $cart
* @param $method
* @param $cart_prices
* @return bool
*/
function checkConditions ($cart, $method, $cart_prices) {
if (!$this->getPayboxServerUrl()) {
$this->plugin->debugLog('getPayboxServerUrl FALSE', 'checkConditions', 'debug');
$this->pbxError('No Pbx server available');
return false;
}
if (!$this->getPayboxReturnUrls()) {
$this->plugin->debugLog('getPayboxReturnUrls FALSE', 'checkConditions', 'debug');
return false;
}
$this->convert_condition_amount($method);
$address = $cart->getST();
$amount = $cart_prices['salesPrice'];
$amount_cond = ($amount >= $method->min_amount AND $amount <= $method->max_amount
OR
($method->min_amount <= $amount AND ($method->max_amount == 0)));
if ( !$amount_cond) {
$this->plugin->debugLog('min_amount FALSE' . $amount . ' ' . $method->min_amount, 'checkConditions', 'debug');
return false;
}
$countries = array();
if (!empty($method->countries)) {
if (!is_array($method->countries)) {
$countries[0] = $method->countries;
} else {
$countries = $method->countries;
}
}
// probably did not gave his BT:ST address
if (!is_array($address)) {
$address = array();
$address['virtuemart_country_id'] = 0;
}
if (!isset($address['virtuemart_country_id'])) {
$address['virtuemart_country_id'] = 0;
}
if (in_array($address['virtuemart_country_id'], $countries) || count($countries) == 0) {
if ($amount_cond) {
return TRUE;
}
}
$this->plugin->debugLog(' FALSE', 'checkConditions', 'debug');
return FALSE;
}
/**
* Converts amounts to accept different decimal format (, and .)
* @param $method
*/
function convert_condition_amount (&$method) {
//$method->recurring_min_amount = (float)str_replace(',', '.', $method->recurring_min_amount);
$method->min_amount_3dsecure = (float)str_replace(',', '.', $method->min_amount_3dsecure);
}
/**
* @param $paybox_data
* @param $order
* @return mixed
*/
function getOrderHistory ($paybox_data, $order, $payments) {
$amountInCurrency = vmPSPlugin::getAmountInCurrency($paybox_data['M'] * 0.01, $order['details']['BT']->order_currency);
$order_history['comments'] = vmText::sprintf('VMPAYMENT_' . $this->plugin_name . '_PAYMENT_STATUS_CONFIRMED', $amountInCurrency['display'], $order['details']['BT']->order_number);
$order_history['comments'] .= "<br />" . vmText::_('VMPAYMENT_' . $this->plugin_name . '_RESPONSE_S') . ' ' . $paybox_data['S'];
$order_history['customer_notified'] = true;
$status_success = 'status_success_' . $this->_method->debit_type;
$order_history['order_status'] = $this->_method->$status_success;
return $order_history;
}
/**
* @param $keyfile
* @param bool $pub
* @param string $pass
* @return bool|resource
*/
private function loadKey ($keyfile, $public_key = TRUE, $pass = '') {
$fp = $filedata = $key = FALSE; // initialisation variables
$fsize = filesize($keyfile); // taille du fichier
if (!$fsize) {
$this->pbxError('loadKey :' . 'Key File:' . $keyfile . ' not found');
$this->plugin->debugLog('loadKey :' . 'Key File:' . $keyfile . ' not found', 'error');
return FALSE;
}
$fp = fopen($keyfile, 'r'); // ouverture fichier
if (!$fp) {
$this->pbxError('Cannot open Key File' . $keyfile);
$this->plugin->debugLog('loadKey :' . 'Cannot open Key File' . $keyfile, 'error');
return FALSE;
}
$filedata = fread($fp, $fsize);
fclose($fp);
if (!$filedata) {
$this->pbxError('Empty Key File' . $keyfile);
$this->plugin->debugLog('loadKey :' . 'Empty Key File' . $keyfile, 'error');
return FALSE;
}
if ($public_key) {
$key = openssl_pkey_get_public($filedata);
} // recuperation de la cle publique
else // ou recuperation de la cle privee
{
$key = openssl_pkey_get_private(array($filedata, $pass));
}
return $key; // renvoi cle ( ou erreur )
}
/**
* @param $keyfile
* @param $queryString
* @return bool
*/
public function pbxIsValidSignature ($keyfile, $queryString) {
//return true;
$key = $this->loadKey($keyfile);
if (!$key) {
return false;
}
$sig = '';
$queryStringNoSig = "";
$this->GetSignedData($queryString, $queryStringNoSig, $sig);
$sigURLDecoded = $this->getSignatureDecoded($sig, true);
$sigURLNotDecoded = $this->getSignatureDecoded($sig, false);
$verifySigURLDecoded = openssl_verify($queryStringNoSig, $sigURLDecoded, $key);
$verifySigURLNotDecoded = openssl_verify($queryStringNoSig, $sigURLNotDecoded, $key);
openssl_free_key($key);
// openssl_verify: verification : 1 si valide, 0 si invalide, -1 si erreur
if ($verifySigURLDecoded or $verifySigURLNotDecoded) {
$msg = 'PbxVerSign :' . 'openssl_verify return value DECODED: ' . $verifySigURLDecoded . '<br />';
$msg .= 'PbxVerSign :' . 'openssl_verify return value NOT DECODED: ' . $verifySigURLNotDecoded . '<br />';
$this->plugin->debugLog($msg, 'pbxIsValidSignature', 'debug');
return true;
}
$msg = 'PbxVerSign :' . 'openssl_verify return value DECODED: ' . $verifySigURLDecoded . '<br />';
$msg .= 'PbxVerSign :' . 'openssl_verify return value NOT DECODED: ' . $verifySigURLNotDecoded . '<br />';
$msg .= ' ' . 'query sign ' . $queryString . '<br />';
$msg .= ' ' . 'data ' . $queryStringNoSig . '<br />';
//$msg .= ' ' . 'sig ' . $sig . '<br />';
// we cannot send an error at this stage because may be the signature is not valid from the
$this->plugin->debugLog($msg, 'pbxIsValidSignature', 'debug');
return false;
}
/**
* @param $message
*/
function pbxError ($message) {
$public = "";
if ($this->_method->debug) {
$public = $message;
}
vmError($message, $public);
}
/**
* renvoi les donnes signees et la signature
* @param $qrystr
* @param $data
* @param $sig
*/
public function GetSignedData ($qrystr, &$data, &$sig) {
$pos = strrpos($qrystr, '&');
$data = substr($qrystr, 0, $pos);
$pos = strpos($qrystr, '=', $pos) + 1;
$sig = substr($qrystr, $pos);
}
/**
* @param $sig
* @param $doDecode
* @return string
*/
function getSignatureDecoded ($sig, $doDecode) {
if ($doDecode) {
$this->plugin->debugLog('URL DO DECODE', 'debug');
$sig = urldecode($sig);
} else {
$this->plugin->debugLog('URL NOT DECODE', 'debug');
}
$sig = base64_decode($sig); //decodage Base 64
return $sig;
}
}