364 lines
13 KiB
PHP
364 lines
13 KiB
PHP
<?php
|
|
/*************************************************************************************/
|
|
/* This file is part of the Thelia package. */
|
|
/* */
|
|
/* Copyright (c) OpenStudio */
|
|
/* email : dev@thelia.net */
|
|
/* web : http://www.thelia.net */
|
|
/* */
|
|
/* For the full copyright and license information, please view the LICENSE.txt */
|
|
/* file that was distributed with this source code. */
|
|
/*************************************************************************************/
|
|
|
|
namespace Atos;
|
|
|
|
use Atos\Model\AtosCurrencyQuery;
|
|
use Propel\Runtime\ActiveQuery\Criteria;
|
|
use Propel\Runtime\Connection\ConnectionInterface;
|
|
use Symfony\Component\Routing\Router;
|
|
use Thelia\Core\HttpFoundation\Response;
|
|
use Thelia\Core\Template\ParserInterface;
|
|
use Thelia\Core\Translation\Translator;
|
|
use Thelia\Install\Database;
|
|
use Thelia\Log\Tlog;
|
|
use Thelia\Model\Config;
|
|
use Thelia\Model\ConfigQuery;
|
|
use Thelia\Model\Message;
|
|
use Thelia\Model\MessageQuery;
|
|
use Thelia\Model\Order;
|
|
use Thelia\Module\AbstractPaymentModule;
|
|
use Thelia\Tools\URL;
|
|
|
|
class Atos extends AbstractPaymentModule
|
|
{
|
|
const MODULE_DOMAIN = 'atos';
|
|
|
|
/**
|
|
* The confirmation message identifier
|
|
*/
|
|
const CONFIRMATION_MESSAGE_NAME = 'atos_payment_confirmation';
|
|
|
|
private $parameters;
|
|
|
|
public function postActivation(ConnectionInterface $con = null)
|
|
{
|
|
// Setup some default values
|
|
if (null === Atos::getConfigValue('atos_merchantId', null)) {
|
|
Atos::setConfigValue('atos_transactionId', 1);
|
|
Atos::setConfigValue('minimum_amount', 0);
|
|
Atos::setConfigValue('maximum_amount', 0);
|
|
Atos::setConfigValue('send_payment_confirmation_message', 1);
|
|
}
|
|
|
|
// Try to chmod binaries if they're not executables
|
|
$binFile = Atos::getBinDirectory() . 'request';
|
|
if (! is_executable($binFile)) {
|
|
@chmod($binFile, 0755);
|
|
}
|
|
|
|
$binFile = Atos::getBinDirectory() . 'response';
|
|
if (! is_executable($binFile)) {
|
|
@chmod($binFile, 0755);
|
|
}
|
|
|
|
$database = new Database($con);
|
|
|
|
$database->insertSql(null, array(
|
|
__DIR__ . DS . 'Config'.DS.'thelia.sql'
|
|
));
|
|
|
|
// Create payment confirmation message from templates, if not already defined
|
|
$email_templates_dir = __DIR__.DS.'I18n'.DS.'email-templates'.DS;
|
|
|
|
if (null === MessageQuery::create()->findOneByName(Atos::CONFIRMATION_MESSAGE_NAME)) {
|
|
$message = new Message();
|
|
|
|
$message
|
|
->setName(Atos::CONFIRMATION_MESSAGE_NAME)
|
|
->setHtmlTemplateFileName('atos-payment-confirmation.html')
|
|
->setTextTemplateFileName('atos-payment-confirmation.txt')
|
|
->setLocale('en_US')
|
|
->setTitle('Atos payment confirmation')
|
|
->setSubject('Payment of order {$order_ref}')
|
|
->setLocale('fr_FR')
|
|
->setTitle('Confirmation de paiement par Atos')
|
|
->setSubject('Confirmation du paiement de votre commande {$order_ref}')
|
|
->save()
|
|
;
|
|
}
|
|
|
|
$this->replacePath();
|
|
}
|
|
|
|
public function update($currentVersion, $newVersion, ConnectionInterface $con = null)
|
|
{
|
|
// Migrate old configuration
|
|
if (null === Atos::getConfigValue('atos_merchantId', null)) {
|
|
if (null !== $atosConfigs = ConfigQuery::create()->filterByName('atos_%', Criteria::LIKE)->find()) {
|
|
/** @var Config $atosConfig */
|
|
foreach ($atosConfigs as $atosConfig) {
|
|
Atos::setConfigValue($atosConfig->getName(), $atosConfig->getValue());
|
|
|
|
$atosConfig->delete($con);
|
|
}
|
|
}
|
|
}
|
|
|
|
parent::update($currentVersion, $newVersion, $con);
|
|
}
|
|
|
|
public function destroy(ConnectionInterface $con = null, $deleteModuleData = false)
|
|
{
|
|
if ($deleteModuleData) {
|
|
$database = new Database($con);
|
|
|
|
$database->execute('drop table `atos_currency`');
|
|
|
|
MessageQuery::create()->findOneByName(Atos::CONFIRMATION_MESSAGE_NAME)->delete();
|
|
}
|
|
}
|
|
|
|
protected function replacePath()
|
|
{
|
|
$pathfile = $this->getPathfilePath();
|
|
|
|
$pathfileContent = @file_get_contents($pathfile . '.dist');
|
|
|
|
if ($pathfileContent) {
|
|
$pathfileContent = str_replace('__PATH__', __DIR__, $pathfileContent);
|
|
|
|
if (! file_put_contents($this->getConfigDirectory() . 'pathfile', $pathfileContent)) {
|
|
throw new \RuntimeException(
|
|
Translator::getInstance()->trans(
|
|
'File %file must be writable, please check Atos/Config directory permissions.',
|
|
[ '%file' => 'pathfile' ],
|
|
Atos::MODULE_DOMAIN
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
throw new \RuntimeException(
|
|
Translator::getInstance()->trans(
|
|
'Failed to read the %file file. Please check file and directory permissions.',
|
|
[ '%file' => $pathfile . '.dist' ],
|
|
Atos::MODULE_DOMAIN
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $key atos key parameter
|
|
* @param string $value parameter value
|
|
* @return $this
|
|
*/
|
|
protected function addParam($key, $value)
|
|
{
|
|
$this->parameters = sprintf("%s %s=%s", $this->parameters, $key, $value);
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function getParameters()
|
|
{
|
|
return trim($this->parameters);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* generate a transaction id for atos solution
|
|
*
|
|
* @return int|mixed
|
|
*/
|
|
private function generateTransactionID()
|
|
{
|
|
$transId = Atos::getConfigValue('atos_transactionId', 1);
|
|
|
|
$transId = 1 + intval($transId);
|
|
|
|
if (strlen($transId) > 6) {
|
|
$transId = 1;
|
|
}
|
|
|
|
Atos::setConfigValue('atos_transactionId', $transId);
|
|
|
|
return sprintf("%06d", $transId);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Method used by payment gateway.
|
|
*
|
|
* If this method return a \Thelia\Core\HttpFoundation\Response instance, this response is send to the
|
|
* browser.
|
|
*
|
|
* In many cases, it's necessary to send a form to the payment gateway.
|
|
* On your response you can return this form already completed, ready to be sent
|
|
*
|
|
* @param \Thelia\Model\Order $order processed order
|
|
* @return null|\Thelia\Core\HttpFoundation\Response
|
|
*/
|
|
public function pay(Order $order)
|
|
{
|
|
$pathBin = Atos::getBinDirectory() .'request';
|
|
|
|
$atosCurrency = AtosCurrencyQuery::create()->findPk(
|
|
$order->getCurrency()->getCode()
|
|
);
|
|
|
|
if (null == $atosCurrency) {
|
|
throw new \InvalidArgumentException(
|
|
sprintf(
|
|
"Atos does not supprot this currency : %s",
|
|
$order->getCurrency()->getCode()
|
|
)
|
|
);
|
|
}
|
|
|
|
$amount = $order->getTotalAmount();
|
|
$amount = number_format($amount, $atosCurrency->getDecimals(), '', '');
|
|
|
|
$transactionId = $this->generateTransactionID();
|
|
|
|
$order->setTransactionRef($transactionId)->save();
|
|
|
|
/** @var Router $router */
|
|
$router = $this->getContainer()->get('router.atos');
|
|
|
|
$this
|
|
->addParam('pathfile', Atos::getPathfilePath())
|
|
->addParam('merchant_id', Atos::getConfigValue('atos_merchantId'))
|
|
->addParam('customer_email', $order->getCustomer()->getEmail())
|
|
->addParam('currency_code', $atosCurrency->getAtosCode())
|
|
->addParam('amount', $amount)
|
|
->addParam('language', $order->getLang()->getCode())
|
|
->addParam('transaction_id', $transactionId)
|
|
->addParam('order_id', $order->getId())
|
|
->addParam('automatic_response_url', URL::getInstance()->absoluteUrl($router->generate('atos.payment.confirmation')))
|
|
->addParam('cancel_return_url', URL::getInstance()->absoluteUrl($router->generate('atos.payment.cancel', [ 'orderId' => $order->getId() ])))
|
|
->addParam('normal_return_url', $this->getPaymentSuccessPageUrl($order->getId()))
|
|
;
|
|
|
|
$encrypt = exec(sprintf("%s %s", $pathBin, $this->getParameters()));
|
|
|
|
if (! empty($encrypt)) {
|
|
$datas = explode('!', $encrypt);
|
|
|
|
if ($datas[1] == '' && $datas[2] == '') {
|
|
throw new \RuntimeException(
|
|
Translator::getInstance()->trans('Request binary not found in "%path"', ['%path' => $pathBin])
|
|
);
|
|
} elseif ($datas[1] != 0) {
|
|
throw new \RuntimeException($datas[2]);
|
|
} else {
|
|
/** @var ParserInterface $parser */
|
|
$parser = $this->getContainer()->get('thelia.parser');
|
|
|
|
$parser->setTemplateDefinition(
|
|
$parser->getTemplateHelper()->getActiveFrontTemplate(),
|
|
true
|
|
);
|
|
|
|
$content = $parser->render('atos/payment.html', [
|
|
'site_name' => self::getConfigValue('store_name'),
|
|
'form' => $datas[3],
|
|
'order_id' => $order->getId()
|
|
]);
|
|
|
|
return Response::create($content);
|
|
}
|
|
} else {
|
|
throw new \RuntimeException(
|
|
Translator::getInstance()->trans(
|
|
'Empty response recevied from Atos binary "%path". Please check path and permissions.',
|
|
['%path' => $pathBin],
|
|
Atos::MODULE_DOMAIN
|
|
)
|
|
);
|
|
// FIXME : show something to the customer
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return boolean true to allow usage of this payment module, false otherwise.
|
|
*/
|
|
public function isValidPayment()
|
|
{
|
|
$valid = false;
|
|
|
|
// Check config files
|
|
$parmcomFile = Atos::getConfigDirectory() . 'parmcom.' . Atos::getConfigValue('atos_merchantId', '0');
|
|
$certifFile = Atos::getConfigDirectory() . 'certif.fr.' . Atos::getConfigValue('atos_merchantId', '0');
|
|
|
|
if (is_readable($parmcomFile) && is_readable($certifFile)) {
|
|
$mode = Atos::getConfigValue('atos_mode', false);
|
|
|
|
// If we're in test mode, do not display Payzen on the front office, except for allowed IP addresses.
|
|
if ('TEST' == $mode) {
|
|
$raw_ips = explode("\n", Atos::getConfigValue('atos_allowed_ip_list', ''));
|
|
|
|
$allowed_client_ips = array();
|
|
|
|
foreach ($raw_ips as $ip) {
|
|
$allowed_client_ips[] = trim($ip);
|
|
}
|
|
|
|
$client_ip = $this->getRequest()->getClientIp();
|
|
|
|
$valid = in_array($client_ip, $allowed_client_ips);
|
|
|
|
} elseif ('PRODUCTION' == $mode) {
|
|
$valid = true;
|
|
}
|
|
|
|
if ($valid) {
|
|
// Check if total order amount is in the module's limits
|
|
$valid = $this->checkMinMaxAmount();
|
|
}
|
|
} else {
|
|
Tlog::getInstance()->addWarning(
|
|
Translator::getInstance()->trans(
|
|
"Atos payment module is nort properly configured. Please check module configuration in your back-office.",
|
|
[],
|
|
Atos::MODULE_DOMAIN
|
|
)
|
|
);
|
|
}
|
|
return $valid;
|
|
}
|
|
|
|
/**
|
|
* Check if total order amount is in the module's limits
|
|
*
|
|
* @return bool true if the current order total is within the min and max limits
|
|
*/
|
|
protected function checkMinMaxAmount()
|
|
{
|
|
// Check if total order amount is in the module's limits
|
|
$order_total = $this->getCurrentOrderTotalAmount();
|
|
|
|
$min_amount = Atos::getConfigValue('atos_minimum_amount', 0);
|
|
$max_amount = Atos::getConfigValue('atos_maximum_amount', 0);
|
|
|
|
return
|
|
$order_total > 0
|
|
&&
|
|
($min_amount <= 0 || $order_total >= $min_amount) && ($max_amount <= 0 || $order_total <= $max_amount);
|
|
}
|
|
|
|
public static function getBinDirectory()
|
|
{
|
|
return __DIR__ . DS . 'bin' . DS;
|
|
}
|
|
|
|
public static function getConfigDirectory()
|
|
{
|
|
return __DIR__ . DS . 'Config' . DS;
|
|
}
|
|
|
|
public static function getPathfilePath()
|
|
{
|
|
return Atos::getConfigDirectory() . 'pathfile';
|
|
}
|
|
}
|