forked from verdnatura/hedera-web
273 lines
6.1 KiB
PHP
Executable File
273 lines
6.1 KiB
PHP
Executable File
<?php
|
|
|
|
namespace Vn;
|
|
|
|
require_once ('vn/hedera/init.php');
|
|
require_once ('vn/db/db.php');
|
|
require_once ('vn/tpv/soap-method.php');
|
|
|
|
use Vn\Lib\Log;
|
|
|
|
class Tpv
|
|
{
|
|
static $conn;
|
|
|
|
/**
|
|
* Initializes the class.
|
|
**/
|
|
static function init ()
|
|
{
|
|
global $conf;
|
|
|
|
$conf = require (Hedera\_CONFIG_DIR .'/config.my.php');
|
|
|
|
openlog ('hedera-web', LOG_ODELAY, LOG_LOCAL0);
|
|
|
|
self::$conn = new Db\Conn ();
|
|
self::$conn->open (
|
|
$conf['db']['host']
|
|
,$conf['db']['user']
|
|
,base64_decode ($conf['db']['pass'])
|
|
,$conf['db']['schema']
|
|
,$conf['db']['port']
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Deinitializes the class.
|
|
**/
|
|
static function deinit ()
|
|
{
|
|
self::$conn->close ();
|
|
closelog ();
|
|
}
|
|
|
|
/**
|
|
* Gets transaction confirmations from the IMAP mailbox.
|
|
**/
|
|
static function getFromMailbox ()
|
|
{
|
|
self::init ();
|
|
|
|
$imap = NULL;
|
|
|
|
if (self::$conn->isOpen ())
|
|
{
|
|
$imapConf = self::$conn->getRow (
|
|
'SELECT host, user, pass, clean_period, success_folder, error_folder '
|
|
.'FROM tpv_imap_config'
|
|
);
|
|
|
|
if ($imapConf)
|
|
{
|
|
$mailbox = sprintf ('{%s/imap/ssl/novalidate-cert}INBOX',
|
|
$imapConf['host']);
|
|
|
|
$imap = imap_open ($mailbox
|
|
,$imapConf['user']
|
|
,base64_decode ($imapConf['pass'])
|
|
);
|
|
}
|
|
}
|
|
|
|
if ($imap)
|
|
{
|
|
// Fetchs and confirms new transaction mails
|
|
|
|
$inbox = imap_search ($imap, 'ALL');
|
|
|
|
if ($inbox)
|
|
foreach ($inbox as $msg)
|
|
{
|
|
// Decodes the mail body
|
|
|
|
$params = [];
|
|
$body = imap_fetchbody ($imap, $msg, '1');
|
|
$strings = explode (';', $body);
|
|
|
|
foreach ($strings as $string)
|
|
{
|
|
$x = explode (':', $string);
|
|
$params[trim ($x[0])] = trim ($x[1]);
|
|
}
|
|
|
|
// Confirms the transaction
|
|
|
|
$success = self::confirm ($params);
|
|
|
|
// Moves the processed mail to another folder
|
|
|
|
if ($success)
|
|
$folder = $imapConf['success_folder'];
|
|
else
|
|
$folder = $imapConf['error_folder'];
|
|
|
|
$folder = sprintf ('INBOX.%s', $folder);
|
|
|
|
if (!imap_mail_move ($imap, $msg, $folder))
|
|
trigger_error (sprintf ('TPV: IMAP: Can\'t move message to %s: %s'
|
|
,$folder
|
|
,imap_last_error ()
|
|
), E_USER_WARNING);
|
|
}
|
|
|
|
if ($inbox && ($count = count ($inbox)) > 0)
|
|
trigger_error (sprintf ('TPV: %d mails processed.', $count));
|
|
|
|
imap_expunge ($imap);
|
|
|
|
// Cleans the old mails
|
|
|
|
if (rand (1, 20) == 1)
|
|
{
|
|
$folders = array (
|
|
$imapConf['success_folder']
|
|
,$imapConf['error_folder']
|
|
);
|
|
|
|
$deleted = 0;
|
|
$date = new \DateTime (NULL);
|
|
$date->sub (new \DateInterval ($imapConf['clean_period']));
|
|
$filter = sprintf ('BEFORE "%s"', $date->format('D, j M Y'));
|
|
|
|
foreach ($folders as $folder)
|
|
if (imap_reopen ($imap, $mailbox.'.'.$folder))
|
|
if ($messages = imap_search ($imap, $filter))
|
|
{
|
|
foreach ($messages as $message)
|
|
imap_delete ($imap, $message);
|
|
|
|
imap_expunge ($imap);
|
|
$deleted += count ($messages);
|
|
}
|
|
|
|
trigger_error (sprintf ('TPV: Cleaner: %d mails deleted.', $deleted));
|
|
}
|
|
|
|
imap_close ($imap);
|
|
}
|
|
else
|
|
trigger_error (sprintf ('TPV: IMAP: %s', imap_last_error ()), E_USER_ERROR);
|
|
|
|
self::deinit ();
|
|
}
|
|
|
|
/**
|
|
* Gets transaction confirmation from HTTP POST.
|
|
**/
|
|
static function getFromPost ()
|
|
{
|
|
self::init ();
|
|
|
|
if (self::$conn->isOpen ())
|
|
self::confirm ($_POST);
|
|
|
|
self::deinit ();
|
|
}
|
|
|
|
/**
|
|
* Gets transaction confirmation from SOAP service.
|
|
**/
|
|
static function getFromSoap ()
|
|
{
|
|
ini_set ('soap.wsdl_cache_enabled', FALSE);
|
|
|
|
$server = new \SoapServer (__DIR__ .'/soap.wsdl');
|
|
$server->addFunction ('procesaNotificacionSIS');
|
|
$server->handle ();
|
|
}
|
|
|
|
/**
|
|
* Tryes to confirm a transaction with the given params.
|
|
**/
|
|
static function confirm ($params)
|
|
{
|
|
if (isset ($params['Ds_Amount'])
|
|
&& isset ($params['Ds_Order'])
|
|
&& isset ($params['Ds_MerchantCode'])
|
|
&& isset ($params['Ds_Currency'])
|
|
&& isset ($params['Ds_Response']))
|
|
{
|
|
if (isset ($params['Ds_ErrorCode']))
|
|
$error = $params['Ds_ErrorCode'];
|
|
else
|
|
$error = NULL;
|
|
|
|
try {
|
|
return self::$conn->query (
|
|
'CALL transaction_confirm (#, #, #, #, #, #)',
|
|
[
|
|
$params['Ds_Amount']
|
|
,$params['Ds_Order']
|
|
,$params['Ds_MerchantCode']
|
|
,$params['Ds_Currency']
|
|
,$params['Ds_Response']
|
|
,$error
|
|
]
|
|
);
|
|
}
|
|
catch (\Exception $e)
|
|
{
|
|
trigger_error (sprintf ("TPV: DB: %s", $e->getMessage ()), E_USER_WARNING);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static function transactionStart ($conn, $amount, $urlOk, $urlKo, $companyId, &$url, &$signature)
|
|
{
|
|
$row = $conn->getRow ('CALL transaction_start_sha256 (#, #)',
|
|
[$amount, $companyId]);
|
|
|
|
if (!isset($row))
|
|
throw new Exception ('Transaction error');
|
|
|
|
$transactionId = str_pad ($row['transaction_id'], 12, '0', STR_PAD_LEFT);
|
|
$urlOk = empty ($urlOk) ? '' : sprintf ($urlOk, $transactionId);
|
|
$urlKo = empty ($urlKo) ? '' : sprintf ($urlKo, $transactionId);
|
|
$merchantUrl = $row['merchant_url'] ? $row['merchant_url'] : '';
|
|
|
|
$params = [
|
|
'Ds_Merchant_Amount' => $amount
|
|
,'Ds_Merchant_Order' => $transactionId
|
|
,'Ds_Merchant_MerchantCode' => $row['merchant']
|
|
,'Ds_Merchant_Currency' => $row['currency']
|
|
,'Ds_Merchant_TransactionType' => $row['transaction_type']
|
|
,'Ds_Merchant_Terminal' => $row['terminal']
|
|
,'Ds_Merchant_MerchantURL' => $merchantUrl
|
|
,'Ds_Merchant_UrlOK' => $urlOk
|
|
,'Ds_Merchant_UrlKO' => $urlKo
|
|
];
|
|
|
|
$encodedParams = base64_encode (json_encode ($params));
|
|
|
|
$key = base64_decode ($row['secret_key']);
|
|
|
|
$bytes = array (0, 0, 0, 0, 0, 0, 0, 0);
|
|
$iv = implode (array_map ("chr", $bytes));
|
|
$key = mcrypt_encrypt (MCRYPT_3DES, $key, $transactionId, MCRYPT_MODE_CBC, $iv);
|
|
|
|
$signature = base64_encode (hash_hmac ('sha256', $encodedParams, $key, TRUE));
|
|
$url = $row['url'];
|
|
|
|
return $encodedParams;
|
|
}
|
|
|
|
/**
|
|
* Tests the confirmation process. The corresponding record
|
|
* must exist in the `tpv_transaction` table.
|
|
**/
|
|
static function test ($order)
|
|
{
|
|
self::init ();
|
|
|
|
if (self::$conn->isOpen () && isset ($order))
|
|
self::$conn->query ('CALL transaction_confirm_by_id (#)', [$order]);
|
|
|
|
self::deinit ();
|
|
}
|
|
}
|
|
|
|
?>
|