api.ipay.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. // API DOC: https://walletmc.ipay.ua/doc.php
  3. // notification API: http://store.nightfly.biz/st/1512477073/ipay_notify.pdf
  4. class IpayMasterPass {
  5. /**
  6. * merchant sign key
  7. *
  8. * @var string
  9. */
  10. protected $sign_key = '';
  11. /**
  12. * Current requests date/time
  13. *
  14. * @var string
  15. */
  16. protected $curtime = '';
  17. /**
  18. * Merchants name
  19. *
  20. * @var string
  21. */
  22. protected $mch_id = '';
  23. /**
  24. * Default dialogs language
  25. *
  26. * @var string
  27. */
  28. protected $lang = 'ru';
  29. /**
  30. * Contains current merchant login
  31. *
  32. * @var string
  33. */
  34. protected $login = '';
  35. /**
  36. * Contains all available user mobile phones
  37. *
  38. * @var array
  39. */
  40. protected $allUserPhones = array();
  41. /**
  42. * Contains all available openpayz customers
  43. *
  44. * @var arrays
  45. */
  46. protected $allCustomers = array();
  47. /**
  48. * Ipay MasterPass API URL
  49. */
  50. const URL_API = 'https://walletmc.ipay.ua/';
  51. /**
  52. * Creates new object instance
  53. *
  54. * @param string $mch_id
  55. * @param string $sign_key
  56. * @param string $lang
  57. * @param string $login
  58. *
  59. * @return void
  60. */
  61. public function __construct($mch_id, $sign_key, $lang = '', $login = '') {
  62. $this->setTime();
  63. $this->setSign($sign_key);
  64. $this->setMchId($mch_id);
  65. $this->setLang($lang);
  66. $this->setLogin($login);
  67. $this->loadCustomers();
  68. $this->loadPhones();
  69. }
  70. /**
  71. * Sets current date/time for further requests
  72. *
  73. * @return void
  74. */
  75. protected function setTime() {
  76. $this->curtime = date("Y-m-d H:i:s");
  77. }
  78. /**
  79. * Sets merchant name
  80. *
  81. * @param string $mch_id
  82. *
  83. * @return void
  84. */
  85. protected function setMchId($mch_id) {
  86. $this->mch_id = $mch_id;
  87. }
  88. /**
  89. * Sets default language
  90. *
  91. * @param string $lang
  92. *
  93. * @return void
  94. */
  95. protected function setLang($lang = '') {
  96. if (!empty($lang)) {
  97. $this->lang = $lang;
  98. }
  99. }
  100. /**
  101. * Sets current merch login
  102. *
  103. * @param string $login
  104. *
  105. * @return void
  106. */
  107. protected function setLogin($login = '') {
  108. if (!empty($login)) {
  109. $this->login = $login;
  110. }
  111. }
  112. /**
  113. * Sets private sing key
  114. *
  115. * @param string $sign_key
  116. *
  117. * @return void
  118. */
  119. protected function setSign($sign_key) {
  120. $this->sign_key = $sign_key;
  121. }
  122. /**
  123. * Loads all users phones from database for further usage
  124. *
  125. * @return void
  126. */
  127. protected function loadPhones() {
  128. $query = "SELECT * from `phones`";
  129. $all = simple_queryall($query);
  130. if (!empty($all)) {
  131. foreach ($all as $io => $each) {
  132. $this->allUserPhones[$each['login']] = $each['mobile'];
  133. }
  134. }
  135. }
  136. /**
  137. * Loads customers array for further usage as vitrualid=>realid
  138. *
  139. * @return void
  140. */
  141. protected function loadCustomers() {
  142. $this->allCustomers = op_CustomersGetAll();
  143. }
  144. /**
  145. * Returns some customers phone
  146. *
  147. * @param string $customer_id
  148. *
  149. * @return string
  150. */
  151. protected function getPhoneByCustomerId($customer_id) {
  152. $result = '';
  153. if (isset($this->allCustomers[$customer_id])) {
  154. $customerLogin = $this->allCustomers[$customer_id];
  155. if (isset($this->allUserPhones[$customerLogin])) {
  156. $result = $this->allUserPhones[$customerLogin];
  157. }
  158. }
  159. return ($result);
  160. }
  161. /**
  162. * Returns encoded auth key
  163. *
  164. * @param string $data
  165. *
  166. * @return string
  167. */
  168. protected function makeSign($data) {
  169. $result = md5($data . $this->sign_key);
  170. return ($result);
  171. }
  172. /**
  173. * Pushes some json POST data to API and returns result
  174. *
  175. * @param string $request
  176. *
  177. * @return array
  178. */
  179. protected function pushJsonRequest($request) {
  180. $curl = curl_init(self::URL_API);
  181. curl_setopt($curl, CURLOPT_HEADER, false);
  182. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  183. curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
  184. curl_setopt($curl, CURLOPT_POST, true);
  185. curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
  186. $json_response = curl_exec($curl);
  187. $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  188. if ($status != 200) {
  189. die('Error: call to URL ' . self::URL_API . ' failed with status ' . $status . ', response ' . $json_response . ', curl_error ' . curl_error($curl) . ', curl_errno ' . curl_errno($curl));
  190. }
  191. curl_close($curl);
  192. $result = json_decode($json_response, true);
  193. return ($result);
  194. }
  195. /**
  196. * Make phone format as 380xxxxxxxxxx
  197. *
  198. * @param string $mobile
  199. *
  200. * @return string
  201. */
  202. protected function normalizePhoneFormat($mobile) {
  203. $mobile = vf($mobile, 3);
  204. $len = strlen($mobile);
  205. //all is ok
  206. if ($len != 12) {
  207. switch ($len) {
  208. case 11:
  209. $mobile = '3' . $mobile;
  210. break;
  211. case 10:
  212. $mobile = '38' . $mobile;
  213. break;
  214. case 9:
  215. $mobile = '380' . $mobile;
  216. break;
  217. }
  218. }
  219. return ($mobile);
  220. }
  221. /**
  222. * Returns widget session for some user and mobile
  223. *
  224. * @param string $user_id
  225. *
  226. * @return array
  227. */
  228. public function InitWidgetSession($user_id) {
  229. $result = '';
  230. $userMobile = $this->getPhoneByCustomerId($user_id);
  231. $userMobile = $this->normalizePhoneFormat($userMobile);
  232. $request = '{
  233. "request": {
  234. "auth": {
  235. "login": "' . $this->login . '",
  236. "time": "' . $this->curtime . '",
  237. "sign": "' . $this->makeSign($this->curtime) . '"
  238. },
  239. "action": "InitWidgetSession",
  240. "body": {
  241. "msisdn": "' . $userMobile . '",
  242. "user_id": "' . $user_id . '",
  243. "pmt_desc": "Internet service for:' . $user_id . '",
  244. "pmt_info": {
  245. "acc": "' . $user_id . '"
  246. }
  247. }
  248. }
  249. }';
  250. if (!empty($userMobile)) {
  251. $result = $this->pushJsonRequest($request);
  252. }
  253. return ($result);
  254. }
  255. /**
  256. * Returns widget code for some session
  257. *
  258. * @param string $session
  259. *
  260. * @return string
  261. */
  262. public function getWidgetCode($session) {
  263. $result = '
  264. <script type="text/javascript" src="https://widgetmp.ipay.ua/widget.js"></script>
  265. <a href="#" onclick="MasterpassWidget.open(
  266. {
  267. partner: \'' . $this->mch_id . '\',
  268. lang: \'' . $this->lang . '\',
  269. session: \'' . $session . '\'
  270. },
  271. function() {},
  272. function() {},
  273. function() {}
  274. );">
  275. <img src="https://widgetmp.ipay.ua/mp-button.svg">
  276. </a>';
  277. return ($result);
  278. }
  279. }
  280. /**
  281. * IPAY checkout API: https://checkout.ipay.ua/doc
  282. */
  283. class IpayZ {
  284. protected $merchId = '';
  285. protected $signKey = '';
  286. protected $salt = '';
  287. protected $lang = 'ua';
  288. protected $urlSuccess = '';
  289. protected $urlFail = '';
  290. protected $currency = '';
  291. protected $lifeTime = 24;
  292. protected $payDesc = '';
  293. protected $UrlApi = 'https://api.ipay.ua';
  294. protected $api = '';
  295. public function __construct() {
  296. $this->setIOptions();
  297. $this->setSalt();
  298. }
  299. protected function setIOptions() {
  300. $conf = parse_ini_file('config/ipayz.ini');
  301. $this->merchId = $conf['MERCHANT_ID'];
  302. $this->signKey = $conf['SIGN'];
  303. $this->lang = $conf['LANG'];
  304. $this->urlSuccess = $conf['URL_OK'];
  305. $this->urlFail = $conf['URL_FAIL'];
  306. $this->currency = $conf['CURRENCY'];
  307. $this->lifeTime = $conf['TIMEOUT'];
  308. $this->payDesc = $conf['PAYMENT_DESC'];
  309. $this->UrlApi = $conf['API_URL'];
  310. }
  311. protected function setSalt() {
  312. $this->salt = sha1(microtime(true));
  313. }
  314. public function makeSign() {
  315. $result = hash_hmac('sha512', $this->salt, $this->signKey);
  316. return($result);
  317. }
  318. protected function pushRequest($request) {
  319. $curl = curl_init($this->UrlApi);
  320. curl_setopt($curl, CURLOPT_HEADER, false);
  321. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  322. curl_setopt($curl, CURLOPT_POST, true);
  323. curl_setopt($curl, CURLOPT_POSTFIELDS, 'data=' . $request . '&');
  324. $response = curl_exec($curl);
  325. $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  326. if ($status != 200) {
  327. die('Error: call to URL ' . $this->UrlApi . ' failed with status ' . $status . ', response ' . $response . ', curl_error ' . curl_error($curl) . ', curl_errno ' . curl_errno($curl));
  328. }
  329. curl_close($curl);
  330. $result = $response;
  331. return ($result);
  332. }
  333. public function paymentCreate($paymentId = '', $summ = '') {
  334. $result = '';
  335. $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';
  336. $xml = '<payment>
  337. <auth>
  338. <mch_id>' . $this->merchId . '</mch_id>
  339. <salt>' . $this->salt . '</salt>
  340. <sign>' . $this->makeSign() . '</sign>
  341. </auth>
  342. <urls>
  343. <good>' . $this->urlSuccess . '</good>
  344. <bad>' . $this->urlFail . '</bad>
  345. </urls>
  346. <transactions>
  347. <transaction>
  348. <amount>' . $summ . '</amount>
  349. <currency>' . $this->currency . '</currency>
  350. <desc>' . $this->payDesc . '</desc>
  351. <info>{"acc": "' . $paymentId . '"}</info>
  352. </transaction>
  353. </transactions>
  354. <lifetime>' . $this->lifeTime . '</lifetime>
  355. <lang>' . $this->lang . '</lang>
  356. </payment>';
  357. $reply = $this->pushRequest($xml);
  358. if (!empty($reply)) {
  359. $replyArr = xml2array($reply);
  360. if (isset($replyArr['payment'])) {
  361. $result = $replyArr['payment']['url'];
  362. } else {
  363. die('WRONG_REPLY');
  364. }
  365. } else {
  366. die('EMPTY_REPYLY');
  367. }
  368. return($result);
  369. }
  370. }