Bridge.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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\RefillFactory;
  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. $idcard = '';
  35. $card_name = '';
  36. [$code, $msg] = RefillFactory::instance()->add($mchid, $userid, $params['chargeCash'], $params['chargeAcct'], $params['chargeId'], $idcard, $card_name,config::MCH_NOTIFY_URL);
  37. $ret = $this->retbody($code, $msg, $params);
  38. return json_encode($ret,JSON_UNESCAPED_UNICODE);
  39. }
  40. private function errbody($msg,$params)
  41. {
  42. //交易结果 0:未处理 1:充值成功 2:充值结果不确定 3:充值失败
  43. $retCode = 3;
  44. $retDetail = $msg;
  45. $result = [
  46. 'action' => 'CZ',
  47. 'chargeId' => $params['chargeId'],
  48. 'retCode' => $retCode,
  49. 'retDetail' => $retDetail,
  50. 'retRsn' => $params['retRsn']];
  51. $body = "{$params['chargeId']}{$retCode}{$params['retRsn']}" . config::BridgeKey;
  52. $sign = md5($body);
  53. $result['sign'] = $sign;
  54. return $result;
  55. }
  56. private function retbody($code, $msg, $params)
  57. {
  58. //交易结果 0:未处理 1:充值成功 2:充值结果不确定 3:充值失败
  59. if ($code === true) {
  60. $retCode = 0;
  61. $retDetail = '定单已接收';
  62. } else {
  63. $retCode = 3;
  64. $retDetail = $msg;
  65. }
  66. $result = [
  67. 'action' => 'CZ',
  68. 'chargeId' => $params['chargeId'],
  69. 'retCode' => $retCode,
  70. 'retDetail' => $retDetail,
  71. 'retRsn' => $params['retRsn']];
  72. $body = "{$params['chargeId']}{$retCode}{$params['retRsn']}" . config::BridgeKey;
  73. $sign = md5($body);
  74. $result['sign'] = $sign;
  75. return $result;
  76. }
  77. public function notify($params)
  78. {
  79. $proxy = new refill_proxy(config::MCH_KEY);
  80. [$verify, $data] = $proxy->notify($params);
  81. $mchid = config::MCHID;
  82. if ($verify) {
  83. $body = $this->notify_body($data);
  84. if ($body === false) {
  85. Log::record("body error",Log::DEBUG);
  86. return true;
  87. }
  88. $body = json_encode($body,JSON_UNESCAPED_UNICODE);
  89. Log::record("notify body = {$body}",Log::DEBUG);
  90. $body = mb_convert_encoding($body,'GBK','UTF-8');
  91. $resp = $this->send($body);
  92. if ($resp === false) {
  93. return false;
  94. } else {
  95. return true;
  96. }
  97. }
  98. else {
  99. Log::record("内部回调签名错误 mchid = {$mchid}", Log::ERR);
  100. return false;
  101. }
  102. }
  103. private function send($body)
  104. {
  105. try {
  106. $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  107. socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]);
  108. if (socket_connect($sock, config::BridgeIP, config::BridgePort)) {
  109. socket_write($sock, $body);
  110. $resp = socket_read($sock, 1024);
  111. socket_close($sock);
  112. $resp = strtolower(trim($resp));
  113. return $resp == "ok";
  114. }
  115. }
  116. catch (Exception $ex) {
  117. Log::record(__FUNCTION__ . " what:" . $ex->getMessage(),Log::ERR);
  118. }
  119. return false;
  120. }
  121. private function notify_body($params)
  122. {
  123. $mch_ordersn = $params['order_sn'];
  124. $query_info = Model('merchant_query')->query_info(config::MCHID, $mch_ordersn);
  125. if (empty($query_info)) {
  126. $mchid = config::MCHID;
  127. Log::record("查不到mchid={$mchid},mch_order:{$mch_ordersn}的原始订单信息", Log::ERR);
  128. return false;
  129. } else {
  130. $query_info = json_decode($query_info['request'], true);
  131. }
  132. $success = $params['state'] == 'SUCCESS';
  133. $retCode = $success ? 1 : 3;
  134. $body = [
  135. "action" => "CZ",
  136. "chargeId" => $query_info['chargeId'],
  137. "retCode" => $retCode,
  138. "retDetail" => $retCode == 1 ? "充值成功" : "充值失败",
  139. "retRsn" => $query_info['retRsn'],
  140. "userContent" => "",
  141. "retCost" => number_format($this->getCost(config::MCHID, $mch_ordersn), 3,'.',''),
  142. "retBalance" => number_format($this->getBalance(config::MCHID), 3,'.',''),
  143. "retCash" => number_format($query_info['chargeCash'], 3,'.','')
  144. ];
  145. $sign = md5("{$body['chargeId']}{$body['retCode']}{$body['retRsn']}" . config::BridgeKey);
  146. $body['sign'] = $sign;
  147. return $body;
  148. }
  149. private function getBalance($mchid)
  150. {
  151. try {
  152. $mchinfo = Model('merchant')->getMerchantInfo(['mchid' => $mchid]);
  153. $userid = intval($mchinfo['admin_id']);
  154. $info = new member_info($userid);
  155. return round($info->available_predeposit(), 3);
  156. } catch (Exception $ex) {
  157. Log::record("Bridge getBalance mchid={$mchid} what : {$ex->getMessage()}", Log::ERR);
  158. return 0.000;
  159. }
  160. }
  161. private function getCost($mchid, $mch_ordersn)
  162. {
  163. $refill_order = Model('refill_order');
  164. $items = $refill_order->getOrderInfo(['mchid' => $mchid, 'mch_order' => $mch_ordersn, 'inner_status' => 0]);
  165. if (!empty($items)) {
  166. $order = $items[0];
  167. return $order['mch_amount'];
  168. } else {
  169. return 0;
  170. }
  171. }
  172. private function verify($params)
  173. {
  174. $params['chargeCash'] = number_format($params['chargeCash'],3,'.','');
  175. //md5(chargeId + chargeAcct + var1 + var2 + var3 + var4 + chargeCash + md5key)
  176. $keys = ['chargeId', 'chargeAcct', 'var1', 'var2', 'var3', 'var4', 'chargeCash'];
  177. $body = "";
  178. foreach ($keys as $key) {
  179. $body .= $params[$key] ?? "";
  180. }
  181. $body .= config::BridgeKey;
  182. $sign = md5($body);
  183. Log::record("body={$body} sign={$sign} , orgsign={$params['sign']}",Log::DEBUG);
  184. return $params['sign'] == $sign;
  185. }
  186. }