verify($params) === false) { return json_encode($this->errbody("签名不成功",$params),JSON_UNESCAPED_UNICODE); } $action = $params['action']; $chargeType = intval($params['chargeType']); if ($action != 'CZ') { return json_encode($this->errbody("不支持该业务",$params),JSON_UNESCAPED_UNICODE); } //业务类型 //0:话费 1:Q币 2:QQ会员 3:游戏 //4:水电气 5:流量 6:票务 7:固话 8:宽带 9:油卡 if ($chargeType !== 0 && $chargeType !== 9) { return json_encode($this->errbody("不支持该类型业务",$params),JSON_UNESCAPED_UNICODE); } $mchid = config::MCHID; Model('merchant_query')->add_info(config::MCHID, $params['chargeId'], json_encode($params)); $mchinfo = Model('merchant')->getMerchantInfo(['mchid' => $mchid]); $userid = intval($mchinfo['admin_id']); $input = [ 'mchid' => $mchid, 'buyer_id' => $userid, 'amount' => $params['chargeCash'], 'card_no' => $params['chargeAcct'], 'mch_order' => $params['chargeId'], 'notify_url' => config::MCH_NOTIFY_URL]; $code = refill\util::push_add($input); if($code) { $ret = $this->retbody($code, '提交成功', $params); refill\util::push_queue_order($mchid,$params['chargeId'],ORDER_STATE_QUEUE); } else { $ret = $this->retbody($code, '提交失败', $params); } return json_encode($ret,JSON_UNESCAPED_UNICODE); } private function errbody($msg,$params) { //交易结果 0:未处理 1:充值成功 2:充值结果不确定 3:充值失败 $retCode = 3; $retDetail = $msg; $result = [ 'action' => 'CZ', 'chargeId' => $params['chargeId'], 'retCode' => $retCode, 'retDetail' => $retDetail, 'retRsn' => $params['retRsn']]; $body = "{$params['chargeId']}{$retCode}{$params['retRsn']}" . config::BridgeKey; $sign = md5($body); $result['sign'] = $sign; return $result; } private function retbody($code, $msg, $params) { //交易结果 0:未处理 1:充值成功 2:充值结果不确定 3:充值失败 if ($code === true) { $retCode = 0; $retDetail = '定单已接收'; } else { $retCode = 3; $retDetail = $msg; } $result = [ 'action' => 'CZ', 'chargeId' => $params['chargeId'], 'retCode' => $retCode, 'retDetail' => $retDetail, 'retRsn' => $params['retRsn']]; $body = "{$params['chargeId']}{$retCode}{$params['retRsn']}" . config::BridgeKey; $sign = md5($body); $result['sign'] = $sign; return $result; } public function notify($params) { $proxy = new refill_proxy(config::MCH_KEY); [$verify, $data] = $proxy->notify($params); $mchid = config::MCHID; if ($verify) { $body = $this->notify_body($data); if ($body === false) { Log::record("body error",Log::DEBUG); return true; } $body = json_encode($body,JSON_UNESCAPED_UNICODE); Log::record("notify body = {$body}",Log::DEBUG); $body = mb_convert_encoding($body,'GBK','UTF-8'); $resp = $this->send($body); if ($resp === false) { return false; } else { return true; } } else { Log::record("内部回调签名错误 mchid = {$mchid}", Log::ERR); return false; } } private function send($body) { try { $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]); if (socket_connect($sock, config::BridgeIP, config::BridgePort)) { socket_write($sock, $body); $resp = socket_read($sock, 1024); socket_close($sock); $resp = strtolower(trim($resp)); return $resp == "ok"; } } catch (Exception $ex) { Log::record(__FUNCTION__ . " what:" . $ex->getMessage(),Log::ERR); } return false; } private function notify_body($params) { $mch_ordersn = $params['order_sn']; $query_info = Model('merchant_query')->query_info(config::MCHID, $mch_ordersn); if (empty($query_info)) { $mchid = config::MCHID; Log::record("查不到mchid={$mchid},mch_order:{$mch_ordersn}的原始订单信息", Log::ERR); return false; } else { $query_info = json_decode($query_info['request'], true); } $success = $params['state'] == 'SUCCESS'; $retCode = $success ? 1 : 3; $body = [ "action" => "CZ", "chargeId" => $query_info['chargeId'], "retCode" => $retCode, "retDetail" => $retCode == 1 ? "充值成功" : "充值失败", "retRsn" => $query_info['retRsn'], "userContent" => "", "retCost" => number_format($this->getCost(config::MCHID, $mch_ordersn), 3,'.',''), "retBalance" => number_format($this->getBalance(config::MCHID), 3,'.',''), "retCash" => number_format($query_info['chargeCash'], 3,'.','') ]; $sign = md5("{$body['chargeId']}{$body['retCode']}{$body['retRsn']}" . config::BridgeKey); $body['sign'] = $sign; return $body; } private function getBalance($mchid) { try { $mchinfo = Model('merchant')->getMerchantInfo(['mchid' => $mchid]); $userid = intval($mchinfo['admin_id']); $info = new member_info($userid); return round($info->available_predeposit(), 3); } catch (Exception $ex) { Log::record("Bridge getBalance mchid={$mchid} what : {$ex->getMessage()}", Log::ERR); return 0.000; } } private function getCost($mchid, $mch_ordersn) { $refill_order = Model('refill_order'); $items = $refill_order->getOrderInfo(['mchid' => $mchid, 'mch_order' => $mch_ordersn, 'inner_status' => 0]); if (!empty($items)) { $order = $items[0]; return $order['mch_amount']; } else { return 0; } } private function verify($params) { $params['chargeCash'] = number_format($params['chargeCash'],3,'.',''); //md5(chargeId + chargeAcct + var1 + var2 + var3 + var4 + chargeCash + md5key) $keys = ['chargeId', 'chargeAcct', 'var1', 'var2', 'var3', 'var4', 'chargeCash']; $body = ""; foreach ($keys as $key) { $body .= $params[$key] ?? ""; } $body .= config::BridgeKey; $sign = md5($body); Log::record("body={$body} sign={$sign} , orgsign={$params['sign']}",Log::DEBUG); return $params['sign'] == $sign; } }