urls . 'coinBalance/getBalance?'; $api_url .= 'address=' . $address; $api_url .= '&coinType=bsc'; $get_data = $this->curlGetData($api_url); if(empty($get_data)){ return _error('API返回结果为空'); } $get_data = json_decode($get_data, true); //返回数据结构 //{ // "code": 200, // "msg": "操作成功", // "data": 0.166243248 //} if($get_data['code'] == 200){ return _success($get_data['data']); } return _error($get_data['msg']); } /* * 获取代币合约余额,默认为USDT * * $contract 合约地址 * $decimal 合约地址精度 */ public function getTokenBalance(string $address, string $contract = '0x55d398326f99059fF775485246999027B3197955', int $decimal = 18) { $api_url = $this->urls . 'coinBalance/getTokenBalance?'; $api_url .= 'address=' . $address; $api_url .= '&coinType=bsc'; $api_url .= '&contract=' . $contract; $api_url .= '&decimal=' . $decimal; $get_data = $this->curlGetData($api_url); if(empty($get_data)){ return _error('API返回结果为空'); } $get_data = json_decode($get_data, true); //返回数据结构 //{ // "code": 200, // "msg": "操作成功", // "data": 0.166243248 //} if($get_data['code'] == 200){ return _success($get_data['data']); } return _error($get_data['msg']); } public function createWithdraw(string $order_id) { $order_info = (new OfflineWithdrawRecordModel()) ->fetchSql(false) ->field('w.id,u.address,w.status,w.real_amount') ->alias('w') ->join('user u', 'u.id = w.user_id') ->where('w.id', $order_id) ->find(); if(empty($order_info)){ return _error('提现订单不存在'); } if($order_info['status'] != 0){ return _error('该订单当前状态不可提现'); } if(!Cache::has('usdt_balance')){ //手续费 $fee = $this->getBalance(Env::get('rental.out_address')); if ($fee['code'] != 1){ return _error('获取手续费失败'); } $reqFee = $fee['data']; if($reqFee > 0){ $reqFee = round($fee['data'], 6); } if ($reqFee < $this->bnb_fee){ return _error("BNB手续费不足,不能低于:" . $this->bnb_fee); } //Usdt余额 $balan = $this->getTokenBalance((Env::get('rental.out_address'))); if ($balan['code'] != 1){ return _error('获取USDT余额失败:'. $balan['msg']); } $reqBalance = round($balan['data'], 6); Cache::set('usdt_balance', $reqBalance, 1800);//钱包余额 Cache::set('use_amount', 0, 1800);//使用额度 } $usdt_balance = Cache::get('usdt_balance'); $use_amount = Cache::get('use_amount'); $remaining_amount = $usdt_balance - $use_amount; if ($remaining_amount < $order_info['real_amount']){ return _error("USDT余额不足,半小时内可提现额度:" . $usdt_balance . ',剩余额度:' . $remaining_amount); } $this->api_key = Env::get('rental.kang_api_key'); $this->api_pwd = (new ParametersModel())->getValue('kangApiPwd'); $req = $this->withdraw($order_info['address'],$order_info['real_amount'],$order_info['id'],$this->api_key, $this->api_pwd); if($req['code'] == 0){ return _error($req['msg']); } return _success(); } /** * 新增提现 */ protected function withdraw(string $address, float $mum, string $order_sn, string $api_key, string $api_pwd) { $data = [ 'apiKey' => $api_key, 'toAddress' => $address, 'coinName' => 'usdt', 'coinType' => 'bsc', 'mum' => $mum,//提币数量 'companyWithdrawId' => $order_sn//本平台的唯一订单号 ]; $data['sign'] = md5($this->getSignKey($data, $api_pwd)); $api_url = $this->urls . 'coinWithdraw/withdraw'; $get_data = $this->curlPostData($api_url, $data); if(empty($get_data)){ return _error('API返回结果为空'); } $get_data = json_decode($get_data, true); //返回数据结构 //{ // "code": 200, // "msg": "操作成功", // "data": 0.166243248 //} $data['url'] = $api_url; $data['msg'] = $get_data['msg']; paymentLog($data); if($get_data['code'] == 200){ return _success($get_data['data']); } return _error($get_data['msg']); } /** * 提现自动打款回调 * * 接口回调信息格式: * companyWithdrawId=126&sign=8e3c6aee53e3ea4ff974c1d80f4e8beb&status=1&txId=0x39ce05a0698ff2b7459ca707703fd48937dd958422d98ebade6b4f5188b70995 */ public function withdrawCallback() { // $body1 = file_get_contents("php://input"); // Log::write('提现自动打款回调1:' . $body1, 'info'); // // $body = $this->request->post(); $body = file_get_contents("php://input"); //$body = 'companyWithdrawId=126&sign=8e3c6aee53e3ea4ff974c1d80f4e8beb&status=1&txId=0x39ce05a0698ff2b7459ca707703fd48937dd958422d98ebade6b4f5188b70995'; Log::write('提现自动打款回调:' . $body, 'info'); if(empty($body)){ return _error('回调内容为空'); } $parems = explode('&', $body); $req_arr = []; foreach ($parems as $item){ $temp = explode('=', $item); $req_arr[$temp[0]] = $temp[1]; } Log::write('提现自动打款回调参数:','info'); Log::info(json_encode($req_arr)); return _success($req_arr); } /** * 设置回调url * * 设置 api_key对应的回调地址 * * url_type 通知地址类型 1充值 2提现 */ public function configNotice(string $api_key, string $api_pwd, string $url, int $url_type = 1) { $data = [ 'apiKey' => $api_key, 'noticeUrl' => $url, 'urlType' => $url_type, ]; $data['sign'] = md5($this->getSignKey($data, $api_pwd)); $api_url = $this->urls . 'walletCollectTask/configNotice'; dump($data); $get_data = $this->curlPostData($api_url, $data); if(empty($get_data)){ return _error('API返回结果为空'); } $get_data = json_decode($get_data, true); //返回数据结构 //{ // "code": 200, // "msg": "操作成功", // "data": null //} if($get_data['code'] == 200){ return _success($get_data['data']); } return _error($get_data['msg']); } /** * 获取签名-带连接符号 * @return string */ protected function getSignKey(array $arr, string $secretKey)//: string { ksort($arr); $arr['apiSecret'] = $secretKey; $string = ''; foreach ($arr as $key => $value) $string .= '&'.$key .'='.$value; return ltrim($string, '&'); } /* * 封装Get请求 */ private function curlGetData($url){ Log::info('查询余额'); Log::info($url); # 初始化一个curl会话 $ch = curl_init(); # 判断是否是https if (stripos($url, "https://") !== false) { # 禁用后cURL将终止从服务端进行验证 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); # 使用的SSL版本(2 或 3) curl_setopt($ch, CURLOPT_SSLVERSION, 1); } # 设置请求地址 curl_setopt($ch, CURLOPT_URL, $url); # 在启用CURLOPT_RETURNTRANSFER的时候,返回原生的(Raw)输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); # 执行这个请求 $output = curl_exec($ch); # 关闭这个请求 curl_close($ch); return $output; } /* * 封装Post请求 */ private function curlPostData($url , $data=array()) { $headers = array("Content-type:application/x-www-form-urlencoded;charset=UTF-8"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER,$headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // POST数据 curl_setopt($ch, CURLOPT_POST, 1); // 把post的变量加上 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $output = curl_exec($ch); curl_close($ch); return $output; } }