Bridge.php 7.5 KB

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