MyBscApi.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <?php
  2. namespace app\common\logic;
  3. use app\api\controller\Offline as OfflineApi;
  4. use app\common\model\OfflineWithdrawRecordModel;
  5. use app\common\model\ParametersModel;
  6. use think\Cache;
  7. use think\Env;
  8. use think\Log;
  9. /**
  10. * 我的BSC出款钱包API
  11. *
  12. * API文档:http://8.222.240.131:8079/doc.html
  13. */
  14. class MyBscApi
  15. {
  16. protected $urls = 'https://payment.hxiaoju.top/';
  17. protected $api_id = 1004;
  18. protected $api_pwd = 'er`kd34.df';
  19. protected $bnb_fee = 0.005;
  20. public function createWithdraw(string $order_id)
  21. {
  22. $order_info = (new OfflineWithdrawRecordModel())
  23. ->fetchSql(false)
  24. ->field('w.id,u.address,w.status,w.real_amount')
  25. ->alias('w')
  26. ->join('user u', 'u.id = w.user_id')
  27. ->where('w.id', $order_id)
  28. ->find();
  29. if(empty($order_info)){
  30. return _error('提现订单不存在');
  31. }
  32. if($order_info['status'] != 0){
  33. return _error('该订单当前状态不可提现');
  34. }
  35. if(!Cache::has('usdt_balance')){
  36. //手续费
  37. $fee = (new BscApi())->getBnbBalance(Env::get('rental.out_address'));
  38. if ($fee['code'] != 1){
  39. return _error('获取手续费失败');
  40. }
  41. $reqFee = $fee['data'];
  42. if ($reqFee < $this->bnb_fee){
  43. return _error("BNB手续费不足,不能低于:" . $this->bnb_fee);
  44. }
  45. //Usdt余额
  46. $balan = (new BscApi())->getTokenBalance((Env::get('rental.out_address')));
  47. if ($balan['code'] != 1){
  48. return _error('获取USDT余额失败:'. $balan['msg']);
  49. }
  50. $reqBalance = $balan['data'];
  51. Cache::set('usdt_balance', $reqBalance, 1800);//钱包余额
  52. Cache::set('use_amount', 0, 1800);//使用额度
  53. }
  54. $usdt_balance = Cache::get('usdt_balance');
  55. $use_amount = Cache::get('use_amount');
  56. $remaining_amount = $usdt_balance - $use_amount;
  57. if ($remaining_amount < $order_info['real_amount']){
  58. return _error("USDT余额不足,半小时内可提现额度:" . $usdt_balance . ',剩余额度:' . $remaining_amount);
  59. }
  60. $req = $this->withdraw($order_info['address'],$order_info['real_amount'],$order_info['id'],$this->api_id, $this->api_pwd);
  61. if($req['code'] == 0){
  62. return _error($req['msg']);
  63. }
  64. return _success();
  65. }
  66. /**
  67. * 根据哈希查看交易详情
  68. *
  69. * 此接口为抓取币安浏览器页面html代码而来
  70. * 访问地址:https://bscscan.com/tx/0x48351c4c215645f2404741343c9be17b0ce494d70a7dba1bf11d1f5c2311de57
  71. */
  72. public function getInfoByTransactionHash($tx_hash = '0x48351c4c215645f2404741343c9be17b0ce494d70a7dba1bf11d1f5c2311de57')
  73. {
  74. if(empty($tx_hash)){
  75. return _error('hash不能为空');
  76. }
  77. $data = [
  78. 'tx_hash' => $tx_hash,
  79. ];
  80. $api_url = $this->urls . 'api/getTxhashDetail';
  81. $get_data = $this->curlPostData($api_url, $data);
  82. if(empty($get_data)){
  83. return _error('API返回结果为空');
  84. }
  85. dump($get_data);
  86. $get_data = json_decode($get_data, true);
  87. //返回数据结构
  88. //{
  89. // "code": 200,
  90. // "msg": "操作成功",
  91. // "data": null
  92. //}
  93. if($get_data['code'] == 200){
  94. return _success($get_data['data']);
  95. }
  96. return _error($get_data['msg']);
  97. }
  98. /**
  99. * 新增提现
  100. */
  101. protected function withdraw(string $address, float $mum, string $order_sn, string $api_id, string $api_key)
  102. {
  103. $data = [
  104. 'apiId' => $api_id,
  105. 'toAddress' => $address,
  106. 'coinName' => 'usdt',
  107. 'coinType' => 'BEP20',
  108. 'amount' => $mum,//提币数量
  109. 'orderNo' => $order_sn,//本平台的唯一订单号
  110. 'timeStamp' => time(),
  111. ];
  112. $data['sign'] = md5($this->getSignKey($data, $api_key));
  113. $api_url = $this->urls . 'api/withdraw';
  114. Log::info('提现申请');
  115. Log::info($api_url);
  116. Log::info(json_encode($data));
  117. $get_data = $this->curlPostData($api_url, $data);
  118. if(empty($get_data)){
  119. return _error('API返回结果为空');
  120. }
  121. $get_data = json_decode($get_data, true);
  122. //返回数据结构
  123. //{
  124. // "code": 200,
  125. // "msg": "操作成功",
  126. // "data": null
  127. //}
  128. $data['url'] = $api_url;
  129. $data['msg'] = $get_data['msg'];
  130. paymentLog($data);
  131. if($get_data['code'] == 200){
  132. return _success($get_data['data']);
  133. }
  134. return _error($get_data['msg']);
  135. }
  136. /**
  137. * 提现自动打款回调
  138. *
  139. * 接口回调信息格式:
  140. * companyWithdrawId=126&sign=8e3c6aee53e3ea4ff974c1d80f4e8beb&status=1&txId=0x39ce05a0698ff2b7459ca707703fd48937dd958422d98ebade6b4f5188b70995
  141. */
  142. public function withdrawCallback()
  143. {
  144. // $body1 = file_get_contents("php://input");
  145. // Log::write('提现自动打款回调1:' . $body1, 'info');
  146. //
  147. // $body = $this->request->post();
  148. $body = file_get_contents("php://input");
  149. //$body = 'companyWithdrawId=126&sign=8e3c6aee53e3ea4ff974c1d80f4e8beb&status=1&txId=0x39ce05a0698ff2b7459ca707703fd48937dd958422d98ebade6b4f5188b70995';
  150. Log::write('提现自动打款回调:' . $body, 'info');
  151. if(empty($body)){
  152. return _error('回调内容为空');
  153. }
  154. $parems = explode('&', $body);
  155. $req_arr = [];
  156. foreach ($parems as $item){
  157. $temp = explode('=', $item);
  158. $req_arr[$temp[0]] = $temp[1];
  159. }
  160. Log::write('提现自动打款回调参数:','info');
  161. Log::info(json_encode($req_arr));
  162. return _success($req_arr);
  163. }
  164. /**
  165. * 设置回调url
  166. *
  167. * 设置 api_key对应的回调地址
  168. *
  169. * url_type 通知地址类型 1充值 2提现
  170. */
  171. public function configNotice(string $api_key, string $api_pwd, string $url, int $url_type = 1)
  172. {
  173. $data = [
  174. 'apiKey' => $api_key,
  175. 'noticeUrl' => $url,
  176. 'urlType' => $url_type,
  177. ];
  178. $data['sign'] = md5($this->getSignKey($data, $api_pwd));
  179. $api_url = $this->urls . 'walletCollectTask/configNotice';
  180. dump($data);
  181. $get_data = $this->curlPostData($api_url, $data);
  182. if(empty($get_data)){
  183. return _error('API返回结果为空');
  184. }
  185. $get_data = json_decode($get_data, true);
  186. //返回数据结构
  187. //{
  188. // "code": 200,
  189. // "msg": "操作成功",
  190. // "data": null
  191. //}
  192. if($get_data['code'] == 200){
  193. return _success($get_data['data']);
  194. }
  195. return _error($get_data['msg']);
  196. }
  197. /**
  198. * 获取签名-带连接符号
  199. * @return string
  200. */
  201. protected function getSignKey(array $arr, string $secretKey)//: string
  202. {
  203. if(isset($arr['sign'])){
  204. //若数组包含前面,则去掉
  205. unset($arr['sign']);
  206. }
  207. ksort($arr);
  208. $arr['apiKey'] = $secretKey;
  209. $string = '';
  210. foreach ($arr as $key => $value)
  211. $string .= '&'.$key .'='.$value;
  212. return ltrim($string, '&');
  213. }
  214. /*
  215. * 封装Get请求
  216. */
  217. private function curlGetData($url){
  218. Log::info('查询余额');
  219. Log::info($url);
  220. # 初始化一个curl会话
  221. $ch = curl_init();
  222. # 判断是否是https
  223. if (stripos($url, "https://") !== false) {
  224. # 禁用后cURL将终止从服务端进行验证
  225. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  226. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  227. # 使用的SSL版本(2 或 3)
  228. curl_setopt($ch, CURLOPT_SSLVERSION, 1);
  229. }
  230. # 设置请求地址
  231. curl_setopt($ch, CURLOPT_URL, $url);
  232. # 在启用CURLOPT_RETURNTRANSFER的时候,返回原生的(Raw)输出
  233. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  234. # 执行这个请求
  235. $output = curl_exec($ch);
  236. # 关闭这个请求
  237. curl_close($ch);
  238. return $output;
  239. }
  240. /*
  241. * 封装Post请求
  242. */
  243. private function curlPostData($url , $data=array())
  244. {
  245. dump($url);
  246. dump($data);
  247. $headers = array("Content-type:application/x-www-form-urlencoded;charset=UTF-8");
  248. $ch = curl_init();
  249. curl_setopt($ch, CURLOPT_URL, $url);
  250. curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
  251. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  252. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  253. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  254. // POST数据
  255. curl_setopt($ch, CURLOPT_POST, 1);
  256. // 把post的变量加上
  257. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  258. $output = curl_exec($ch);
  259. curl_close($ch);
  260. return $output;
  261. }
  262. }