Multi.php 6.6 KB

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