Offline.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use app\common\library\EthSign;
  5. use app\common\library\Token;
  6. use app\common\model\LedgerWalletModel;
  7. use app\common\model\OfflineRechargeRecordModel;
  8. use app\common\model\OfflineWithdrawRecordModel;
  9. use app\common\model\ParametersModel;
  10. use app\common\model\UserModel;
  11. use fast\Action;
  12. use fast\Asset;
  13. use fast\Random;
  14. use think\Config;
  15. use think\Db;
  16. use Exception;
  17. use think\Env;
  18. use think\Hook;
  19. use think\Log;
  20. use think\Model;
  21. use think\Validate;
  22. /**
  23. * 会员接口
  24. */
  25. class Offline extends Api
  26. {
  27. public function withdrawFee()
  28. {
  29. $resp = [
  30. 'usdt' => '0', // 系统余额(U)
  31. 'withdraw_min_amount' => getConfig('withdraw_min_amount'), // 最低提现U数量
  32. 'withdraw_fee_rate' => getConfig('withdrawal_fee') // 手续费比例
  33. ];
  34. $this->success('', $resp);
  35. }
  36. /**
  37. * 提现
  38. * @return void
  39. */
  40. public function withdrawCash()
  41. {
  42. $amount = $this->request->post('amount'); // 金额
  43. $sign = $this->request->post('sign'); // 签名信
  44. $address = $this->request->post('to_address'); // 地址
  45. if(empty($sign) || empty($address)){
  46. $this->error(__('Invalid parameters'));
  47. }
  48. $real = bcdiv($amount, getConfig('convert_rate'), 6); // 折合转换 U = 1
  49. $min = getConfig('withdraw_min_amount');
  50. $rate = getConfig('withdrawal_fee');
  51. if ($amount <= 0) {
  52. $this->error(__('The withdrawal amount must be greater than 0'));
  53. } else if ($amount < $min) {
  54. $this->error(__('The withdrawal amount cannot be less than') . $min);
  55. }
  56. // 扣除手续费后
  57. if ($rate > 0 && $rate < 1) { // 比例范围只在0-1之间
  58. $real = bcmul($real, bcsub(1, $rate, 6), 6);
  59. }
  60. $uid = $this->auth->getTokenUserID();
  61. // 用户信息
  62. $user = (new UserModel())->getById($uid);
  63. if($user['is_withdraw']){
  64. $this->error(__('Withdrawal failed, please contact customer service.'));
  65. }
  66. // 验签
  67. $signMsg = "withdraw"; // 与前端约定的固定值
  68. if (!checkSign($signMsg, $sign, $address)) {
  69. $this->error(__('Signature verification failed'));
  70. }
  71. // 启动事务
  72. Db::startTrans();
  73. try {
  74. // 更新USDT和账变
  75. (new LedgerWalletModel())->changeWalletAccount($uid, Asset::TOKEN, -$amount, LedgerWalletModel::Withdraw);
  76. // 创建提现记录
  77. $txHash = Random::uuid();
  78. (new OfflineWithdrawRecordModel())->createWithdraw($txHash, $uid, $amount, $real, $address, 'usdt');
  79. // 提交事务
  80. Db::commit();
  81. } catch (Exception $e) {
  82. // 回滚事务
  83. Db::rollback();
  84. $this->error( $e->getMessage());
  85. }
  86. $this->success('ok');
  87. }
  88. /**
  89. * 提现地址
  90. * @return void
  91. */
  92. public function withdrawList()
  93. {
  94. $where = ['user_id' => $this->auth->getTokenUserID()];
  95. $paginator = (new OfflineWithdrawRecordModel)->where($where)->order('id DESC')->paginate($this->pageSize);
  96. $this->success('', $this->buildResp($paginator->total(), $paginator->currentPage(), $paginator->items()));
  97. }
  98. /**
  99. * 充值记录
  100. * @return void
  101. */
  102. public function rechargeList()
  103. {
  104. $where = ['user_id' => $this->auth->getTokenUserID()];
  105. $paginator = (new OfflineRechargeRecordModel)->where($where)->order('id DESC')->paginate($this->pageSize);
  106. $this->success('', $this->buildResp($paginator->total(), $paginator->currentPage(), $paginator->items()));
  107. }
  108. /**
  109. * 获取签名-带连接符号
  110. * @return string
  111. */
  112. protected static function getSignKey(array $arr, string $secretKey)//: string
  113. {
  114. ksort($arr);
  115. $arr['apiSecret'] = $secretKey;
  116. $string = '';
  117. foreach ($arr as $key => $value)
  118. $string .= '&'.$key .'='.$value;
  119. return ltrim($string, '&');
  120. }
  121. //post
  122. private static function curlPostData($url , $data=array())
  123. {
  124. $headers = array("Content-type:application/x-www-form-urlencoded;charset=UTF-8");
  125. $ch = curl_init();
  126. curl_setopt($ch, CURLOPT_URL, $url);
  127. curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
  128. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  129. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  130. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  131. // POST数据
  132. curl_setopt($ch, CURLOPT_POST, 1);
  133. // 把post的变量加上
  134. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  135. $output = curl_exec($ch);
  136. curl_close($ch);
  137. return $output;
  138. }
  139. //get
  140. private static function curlGetData($url){
  141. Log::info('查询余额');
  142. Log::info($url);
  143. # 初始化一个curl会话
  144. $ch = curl_init();
  145. # 判断是否是https
  146. if (stripos($url, "https://") !== false) {
  147. # 禁用后cURL将终止从服务端进行验证
  148. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  149. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  150. # 使用的SSL版本(2 或 3)
  151. curl_setopt($ch, CURLOPT_SSLVERSION, 1);
  152. }
  153. # 设置请求地址
  154. curl_setopt($ch, CURLOPT_URL, $url);
  155. # 在启用CURLOPT_RETURNTRANSFER的时候,返回原生的(Raw)输出
  156. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  157. # 执行这个请求
  158. $output = curl_exec($ch);
  159. # 关闭这个请求
  160. curl_close($ch);
  161. return $output;
  162. }
  163. }