index.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. /*
  3. * Фронтенд платежной системы city24.com.ua за основу взят фронтенд platezhka, проверять можно по адресу http://demo.platezhka.com.ua:8081/
  4. * согласно протокола: http://store.nightfly.biz/st/1430694725/platezhkacomua_interface.rtf
  5. *
  6. * Модуль написаний для логіки модуля "Опір Гусака".
  7. * Вам необхіжно в вашому білінгу прописати в "Додаткова інформації" "Господорюючого суб'єкта" "Ім`я платіжної системи" у вигляді префіксу "CITY24M_".
  8. * для кожного "Господорюючого суб'єкта" "Ім`я платіжної системи" повинно бути унікальним, наприклад: "CITY24M_1" для іншого "Господорюючого суб'єкта" "CITY24M_UBILL" і т.д.
  9. * Також в модулі "Опір Гусака" необхідно прописати користувацький парамертр "serviceDescripton" для кожного агента та в кожній “стратегії”. Цей параметр може повторюватись.
  10. * він на квитанціях та платіжній системі показує, за що ви платите
  11. */
  12. // Configuration section
  13. define('DEBUG_MODE', 0);
  14. //Секция конфигурации
  15. $checkMode = true; // включена ли дополнительная авторизация по логину/паролю?
  16. $checkLogin = 'login'; // собственно логин и пароль для доп. авторизации.
  17. $checkPassword = 'password';
  18. //URL вашего работающего Ubilling
  19. define('API_URL', 'http://127.0.0.1/billing/');
  20. //И его серийный номер
  21. define('API_KEY', 'YOUR_API_UBILLING_KEY');
  22. define('SERVICE_DESCRIPTION', 'необхідно уточнити сервіс');
  23. define('PAYSYS_PREFIX', 'CITY24M' . '_');
  24. error_reporting(E_ALL);
  25. // подключаем API OpenPayz
  26. include ("../../libs/api.openpayz.php");
  27. /**
  28. * Дополнительная авторизация по логину/паролю. Может быть отключена флагом $checkMode
  29. *
  30. * @global boolean $checkMode
  31. * @global string $checkLogin
  32. * @global string $checkPassword
  33. * @param string $login
  34. * @param string $password
  35. * @return bool
  36. */
  37. function pltz_AuthLogin($login, $password) {
  38. global $checkMode, $checkLogin, $checkPassword;
  39. if ($checkMode) {
  40. if (($login == $checkLogin) AND ( $password == $checkPassword)) {
  41. $result = true;
  42. } else {
  43. $result = false;
  44. }
  45. } else {
  46. $result = true;
  47. }
  48. return ($result);
  49. }
  50. /**
  51. * Returns user's assigned agent extended data, if available
  52. *
  53. * @param $gentID
  54. *
  55. * @return array|empty
  56. */
  57. function getGoosData($customerId, $amountRaw = '') {
  58. $baseUrl = API_URL . '?module=remoteapi&key=' . API_KEY . '&action=goose';
  59. $callbackUrl = $baseUrl . '&amount=' . $amountRaw . '&paymentid=' . $customerId;
  60. $gooseResult = @file_get_contents($callbackUrl);
  61. return ($gooseResult);
  62. }
  63. /*
  64. * Returns all tariff prices array
  65. *
  66. * @return array
  67. */
  68. function cpay_TariffGetPricesAll() {
  69. $query = "SELECT `name`,`Fee` from `tariffs`";
  70. $allprices = simple_queryall($query);
  71. $result = array();
  72. if (!empty($allprices)) {
  73. foreach ($allprices as $io => $eachtariff) {
  74. $result[$eachtariff['name']] = $eachtariff['Fee'];
  75. }
  76. }
  77. return ($result);
  78. }
  79. /**
  80. * Checks is reference unique?
  81. *
  82. * @param int $rawhash reference number to check
  83. *
  84. * @return bool
  85. */
  86. function city24_CheckHash($rawhash) {
  87. $rawhash = mysql_real_escape_string($rawhash);
  88. $hash = PAYSYS_PREFIX . $rawhash;
  89. $query = "SELECT * from `op_transactions` WHERE `hash`='" . $hash . "';";
  90. $data = simple_query($query);
  91. if (empty($data)) {
  92. return (true);
  93. } else {
  94. return (false);
  95. }
  96. }
  97. /**
  98. * По идее это обертка для ответов на запросы
  99. *
  100. * @param string $response
  101. *
  102. * @return void
  103. */
  104. function pltz_sendResponse($response) {
  105. print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><commandResponse>$response</commandResponse>");
  106. }
  107. /**
  108. * Эмулируем ихнюю доставалку по тегу, с заточем на нативный парсер.
  109. *
  110. * @param array $array
  111. * @param string $tag
  112. * @return string
  113. */
  114. function pltz_getValueByTag($array, $tag) {
  115. $result = '';
  116. if (isset($array['commandCall'])) {
  117. if (isset($array['commandCall'][$tag])) {
  118. $result = $array['commandCall'][$tag];
  119. }
  120. }
  121. return ($result);
  122. }
  123. /**
  124. * А это, такой типа диспатчер экшонов.
  125. *
  126. * @param string $inXmlset
  127. * @return void
  128. */
  129. function pltz_parseXML($inXmlset) {
  130. $xmlArr = xml2array($inXmlset);
  131. if (!empty($xmlArr)) {
  132. // print_r($xmlArr);
  133. foreach ($xmlArr as $i) {
  134. $command = pltz_getValueByTag($xmlArr, 'command');
  135. switch ($command) {//Разбираем, какая команда поступила.
  136. case 'check' ://Валидация
  137. pltz_Check(pltz_getValueByTag($xmlArr, 'login'),
  138. pltz_getValueByTag($xmlArr, 'password'),
  139. pltz_getValueByTag($xmlArr, 'payElementID'),
  140. pltz_getValueByTag($xmlArr, 'transactionID'),
  141. pltz_getValueByTag($xmlArr, 'account'),
  142. pltz_getValueByTag($xmlArr, 'userEnterAmount')
  143. );
  144. return;
  145. case 'pay'://Оплата
  146. pltz_Payment(pltz_getValueByTag($xmlArr, 'login'),
  147. pltz_getValueByTag($xmlArr, 'password'),
  148. pltz_getValueByTag($xmlArr, 'transactionID'),
  149. pltz_getValueByTag($xmlArr, 'payTimestamp'),
  150. pltz_getValueByTag($xmlArr, 'payID'),
  151. pltz_getValueByTag($xmlArr, 'payElementID'),
  152. pltz_getValueByTag($xmlArr, 'account'),
  153. pltz_getValueByTag($xmlArr, 'amount'),
  154. pltz_getValueByTag($xmlArr, 'terminalId'),
  155. pltz_getValueByTag($xmlArr, 'ProductId')
  156. );
  157. return;
  158. case 'cancel'://Отмена платежа
  159. pltz_Cancel(pltz_getValueByTag($xmlArr, 'login'),
  160. pltz_getValueByTag($xmlArr, 'password'),
  161. pltz_getValueByTag($xmlArr, 'transactionID'),
  162. pltz_getValueByTag($xmlArr, 'cancelPayID'),
  163. pltz_getValueByTag($xmlArr, 'payElementID'),
  164. pltz_getValueByTag($xmlArr, 'account'),
  165. pltz_getValueByTag($xmlArr, 'amount')
  166. );
  167. return;
  168. }
  169. }
  170. }
  171. }
  172. function pltz_Check($login, $password, $payElementID, $transactionID, $account, $userEnterAmount = 0) {
  173. $companyData = '';
  174. $result = 0; //Поле кода завершения (см. Приложение А. Список кодов завершения)
  175. $comment = ''; //Необязательном поле, служебный комментарий.
  176. //Здесь записываем в базу поступивший запрос, для того что бы потом разобраться какие запросы к Вам приходили. Уникальный индификатор запроса - $transactionID
  177. $extTransactionID = PAYSYS_PREFIX . $transactionID; //Записываем сюда номер Вашей транзакции.
  178. if (pltz_AuthLogin($login, $password)) { //Проверяем $login, $password, что бы отсекать чужие запросы
  179. $allcustomers = op_CustomersGetAll();
  180. $tariffPrice = cpay_TariffGetPricesAll();
  181. if (isset($allcustomers[$account])) { //Проверяем в БД абонента (по $account)
  182. //Здесь нужно сохранить платеж в базу, со статусом не оплачен
  183. $comment = 'Очікування платежу'; //Коментарий не обязателен
  184. $userlogin = $allcustomers[$account];
  185. $gooseResult = getGoosData($userlogin, $userEnterAmount);
  186. if (!empty($gooseResult)) {
  187. $gooseResult = json_decode($gooseResult);
  188. $companyData = '
  189. <fields>
  190. <field1 name="FIO">' . $gooseResult->user->realname . '</field1>
  191. <field2 name="Balance">' . round($gooseResult->user->Cash, 2) . '</field2>
  192. </fields>';
  193. if (!empty($gooseResult->agents)) {
  194. $companyData.= '<Products>';
  195. foreach ($gooseResult->agents as $id => $agentOblects) {
  196. // Первіряємо чи увів суму клієнт на термігалі, якщо не ввів то розділяємо платіж відповідно до його тарифу.
  197. if (!empty($gooseResult->payopts->amount)) {
  198. $sum = round($agentOblects->splitamount);
  199. $sumAmountMin = round($sum)-4;
  200. $sumAmountMax = round($sum)+4;
  201. } else {
  202. $sum = $agentOblects->splitvalue * $tariffPrice[$gooseResult->user->Tariff]; // Сума в копійках
  203. $sumAmountMin = round($sum)-4;
  204. $sumAmountMax = round($sum)+4;
  205. }
  206. // Вказуэмо дефолтний Service Descripton
  207. if (!empty($agentOblects->customdata->serviceDescripton)) {
  208. $companyData.= '
  209. <Product>
  210. <ProductId>' . $agentOblects->id . '</ProductId>
  211. <ProductName>' . $agentOblects->customdata->serviceDescripton . '</ProductName>
  212. <Amount>' . $sum . '</Amount>
  213. <AmountMin>' . $sumAmountMin . '</AmountMin>
  214. <AmountMax>' . $sumAmountMax . '</AmountMax>
  215. <SubProviderId>' . $agentOblects->bankacc . '</SubProviderId>
  216. <IsRequired>1</IsRequired>
  217. </Product>
  218. ';
  219. }
  220. }
  221. $companyData.= '</Products>';
  222. } else {
  223. $result = 7; //Прием платежа запрещен провайдером
  224. $comment = 'Не знайдено агентів'; //Коментарий не обязателен
  225. }
  226. } else {
  227. die('ERROR:WRONG_API_CONNECTION');
  228. }
  229. } else {
  230. $result = 5; //Идентификатор абонента не найден (Ошиблись номером). Здесь может быть другая ошибка, например 79 (Счет абонента не активен)
  231. $comment = 'Ідентифікатор абонента не знайдено'; //Коментарий не обязателен
  232. }
  233. } else {
  234. $result = 7; //Прием платежа запрещен провайдером
  235. $comment = 'Невірний логін або пароль'; //Коментарий не обязателен
  236. }
  237. pltz_sendResponse('
  238. <extTransactionID>' . $extTransactionID . '</extTransactionID>
  239. <account>' . $account . '</account>
  240. <result>' . $result . '</result>
  241. ' . $companyData . '
  242. <comment>' . $comment . '</comment>'
  243. );
  244. }
  245. function pltz_Payment($login, $password, $transactionID, $payTimestamp, $payID, $payElementID, $account, $amount, $terminalId, $ProductId = '') {
  246. $extTransactionID = 0; //Платеж в системе Вашей системе
  247. $result = 0; //Поле кода завершения (см. Приложение А. Список кодов завершения)
  248. $comment = ''; //Необязательном поле, служебный комментарий.
  249. //Здесь записываем в базу поступивший запрос, для того что бы потом разобраться какие запросы к Вам приходили. Уникальный индификатор запроса - $transactionID
  250. if (pltz_AuthLogin($login, $password)) {//Проверяем $login, $password, что бы отсекать чужие запросы
  251. if (!empty($ProductId)) {
  252. $extTransactionID = PAYSYS_PREFIX . $transactionID; //Записываем сюда номер Вашей транзакции
  253. if (city24_CheckHash($transactionID)) { //Обязательно нужно проверить(по $transactionID) платеж в Вашей системе, если платеж оплачен - возвращаем result - 0
  254. $hash = $extTransactionID;
  255. $summ = $amount / 100; // кошти в копійках
  256. $customerid = $account;
  257. $gooseResult = getGoosData($customerid);
  258. if (!empty($gooseResult)) {
  259. $gooseResult = json_decode($gooseResult);
  260. if (!empty($gooseResult->agents)) {
  261. if (!empty($gooseResult->agents->{$ProductId}->extinfo)) {
  262. $paysys = preg_grep("/^" . PAYSYS_PREFIX . ".+/", array_column((array)$gooseResult->agents->{$ProductId}->extinfo, 'internal_paysys_name', 'id'));
  263. if (!empty($paysys)) {
  264. $paysys = current($paysys);
  265. $note = 'transactionID:' . $payID . ' terminalId:' . $terminalId;
  266. //регистрируем новую транзакцию
  267. op_TransactionAdd($hash, $summ, $customerid, $paysys, $note);
  268. //вызываем обработчики необработанных транзакций
  269. op_ProcessHandlers();
  270. $result = 0; //ОК
  271. $comment = 'Платіж виконано'; //Коментарий не обязателен
  272. } else {
  273. $result = 8; //ОК
  274. $comment = 'Не знайдено додаткової інформації по префіксу агента: ' . PAYSYS_PREFIX; //Коментарий не обязателен
  275. }
  276. } else {
  277. $result = 8; //ОК
  278. $comment = 'Не знайдено опис агента'; //Коментарий не обязателен
  279. }
  280. } else {
  281. $result = 8; //ОК
  282. $comment = 'Не знайдено агентів'; //Коментарий не обязателен
  283. }
  284. } else {
  285. $result = 8; //ОК
  286. $comment = 'В білінгу не знайдено контрагента'; //Коментарий не обязателен
  287. }
  288. } else {
  289. $result = 8; //ОК
  290. $comment = 'Дублікат платежу'; //Коментарий не обязателен
  291. }
  292. } else {
  293. $result = 8; //ОК
  294. $comment = 'Платіжна система не передала ProductId'; //Коментарий не обязателе
  295. }
  296. } else {
  297. $result = 7; //Прием платежа запрещен провайдером
  298. }
  299. pltz_sendResponse("<extTransactionID>$extTransactionID</extTransactionID>
  300. <account>$account</account>
  301. <result>$result</result>
  302. <comment>$comment</comment>");
  303. }
  304. function pltz_Cancel($login, $password, $transactionID, $cancelPayID, $payElementID, $account, $amount) {
  305. $extTransactionID = 0; //Платеж в системе Вашей системе
  306. $comment = ''; //Необязательном поле, служебный комментарий.
  307. $result = 7; //Проверяем возможность отмены платежа, если нет - отдаем result - 7, дальнейшая реализация не нужна
  308. pltz_sendResponse("<extTransactionID>$extTransactionID</extTransactionID>
  309. <account>$account</account>
  310. <result>$result</result>
  311. <comment>$comment</comment>");
  312. }
  313. $xml = file_get_contents("php://input");
  314. pltz_parseXML($xml);
  315. //debug mode logging
  316. if (DEBUG_MODE) {
  317. //$debugSave = print_r($xml, true);
  318. file_put_contents('debug.log', $xml, FILE_APPEND | LOCK_EX);
  319. }