Multi.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php namespace Pay\Yspay;
  2. use Dever;
  3. use Dever\Http\Curl;
  4. # 银联商务商户资金自主管理系统
  5. class Multi
  6. {
  7. static $host = 'https://im.chinaums.com/channel/Business/UnifyMulti/';
  8. /*
  9. public function act($config, $merchant, $info, $auto = 1)
  10. {
  11. $result = $this->huafu($config, $merchant, $info);
  12. if ($result == 'ok') {
  13. $this->fenzhang($config, $merchant, $info);
  14. }
  15. return $result;
  16. }*/
  17. # 划付
  18. public function huafu($config, $merchant, $info, $auto = 1)
  19. {
  20. $this->config = $config;
  21. $mid = $merchant['mid'];
  22. $cash = $info['hf_cash'];
  23. $order_num = $this->getOrderNum($info['order_num']);
  24. //整理内容信息
  25. $content = [
  26. 'merNo' => $merchant['merno'],
  27. //'merOrderNo' => $order_num,
  28. 'payAmt' => $cash,
  29. 'ps' => $merchant['name'] . '划付',
  30. ];
  31. Dever::log($content, 'yspay_huafu');
  32. $result = $this->curl('202002', $content);
  33. if ($result == 'ok') {
  34. $data['status'] = 1;
  35. } else {
  36. $data['status'] = 3;
  37. $data['error'] = $result;
  38. }
  39. $data['merchant_id'] = $merchant['id'];
  40. $data['mid'] = $mid;
  41. $data['order_num'] = $order_num;
  42. $data['type'] = 1;
  43. $data['cash'] = $cash;
  44. $data['tdate'] = time();
  45. $data['desc'] = $content['ps'];
  46. $data['auto'] = $auto;
  47. Dever::db('pay/yspay_cash_log')->insert($data);
  48. return 'ok';
  49. }
  50. # 分账
  51. public function fenzhang($config, $merchant, $info, $auto = 1)
  52. {
  53. $this->config = $config;
  54. $mid = $this->config['cash_mid'];
  55. $cash = $info['fz_cash'] + $info['pt_cash'];
  56. if (!$cash || $cash <= 0) {
  57. return false;
  58. }
  59. $order_num = $this->getOrderNum($info['order_num']);
  60. //整理内容信息
  61. $content = [
  62. 'merNo' => $this->config['cash_merno'],
  63. //'merOrderNo' => $order_num,
  64. 'payAmt' => $cash,
  65. 'cardNo' => hash("sha256", $this->config['cash_card']),
  66. 'ps' => $merchant['name'] . '分账',
  67. ];
  68. Dever::log($content, 'yspay_fenzhang');
  69. $result = $this->curl('202004', $content);
  70. if ($result == 'ok') {
  71. $data['status'] = 1;
  72. } else {
  73. $data['status'] = 3;
  74. $data['error'] = $result;
  75. }
  76. $data['merchant_id'] = $merchant['id'];
  77. $data['mid'] = $mid;
  78. $data['order_num'] = $order_num;
  79. $data['type'] = 2;
  80. $data['cash'] = $cash;
  81. $data['tdate'] = time();
  82. $data['desc'] = $content['ps'];
  83. $data['auto'] = $auto;
  84. Dever::db('pay/yspay_cash_log')->insert($data);
  85. return $data['status'];
  86. }
  87. # 查询余额
  88. public function yue($config, $merchant)
  89. {
  90. $this->config = $config;
  91. //整理内容信息
  92. $content = [
  93. 'merNo' => $merchant['merno'],
  94. ];
  95. Dever::log($content, 'yspay_yue');
  96. $result = $this->curl('202006', $content, false);
  97. if (isset($result['canPayAmt'])) {
  98. return $result['canPayAmt'];
  99. }
  100. return 0;
  101. }
  102. # 提现
  103. public function tixian($config, $merchant, $cash)
  104. {
  105. $this->config = $config;
  106. $mid = $merchant['mid'];
  107. //整理内容信息
  108. $content = [
  109. 'merNo' => $merchant['merno'],
  110. 'payAmt' => $cash,
  111. 'ps' => $merchant['name'] . '划付',
  112. ];
  113. Dever::log($content, 'yspay_huafu_tixian');
  114. $result = $this->curl('202002', $content);
  115. return 'ok';
  116. }
  117. protected function getOrderNum($order_num)
  118. {
  119. $where['order_num'] = $order_num . '_' . Dever::rand(8, 0);
  120. $state = Dever::db('pay/yspay_cash_log')->one($where);
  121. if (!$state) {
  122. return $where['order_num'];
  123. } else {
  124. return $this->getOrderNum($order_num);
  125. }
  126. }
  127. protected function common($param, $code)
  128. {
  129. $param += array(
  130. 'transCode' => $code,
  131. 'verNo' => '100',
  132. 'srcReqDate' => date("Ymd"),
  133. 'srcReqTime' => date("His"),
  134. 'srcReqId' => Dever::uuid(),
  135. 'channelId' => '043',
  136. 'groupId' => $this->config['cash_groupid'],
  137. );
  138. return $param;
  139. }
  140. protected function curl($code, $param, $state = true)
  141. {
  142. $url = self::$host;
  143. $url .= $code;
  144. $param = $this->common($param, $code);
  145. $param['signature'] = $this->sign($param);
  146. $curl = Curl::getInstance($url, $param, 'post', true);
  147. $body = $curl->result();
  148. if (strstr($body, '<html><head>')) {
  149. return 'error';
  150. }
  151. $body = Dever::json_decode($body);
  152. if (isset($body['respCode'])) {
  153. if ($body['respCode'] == '99999999') {
  154. return $state ? 'ok' : $body;
  155. } elseif ($body['respCode'] == 'FAN00012') {
  156. return $this->curl($code, $param, $state);
  157. } else {
  158. return $body['respMsg'];
  159. }
  160. } else {
  161. return 'error';
  162. }
  163. }
  164. protected function sign($data)
  165. {
  166. $data = $this->getParams($data);
  167. $file = $this->config['cash_private_file'];
  168. if (!strstr($file, 'http')) {
  169. $file = Dever::local($file);
  170. }
  171. $pkcs12 = file_get_contents($file);
  172. openssl_pkcs12_read($pkcs12, $certs, $this->config['cash_private_file_password']);
  173. if (!$certs) {
  174. Dever::alert('private_key error');
  175. }
  176. $privateKey = $certs['pkey'];
  177. if (openssl_sign(utf8_encode($data), $binarySignature, $privateKey, OPENSSL_ALGO_SHA256)) {
  178. return bin2hex($binarySignature);
  179. } else {
  180. return '';
  181. }
  182. }
  183. protected function checkSign($data, $signature)
  184. {
  185. $file = $this->config['cash_public_file'];
  186. if (!strstr($file, 'http')) {
  187. $file = Dever::local($file);
  188. }
  189. $cert = file_get_contents($file);
  190. $cert = '-----BEGIN CERTIFICATE-----' . PHP_EOL
  191. . chunk_split(base64_encode($cert), 64, PHP_EOL)
  192. . '-----END CERTIFICATE-----' . PHP_EOL;
  193. $pubKeyId = openssl_get_publickey($cert);
  194. $signature = hex2bin($signature);
  195. $ok = openssl_verify($data, $signature, $pubKeyId, OPENSSL_ALGO_SHA256);
  196. if ($ok == 1) {
  197. openssl_free_key($pubKeyId);
  198. return true;
  199. }
  200. return false;
  201. }
  202. protected function getParams($param)
  203. {
  204. ksort($param);
  205. $result = array();
  206. foreach ($param as $k => $v) {
  207. if (is_array($v)) {
  208. $v = json_encode($v, JSON_UNESCAPED_UNICODE);
  209. } elseif(trim($v) == ""){
  210. continue;
  211. }
  212. if (is_bool($v)) {
  213. $result[] = $v ? "$k=true" : "$k=false";
  214. } else {
  215. $result[] = $k . '=' . $v;
  216. }
  217. }
  218. $result = implode('&', $result);
  219. return $result;
  220. }
  221. }