Bridge.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. namespace rbridge\wsd;
  3. require_once(BASE_HELPER_PATH . '/rbridge/wsd/config.php');
  4. require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
  5. use rbridge\IBridge;
  6. use rbridge\wsd\config;
  7. use refill;
  8. use refill_proxy;
  9. use Log;
  10. use member_info;
  11. use Exception;
  12. class Bridge implements IBridge
  13. {
  14. public function add($params)
  15. {
  16. if ($this->verify($params) === false) {
  17. return json_encode($this->errbody("签名不成功",$params),JSON_UNESCAPED_UNICODE);
  18. }
  19. $action = $params['action'];
  20. $chargeType = intval($params['chargeType']);
  21. if ($action != 'CZ') {
  22. return json_encode($this->errbody("不支持该业务",$params),JSON_UNESCAPED_UNICODE);
  23. }
  24. //业务类型
  25. //0:话费 1:Q币 2:QQ会员 3:游戏
  26. //4:水电气 5:流量 6:票务 7:固话 8:宽带 9:油卡
  27. if ($chargeType !== 0 && $chargeType !== 9) {
  28. return json_encode($this->errbody("不支持该类型业务",$params),JSON_UNESCAPED_UNICODE);
  29. }
  30. $mchid = config::MCHID;
  31. Model('merchant_query')->add_info(config::MCHID, $params['chargeId'], json_encode($params));
  32. $mchinfo = Model('merchant')->getMerchantInfo(['mchid' => $mchid]);
  33. $userid = intval($mchinfo['admin_id']);
  34. $input = [ 'mchid' => $mchid,
  35. 'buyer_id' => $userid,
  36. 'amount' => $params['chargeCash'],
  37. 'card_no' => $params['chargeAcct'],
  38. 'mch_order' => $params['chargeId'],
  39. 'notify_url' => config::MCH_NOTIFY_URL];
  40. $code = refill\util::push_add($input);
  41. if($code) {
  42. $ret = $this->retbody($code, '提交成功', $params);
  43. refill\util::push_queue_order($mchid,$params['chargeId'],ORDER_STATE_QUEUE);
  44. }
  45. else {
  46. $ret = $this->retbody($code, '提交失败', $params);
  47. }
  48. return json_encode($ret,JSON_UNESCAPED_UNICODE);
  49. }
  50. private function errbody($msg,$params)
  51. {
  52. //交易结果 0:未处理 1:充值成功 2:充值结果不确定 3:充值失败
  53. $retCode = 3;
  54. $retDetail = $msg;
  55. $result = [
  56. 'action' => 'CZ',
  57. 'chargeId' => $params['chargeId'],
  58. 'retCode' => $retCode,
  59. 'retDetail' => $retDetail,
  60. 'retRsn' => $params['retRsn']];
  61. $body = "{$params['chargeId']}{$retCode}{$params['retRsn']}" . config::BridgeKey;
  62. $sign = md5($body);
  63. $result['sign'] = $sign;
  64. return $result;
  65. }
  66. private function retbody($code, $msg, $params)
  67. {
  68. //交易结果 0:未处理 1:充值成功 2:充值结果不确定 3:充值失败
  69. if ($code === true) {
  70. $retCode = 0;
  71. $retDetail = '定单已接收';
  72. } else {
  73. $retCode = 3;
  74. $retDetail = $msg;
  75. }
  76. $result = [
  77. 'action' => 'CZ',
  78. 'chargeId' => $params['chargeId'],
  79. 'retCode' => $retCode,
  80. 'retDetail' => $retDetail,
  81. 'retRsn' => $params['retRsn']];
  82. $body = "{$params['chargeId']}{$retCode}{$params['retRsn']}" . config::BridgeKey;
  83. $sign = md5($body);
  84. $result['sign'] = $sign;
  85. return $result;
  86. }
  87. public function notify($params)
  88. {
  89. $proxy = new refill_proxy(config::MCH_KEY);
  90. [$verify, $data] = $proxy->notify($params);
  91. $mchid = config::MCHID;
  92. if ($verify) {
  93. $body = $this->notify_body($data);
  94. if ($body === false) {
  95. Log::record("body error",Log::DEBUG);
  96. return true;
  97. }
  98. $body = json_encode($body,JSON_UNESCAPED_UNICODE);
  99. Log::record("notify body = {$body}",Log::DEBUG);
  100. $body = mb_convert_encoding($body,'GBK','UTF-8');
  101. $resp = $this->send($body);
  102. if ($resp === false) {
  103. return false;
  104. } else {
  105. return true;
  106. }
  107. }
  108. else {
  109. Log::record("内部回调签名错误 mchid = {$mchid}", Log::ERR);
  110. return false;
  111. }
  112. }
  113. private function send($body)
  114. {
  115. try {
  116. $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  117. socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]);
  118. if (socket_connect($sock, config::BridgeIP, config::BridgePort)) {
  119. socket_write($sock, $body);
  120. $resp = socket_read($sock, 1024);
  121. socket_close($sock);
  122. $resp = strtolower(trim($resp));
  123. return $resp == "ok";
  124. }
  125. }
  126. catch (Exception $ex) {
  127. Log::record(__FUNCTION__ . " what:" . $ex->getMessage(),Log::ERR);
  128. }
  129. return false;
  130. }
  131. private function notify_body($params)
  132. {
  133. $mch_ordersn = $params['order_sn'];
  134. $query_info = Model('merchant_query')->query_info(config::MCHID, $mch_ordersn);
  135. if (empty($query_info)) {
  136. $mchid = config::MCHID;
  137. Log::record("查不到mchid={$mchid},mch_order:{$mch_ordersn}的原始订单信息", Log::ERR);
  138. return false;
  139. } else {
  140. $query_info = json_decode($query_info['request'], true);
  141. }
  142. $success = $params['state'] == 'SUCCESS';
  143. $retCode = $success ? 1 : 3;
  144. $body = [
  145. "action" => "CZ",
  146. "chargeId" => $query_info['chargeId'],
  147. "retCode" => $retCode,
  148. "retDetail" => $retCode == 1 ? "充值成功" : "充值失败",
  149. "retRsn" => $query_info['retRsn'],
  150. "userContent" => "",
  151. "retCost" => number_format($this->getCost(config::MCHID, $mch_ordersn), 3,'.',''),
  152. "retBalance" => number_format($this->getBalance(config::MCHID), 3,'.',''),
  153. "retCash" => number_format($query_info['chargeCash'], 3,'.','')
  154. ];
  155. $sign = md5("{$body['chargeId']}{$body['retCode']}{$body['retRsn']}" . config::BridgeKey);
  156. $body['sign'] = $sign;
  157. return $body;
  158. }
  159. private function getBalance($mchid)
  160. {
  161. try {
  162. $mchinfo = Model('merchant')->getMerchantInfo(['mchid' => $mchid]);
  163. $userid = intval($mchinfo['admin_id']);
  164. $info = new member_info($userid);
  165. return round($info->available_predeposit(), 3);
  166. } catch (Exception $ex) {
  167. Log::record("Bridge getBalance mchid={$mchid} what : {$ex->getMessage()}", Log::ERR);
  168. return 0.000;
  169. }
  170. }
  171. private function getCost($mchid, $mch_ordersn)
  172. {
  173. $refill_order = Model('refill_order');
  174. $items = $refill_order->getOrderInfo(['mchid' => $mchid, 'mch_order' => $mch_ordersn, 'inner_status' => 0]);
  175. if (!empty($items)) {
  176. $order = $items[0];
  177. return $order['mch_amount'];
  178. } else {
  179. return 0;
  180. }
  181. }
  182. private function verify($params)
  183. {
  184. $params['chargeCash'] = number_format($params['chargeCash'],3,'.','');
  185. //md5(chargeId + chargeAcct + var1 + var2 + var3 + var4 + chargeCash + md5key)
  186. $keys = ['chargeId', 'chargeAcct', 'var1', 'var2', 'var3', 'var4', 'chargeCash'];
  187. $body = "";
  188. foreach ($keys as $key) {
  189. $body .= $params[$key] ?? "";
  190. }
  191. $body .= config::BridgeKey;
  192. $sign = md5($body);
  193. Log::record("body={$body} sign={$sign} , orgsign={$params['sign']}",Log::DEBUG);
  194. return $params['sign'] == $sign;
  195. }
  196. }