123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525 |
- <?php
- /*
- * Фронтенд для получения уведомлений о платежах от Приватбанка
- * Протокол: https://docs.google.com/document/d/1JrH84x2p4FOjm89q3xArvnEfsFXRnbIoa6qJFNq2VYw/edit#
- *
- * Возможно получение запросов как в виде отдельной POST переменной, так и в виде HTTP_RAW_POST_DATA
- * Идентификация абонента по лицевому счету в виде paymentID материализующемуся из вьюшки вида:
- * CREATE VIEW op_customers (realid,virtualid) AS SELECT users.login, CRC32(users.login) FROM `users`;
- */
- $agentData = parse_ini_file('agentdata.ini', true);
- /////////// Секция настроек
- // Имя POST переменной в которой должны приходить запросы, либо raw в случае получения
- // запросов в виде HTTP_RAW_POST_DATA.
- define('PBX_REQUEST_MODE', 'raw');
- //Режим отладки - заставляет данные подгружаться из файла debug.xml
- //(Да-да, ложите туда запрос и смотрите в браузере как на него отвечает фронтенд)
- define('PBX_DEBUG_MODE', 0);
- //Текст уведомлений и екзепшнов
- define('USER_BALANCE_DECIMALS', -1); // Сколько знаков после запятой возвращать в балансе абонента 0 - возвращать только целую часть
- //Исключения
- define('PBX_EX_NOT_FOUND', 'Абонент не найден');
- define('PBX_EX_DUPLICATE', 'Дублирование платежа');
- define('PBX_AGENT_NOT_FOUND', 'Критическая ошибка. Не найден агент, которому пренадлежит абонент');
- // подключаем API OpenPayz
- include ("../../libs/api.openpayz.php");
- error_reporting(E_ALL);
- // Send main headers
- header('Last-Modified: ' . gmdate('r'));
- header('Content-Type: text/html; charset=utf-8');
- header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
- header("Pragma: no-cache");
- /**
- * Gets user associated agent data by ID
- *
- * @param string $userlogin
- *
- * @return string
- */
- function getAgentDataByID($customer_id) {
- global $agentData;
- $result = 'DEFAULT';
- $avaibleTags = array_keys($agentData);
- if (!empty($avaibleTags)) {
- $where = '';
- foreach ($avaibleTags as $tag) {
- if($tag != end($avaibleTags)) {
- $where.= "`tagid` = '" . trim($tag) . "' OR ";
- } else {
- $where.= "`tagid` = '" . trim($tag) . "'";
- }
- }
- $customer_id_m = mysql_real_escape_string($customer_id);
- $query = "SELECT `tagid` FROM `tags` INNER JOIN `op_customers` ON (`tags`.`login`= `op_customers`.`realid`) WHERE `op_customers`.`virtualid` = '" . $customer_id_m . "' AND (" . $where . ")";
- $data = simple_query($query);
- if (!empty($data)) {
- $result = $data['tagid'];
- }
- }
- return ($result);
- }
- /**
- * Check for POST have needed variables
- *
- * @param $params array of POST variables to check
- * @return bool
- *
- */
- function pbx_CheckPost($params) {
- $result = true;
- if (!empty($params)) {
- foreach ($params as $eachparam) {
- if (isset($_POST[$eachparam])) {
- if (empty($_POST[$eachparam])) {
- $result = false;
- }
- } else {
- $result = false;
- }
- }
- }
- return ($result);
- }
- /**
- * Returns request data
- *
- * @return string
- */
- function pbx_RequestGet() {
- $result = '';
- if (PBX_REQUEST_MODE != 'raw') {
- if (pbx_CheckPost(array(PBX_REQUEST_MODE))) {
- $result = $_POST[PBX_REQUEST_MODE];
- }
- } else {
- //$result = $HTTP_RAW_POST_DATA;
- $result = file_get_contents('php://input');
- }
- return ($result);
- }
- /**
- * Returns all user RealNames
- *
- * @return array
- */
- function pbx_UserGetAllRealnames() {
- $query = "SELECT * from `realname`";
- $all = simple_queryall($query);
- $result = array();
- if (!empty($all)) {
- foreach ($all as $io => $each) {
- $result[$each['login']] = $each['realname'];
- }
- }
- return($result);
- }
- /**
- * Returns user stargazer data by login
- *
- * @param string $login existing stargazer login
- *
- * @return array
- */
- function pbx_UserGetStargazerData($login) {
- $login = mysql_real_escape_string($login);
- $query = "SELECT * from `users` WHERE `login`='" . $login . "';";
- $result = simple_query($query);
- return ($result);
- }
- /**
- * Returns all user mobile phones
- *
- * @return array
- */
- function pbx_UserGetAllMobiles() {
- $query = "SELECT * from `phones`";
- $all = simple_queryall($query);
- $result = array();
- if (!empty($all)) {
- foreach ($all as $io => $each) {
- $result[$each['login']] = $each['mobile'];
- }
- }
- return($result);
- }
- /**
- * Returns random numeric string, which will be used as unique transaction hash
- *
- * @param int $size
- * @return int
- */
- function pbx_GenerateHash($size = 12) {
- $characters = '0123456789';
- $string = "";
- for ($p = 0; $p < $size; $p++) {
- $string.= $characters[mt_rand(0, (strlen($characters) - 1))];
- }
- return ($string);
- }
- /**
- * Returns array of availble user address as login=>address
- *
- * @return array
- */
- function pbx_AddressGetFulladdresslist() {
- //наглая заглушка
- $alterconf['ZERO_TOLERANCE'] = 0;
- $alterconf['CITY_DISPLAY'] = 0;
- $result = array();
- $query_full = "
- SELECT `address`.`login`,`city`.`cityname`,`street`.`streetname`,`build`.`buildnum`,`apt`.`apt` FROM `address`
- INNER JOIN `apt` ON `address`.`aptid`= `apt`.`id`
- INNER JOIN `build` ON `apt`.`buildid`=`build`.`id`
- INNER JOIN `street` ON `build`.`streetid`=`street`.`id`
- INNER JOIN `city` ON `street`.`cityid`=`city`.`id`";
- $full_adress = simple_queryall($query_full);
- if (!empty($full_adress)) {
- foreach ($full_adress as $ArrayData) {
- // zero apt handle
- if ($alterconf['ZERO_TOLERANCE']) {
- $apartment_filtered = ($ArrayData['apt'] == 0) ? '' : '/' . $ArrayData['apt'];
- } else {
- $apartment_filtered = '/' . $ArrayData['apt'];
- }
- if ($alterconf['CITY_DISPLAY']) {
- $result[$ArrayData['login']] = $ArrayData['cityname'] . ' ' . $ArrayData['streetname'] . ' ' . $ArrayData['buildnum'] . $apartment_filtered;
- } else {
- $result[$ArrayData['login']] = $ArrayData['streetname'] . ' ' . $ArrayData['buildnum'] . $apartment_filtered;
- }
- }
- }
- return($result);
- }
- /**
- * Returns presearch reply
- *
- * @return string
- */
- function pbx_ReplyPresearch($customerid) {
- $allcustomers = op_CustomersGetAll();
- if (isset($allcustomers[$customerid])) {
- $customerLogin = $allcustomers[$customerid];
- $allrealnames = pbx_UserGetAllRealnames();
- //normal search reply
- $templateOk = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Presearch">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="PayersTable">
- <Headers>
- <Header name="fio"/>
- <Header name="ls"/>
- </Headers>
- <Columns>
- <Column>
- <Element>' . @$allrealnames[$customerLogin] . '</Element>
- </Column>
- <Column>
- <Element>' . $customerid . '</Element>
- </Column>
- </Columns>
- </Data>
- </Transfer>';
- $result = $templateOk;
- } else {
- //search fail reply template
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Presearch">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="99">
- <Message>' . PBX_EX_NOT_FOUND . '</Message>
- </Data>
- </Transfer>';
- $result = $templateFail;
- }
- $result = trim($result);
- return ($result);
- }
- /**
- * Returns search reply
- *
- * @return string
- */
- function pbx_ReplySearch($customerid, $UsrBalanceDecimals = -1) {
- global $agentData;
- $allcustomers = op_CustomersGetAll();
- if (isset($allcustomers[$customerid])) {
- $customerLogin = $allcustomers[$customerid];
- $allrealnames = pbx_UserGetAllRealnames();
- $alladdress = pbx_AddressGetFulladdresslist();
- $allmobiles = pbx_UserGetAllMobiles();
- $userdata = pbx_UserGetStargazerData($customerLogin);
- if (!empty($agentData) and isset($agentData['DEFAULT'])) {
- $agentId = getAgentDataByID($customerLogin);
- $ispServiceCode = $agentData[$agentId]['serviceCode'];
- $ispServiceName = $agentData[$agentId]['serviceName'];
- $companyData = '
- <CompanyInfo mfo="' . $agentData[$agentId]['bankcode'] . '" okpo="' . $agentData[$agentId]['edrpo'] . '" account="' . $agentData[$agentId]['bankacc'] . '" >
- <CompanyCode>' . $agentData[$agentId]['kodificator'] . '</CompanyCode>
- <CompanyName>' . $agentData[$agentId]['contrname'] . '</CompanyName>
- </CompanyInfo>
- ';
- $userBalance = ($UsrBalanceDecimals < 0) ? $userdata['Cash'] : (($UsrBalanceDecimals == 0) ? intval($userdata['Cash'], 10) : round($userdata['Cash'], $UsrBalanceDecimals, PHP_ROUND_HALF_EVEN));
- //normal reply
- $templateOk = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Search">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="DebtPack" billPeriod="' . date("Ym") . '">
- <PayerInfo billIdentifier="' . $customerid . '">
- <Fio>' . @$allrealnames[$customerLogin] . '</Fio>
- <Phone>' . @$allmobiles[$customerLogin] . '</Phone>
- <Address>' . @$alladdress[$customerLogin] . '</Address>
- </PayerInfo>
- <ServiceGroup>
- <DebtService serviceCode="' . $ispServiceCode . '" >
- ' . $companyData . '
- <DebtInfo>
- <Balance>' . $userBalance . '</Balance>
- </DebtInfo>
- <ServiceName>' . $ispServiceName . '</ServiceName>
- <PayerInfo billIdentifier="' . $customerid . '" ls="' . $customerid . '">
- <Fio>' . @$allrealnames[$customerLogin] . '</Fio>
- <Phone>' . @$allmobiles[$customerLogin] . '</Phone>
- <Address>' . @$alladdress[$customerLogin] . '</Address>
- </PayerInfo>
- </DebtService>
- </ServiceGroup>
- </Data>
- </Transfer>
- ';
- $result = $templateOk;
- } else {
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Pay">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="8">
- <Message>' . PBX_AGENT_NOT_FOUND . '</Message>
- </Data>
- </Transfer>';
- $result = $templateFail;
- }
- } else {
- //reply fail
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Search">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="2">
- <Message>' . PBX_EX_NOT_FOUND . '</Message>
- </Data>
- </Transfer>';
- $result = $templateFail;
- }
- $result = trim($result);
- return ($result);
- }
- /**
- * Function that gets last id from table
- *
- * @param string $tablename
- * @return int
- */
- function pbx_simple_get_lastid($tablename) {
- $tablename = mysql_real_escape_string($tablename);
- $query = "SELECT `id` from `" . $tablename . "` ORDER BY `id` DESC LIMIT 1";
- $result = simple_query($query);
- return ($result['id']);
- }
- /**
- * Returns payment possibility reply
- *
- * @return string
- */
- function pbx_ReplyCheck($customerid) {
- $allcustomers = op_CustomersGetAll();
- if (isset($allcustomers[$customerid])) {
- $customerLogin = $allcustomers[$customerid];
- $reference = pbx_GenerateHash();
- // following method may cause reference ID collisions
- // $reference = pbx_simple_get_lastid('op_transactions') + 1;
- $templateOk = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Check">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Gateway" reference="' . $reference . '" />
- </Transfer>
- ';
- $result = $templateOk;
- } else {
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Check">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="2">
- <Message>' . PBX_EX_NOT_FOUND . '</Message>
- </Data>
- </Transfer>
- ';
- $result = $templateFail;
- }
- $result = trim($result);
- return ($result);
- }
- /**
- * Checks is reference unique?
- *
- * @param int $rawhash reference number to check
- *
- * @return bool
- */
- function pbx_CheckHash($rawhash) {
- $rawhash = mysql_real_escape_string($rawhash);
- $hash = 'PBX_' . $rawhash;
- $query = "SELECT * from `op_transactions` WHERE `hash`='" . $hash . "';";
- $data = simple_query($query);
- if (empty($data)) {
- return (true);
- } else {
- return (false);
- }
- }
- /**
- * Returns payment processing reply
- *
- * @return string
- */
- function pbx_ReplyPayment($customerid, $summ, $rawhash) {
- global $agentData;
- $allcustomers = op_CustomersGetAll();
- if (isset($allcustomers[$customerid])) {
- if (pbx_CheckHash($rawhash)) {
- if (!empty($agentData) and isset($agentData['DEFAULT'])) {
- // Check tags id by agent
- $agentId = getAgentDataByID($customerid);
- $ispServiceCode = $agentData[$agentId]['serviceCode'];
- //do the payment
- $hash = 'PBX_' . $rawhash;
- $paysys = 'PBANKX' . $ispServiceCode;
- $note = 'inputreference: ' . $rawhash;
- op_TransactionAdd($hash, $summ, $customerid, $paysys, $note);
- op_ProcessHandlers();
- $templateOk = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Pay">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Gateway" reference="' . $rawhash . '">
- </Data>
- </Transfer>';
- $result = $templateOk;
- } else {
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Pay">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="8">
- <Message>' . PBX_AGENT_NOT_FOUND . '</Message>
- </Data>
- </Transfer>';
- $result = $templateFail;
- }
- } else {
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Pay">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="7">
- <Message>' . PBX_EX_DUPLICATE . '</Message>
- </Data>
- </Transfer>';
- $result = $templateFail;
- }
- } else {
- $templateFail = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <Transfer xmlns="http://debt.privatbank.ua/Transfer" interface="Debt" action="Pay">
- <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ErrorInfo" code="2">
- <Message>' . PBX_EX_NOT_FOUND . '</Message>
- </Data>
- </Transfer>';
- $result = $templateFail;
- }
- $result = trim($result);
- return ($result);
- }
- /*
- * Controller part
- */
- if (!PBX_DEBUG_MODE) {
- $xmlRequest = pbx_RequestGet();
- } else {
- if (file_exists('debug.xml')) {
- $xmlRequest = file_get_contents('debug.xml');
- } else {
- die('PBX_DEBUG_MODE requires existing debug.xml file');
- }
- }
- //raw xml data received
- if (!empty($xmlRequest)) {
- $xmlParse = xml2array($xmlRequest);
- if (!empty($xmlParse)) {
- // Presearch action handling (deprecated?)
- if (isset($xmlParse['Transfer']['Data']['Unit_attr']['name'])) {
- if ($xmlParse['Transfer']['Data']['Unit_attr']['name'] == 'ls') {
- if (isset($xmlParse['Transfer']['Data']['Unit_attr']['value'])) {
- $customerid = vf($xmlParse['Transfer']['Data']['Unit_attr']['value'], 3);
- die(pbx_ReplyPresearch($customerid));
- }
- }
- }
- // Main search
- if (isset($xmlParse['Transfer']['Data']['Unit_attr']['name'])) {
- if ($xmlParse['Transfer']['Data']['Unit_attr']['name'] == 'bill_identifier') {
- if (isset($xmlParse['Transfer']['Data']['Unit_attr']['value'])) {
- if ($xmlParse['Transfer_attr']['action'] == 'Search') {
- $customerid = vf($xmlParse['Transfer']['Data']['Unit_attr']['value'], 3);
- die(pbx_ReplySearch($customerid, USER_BALANCE_DECIMALS));
- }
- }
- }
- }
- // Check payment possibility
- if (isset($xmlParse['Transfer_attr']['action'])) {
- if ($xmlParse['Transfer_attr']['action'] == 'Check') {
- if (isset($xmlParse['Transfer']['Data']['PayerInfo_attr']['billIdentifier'])) {
- $customerid = vf($xmlParse['Transfer']['Data']['PayerInfo_attr']['billIdentifier'], 3);
- die(pbx_ReplyCheck($customerid));
- }
- }
- }
- // Pay transaction handling
- if (isset($xmlParse['Transfer_attr']['action'])) {
- if ($xmlParse['Transfer_attr']['action'] == 'Pay') {
- if (isset($xmlParse['Transfer']['Data']['PayerInfo_attr']['billIdentifier'])) {
- $customerid = vf($xmlParse['Transfer']['Data']['PayerInfo_attr']['billIdentifier'], 3);
- $summ = $xmlParse['Transfer']['Data']['TotalSum'];
- $summ = str_replace(',', '.', $summ);
- $rawhash = $xmlParse['Transfer']['Data']['CompanyInfo']['CheckReference'];
- die(pbx_ReplyPayment($customerid, $summ, $rawhash));
- }
- }
- }
- } else {
- die('XML_PARSER_FAIL');
- }
- }
- ?>
|