// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AcceptorModel; use App\Models\AccountLogModel; use App\Models\BalanceLogModel; use App\Models\MemberBankModel; use App\Models\MemberModel; use App\Models\TradeModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use App\Services\WalletService; use Illuminate\Support\Facades\DB; /** * 承兑商服务管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Api */ class AcceptorService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * MerchantService constructor. */ public function __construct() { $this->model = new AcceptorModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * 获取缓存列表 * @param $position * @param int $num * @return array|mixed */ public function getDataList($params, $pageSize = 15, $refresh = false, $field = '') { $page = request()->post('page', 1); $cacheKey = "caches:acceptor:page_{$page}_" . md5(json_encode($params) . $pageSize); $datas = RedisService::get($cacheKey); $data = isset($datas['data']) ? $datas['data'] : []; if ($datas && $data && !$refresh) { return [ 'list' => $data, 'total' => isset($datas['total']) ? $datas['total'] : 0, 'pageSize' => $pageSize ]; } $field = $field ? $field : 'lev_a.*,lev_b.nickname,lev_b.username,lev_b.avatar'; $order = 'lev_a.id desc'; $datas = $this->model->from('acceptor as a') ->leftJoin('member as b', 'b.id', '=', 'a.user_id') ->where(['a.mark' => 1, 'b.mark' => 1]) ->where('a.quota','>',0) ->whereIn('a.trade_status', [1, 2]) ->where(function ($query) use ($params) { $kw = isset($params['kw']) ? trim($params['kw']) : ''; if ($kw) { $query->where('a.name', 'like', "%{$kw}%"); } }) ->where(function ($query) use ($params) { // 状态 $status = isset($params['status']) && $params['status'] >= 0 ? intval($params['status']) : 2; if ($status > 0) { $query->where('a.status', $status); } $payType = isset($params['pay_type']) && $params['pay_type'] >0 ? intval($params['pay_type']) : 0; if($payType){ $query->where('a.pay_type', $payType); } }) ->selectRaw($field) ->orderByRaw($order) ->paginate($pageSize > 0 ? $pageSize : 9999999); $datas = $datas ? $datas->toArray() : []; if ($datas) { $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $currency = isset($params['currency']) && $params['currency']? strtoupper($params['currency']) : 'CNY'; $tradeType = isset($params['trade_type']) && $params['trade_type']? intval($params['trade_type']) : 1; $cnyPrice = $this->getRealPrice(1,$currency, $tradeType); foreach ($datas['data'] as &$item) { $item['avatar'] = $item['avatar'] ? get_image_url($item['avatar']) : ''; $item['currency_price'] = $this->getRealPrice(1, $currency,0); $item['currency_quota'] = $this->getRealPrice(floatval($item['quota']), $currency, 3); $item['currency_rate'] = $currency=='CNY'? 1 : WalletService::make()->getRateByCNY($currency); $item['usdt_price'] = moneyFormat(1 / $xdPrice, 2); $item['price'] = $cnyPrice; $item['time'] = $item['time']>60? intval($item['time']/60) : 20; } unset($item); RedisService::set($cacheKey, $datas, rand(3, 5)); } return [ 'list' => isset($datas['data']) ? $datas['data'] : [], 'total' => isset($datas['total']) ? $datas['total'] : 0, 'pageSize' => $pageSize ]; } /** * @param $price * @param $urrency * @param int $tradeType * @return string */ public function getRealPrice($money,$currency='CNY', $tradeType=1) { $usdtPrice = RedisService::get("caches:wallets:usdt_rate"); if($usdtPrice<=0){ $usdtCnyPrice = ConfigService::make()->getConfigByCode('usdt_cny_price', 7.2); $usdtPrice = $usdtCnyPrice>0 && $usdtCnyPrice< 100? $usdtCnyPrice : 0; } // 人民币与其他币的汇率价格 $currencyPrice = $currency=='CNY'? 1 : WalletService::make()->getRateByCNY($currency); // 买价 $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $buyPrice = moneyFormat($money/$xdPrice,4); // 星豆价格 $cnyPrice = moneyFormat($buyPrice * $usdtPrice,4); // 币种价格 if($tradeType == 1){ $xdBuyPriceRate = ConfigService::make()->getConfigByCode('trade_buy_price_rate', 0); $xdBuyPriceRate = $xdBuyPriceRate>0 && $xdBuyPriceRate<100? $xdBuyPriceRate : 0; $cnyBuyPrice = moneyFormat($cnyPrice + ($cnyPrice * $xdBuyPriceRate/100), 4); // 上浮价格 return moneyFormat($cnyBuyPrice * $currencyPrice, 4); // 汇率价格 }else if($tradeType == 2){ $xdSellPriceRate = ConfigService::make()->getConfigByCode('trade_sell_price_rate', 0); $xdSellPriceRate = $xdSellPriceRate>0 && $xdSellPriceRate<100? $xdSellPriceRate : 0; $cnyBuyPrice = moneyFormat($cnyPrice - ($cnyPrice * $xdSellPriceRate/100), 4); // 下浮价格 return moneyFormat($cnyBuyPrice * $currencyPrice, 4); // 汇率价格 } return moneyFormat($cnyPrice * $currencyPrice, 4); // 汇率价格 } /** * 获取信息 * @param $where * @param array $field * @return array|mixed */ public function getInfo($id, $field = [], $userId=0) { if($id){ $where = ['a.id'=> $id,'a.mark'=>1]; }else if($userId){ $where = ['a.user_id'=> $userId,'a.mark'=>1]; }else{ return false; } $defaultField = ['a.id', 'a.user_id', 'a.realname','a.name', 'a.mobile','a.telegram', 'a.quota','a.pay_type', 'a.usdt', 'a.status','b.nickname','b.avatar']; $field = $field ? $field : $defaultField; $info = $this->model->from('acceptor as a') ->leftjoin('member as b','b.id','=','a.user_id') ->where($where) ->select($field) ->first(); $info = $info ? $info->toArray() : []; if ($info) { $currency = request()->post('currency','CNY'); $tradeType = request()->post('trade_type',1); $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $cnyPrice = $this->getRealPrice(1,$currency, $tradeType); $info['currency_price'] = $this->getRealPrice(1, $currency,0); $info['currency_quota'] = $this->getRealPrice(floatval($info['quota']), $currency, 3); $info['currency_rate'] = $currency=='CNY'? 1 : WalletService::make()->getRateByCNY($currency); $info['usdt_price'] = moneyFormat(1 / $xdPrice, 2); $info['price'] = $cnyPrice; $info['avatar'] = get_image_url($info['avatar']); } return $info; } /** * 修改信息 * @param $userId * @param $params * @return array|false|int[] */ public function saveInfo($userId, $params) { // 验证是否入驻过和入驻状态 $info = $this->model->where(['user_id' => $userId])->select('id', 'realname', 'trade_status', 'status', 'mark')->first(); $tradeStatus = isset($info['trade_status']) ? $info['trade_status'] : 0; $mark = isset($info['mark']) ? $info['mark'] : 0; $id = isset($info['id']) ? $info['id'] : 0; if ($userId && empty($info)) { $this->error = 2216; return false; } // 是否被冻结 if ($id && $tradeStatus == 4 && $mark) { $this->error = 2202; return false; } // 验证账户是否正常 $userInfo = MemberService::make()->getCacheInfo(['id' => $userId], ['id', 'status']); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; if (empty($userInfo) || $status != 1) { $this->error = 2017; return false; } // 入驻数据 $data = [ 'realname' => isset($params['realname']) ? $params['realname'] : '', 'user_id' => $userId, 'mobile' => isset($params['mobile']) ? $params['mobile'] : '', 'telegram' => isset($params['telegram']) ? $params['telegram'] : '', 'price_float' => isset($params['price_float']) ? $params['price_float'] : '', 'create_time' => time(), 'update_time' => time(), 'mark' => 1, ]; // 写入数据 if ($id) { if ($this->model->where(['id' => $id])->update($data)) { $this->error = 2228; RedisService::keyDel("caches:acceptor:info:temp_{$userId}*"); return ['id' => $id]; } else { $this->error = 2229; return false; } } else { if ($merchId = $this->model->insertGetId($data)) { $this->error = 2228; RedisService::keyDel("caches:acceptor:info:temp_{$userId}*"); return ['id' => $id]; } else { $this->error = 2229; return false; } } } /** * 申请入驻 * @param $userId * @param $params * @return array|false|int[] */ public function apply($userId, $params) { // 验证是否入驻过和入驻状态 $info = $this->model->where(['user_id' => $userId])->select('id', 'name', 'trade_status', 'status', 'mark')->first(); $status = isset($info['status']) ? $info['status'] : 0; $tradeStatus = isset($info['trade_status']) ? $info['trade_status'] : 0; $mark = isset($info['mark']) ? $info['mark'] : 0; $id = isset($info['id']) ? $info['id'] : 0; if ($id && $status == 2 && $mark) { $this->error = 2201; return false; } // 是否被冻结 if ($id && $tradeStatus == 4 && $mark) { $this->error = 2202; return false; } // 验证账户是否正常 $userInfo = MemberService::make()->getCacheInfo(['id' => $userId], ['id', 'status']); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; if (empty($userInfo) || $status != 1) { $this->error = 2017; return false; } // 支付方式验证 $payType = isset($params['pay_type']) && $params['pay_type']? intval($params['pay_type']) : 1; $payment = MemberBankModel::where(['user_id'=> $userId,'type'=> $payType,'status'=>1,'mark'=>1])->value('id'); if($payment<=0){ $this->error = 3011; return false; } // 入驻数据 $data = [ 'name' => isset($params['name']) ? $params['name'] : '', 'realname' => isset($params['realname']) ? $params['realname'] : '', 'user_id' => $userId, 'mobile' => isset($params['mobile']) ? $params['mobile'] : '', 'telegram' => isset($params['telegram']) ? $params['telegram'] : '', 'pay_type' => $payType, 'price_float' => isset($params['price_float']) ? $params['price_float'] : '', 'create_time' => time(), 'update_time' => time(), 'quota' => 0, 'trade_status' => 1, 'status' => 1, 'mark' => 1, ]; // 写入数据 if ($id) { if ($this->model->where(['id' => $id])->update($data)) { $this->error = 3012; return ['id' => $id]; } else { $this->error = 3013; return false; } } else { if ($id = $this->model->insertGetId($data)) { $this->error = 3014; return ['id' => $id]; } else { $this->error = 3013; return false; } } } /** * 获取入驻信息 * @param $userId * @return mixed */ public function getApplyInfo($userId) { $info = $this->model->where(['user_id' => $userId, 'mark' => 1]) ->orderBy('id', 'desc') ->first(); $info = $info ? $info->setHidden(['quota', 'update_time', 'mark'])->toArray() : []; if($info){ $payments = [1=>'微信支付',2=>'支付宝支付',3=>'银行卡支付']; $info['pay_name'] = isset($payments[$info['pay_type']])? $payments[$info['pay_type']] : ''; } return $info; } /** * 充值交易额度 * @param $userId 用户ID * @param $params * @return array|false */ public function rechargeQuota($userId, $params) { // $acceptId = isset($params['id'])? $params['id'] : 0; $usdt = isset($params['usdt']) ? floatval($params['usdt']) : 0; if ($usdt <= 0) { $this->error = 2031; return false; } $info = $this->model->with(['member'])->where(['user_id' => $userId, 'mark' => 1]) ->select(['id', 'realname', 'mobile', 'usdt', 'quota', 'trade_status', 'status']) ->first(); $quota = isset($info['quota']) ? $info['quota'] : 0; $status = isset($info['status']) ? $info['status'] : 0; $acceptId = isset($info['id']) ? $info['id'] : 0; $userInfo = isset($info['member']) ? $info['member'] : []; if ($userId <= 0 || empty($info) || $status != 2) { $this->error = 2015; return false; } // 充值订单 DB::beginTransaction(); $orderNo = get_order_num('DP'); $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $xdPrice = $xdPrice > 0 && $xdPrice <= 10000 ? $xdPrice : 100; $money = round($xdPrice * $usdt, 2); $data = [ 'order_no' => $orderNo, 'user_id' => $acceptId, 'type' => 1, 'user_type' => 3, 'coin_type' => 6, 'money' => $usdt, 'actual_money' => $money, 'pay_type' => 10, 'pay_status' => 20, 'trc_url' => isset($userInfo['trc_url']) ? $userInfo['trc_url'] : '', 'pay_at' => date('Y-m-d H:i:s'), 'date' => date('Y-m-d'), 'create_time' => time(), 'update_time' => time(), 'status' => 2, 'mark' => 1, ]; if (!$orderId = BalanceLogModel::insertGetId($data)) { $this->error = 2033; DB::rollBack(); return false; } // 扣除usdt余额 $updateData = ['usdt' => DB::raw("usdt - {$usdt}"), 'update_time' => time()]; if (!MemberModel::where(['id' => $userId])->update($updateData)) { $this->error = 2036; DB::rollBack(); return false; } // 用户明细 $userUsdt = isset($userInfo['usdt']) ? $userInfo['usdt'] : 0; $log = [ 'user_id' => $userId, 'source_id' => $acceptId, 'source_order_no' => $data['order_no'], 'user_type' => 1, 'type' => 5, 'coin_type' => 1, 'money' => -$usdt, 'actual_money' => -$usdt, 'balance' => $usdt, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易额度充值扣除', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } // 额度增加 $updateData = ['quota' => DB::raw("quota + {$money}"), 'update_time' => time()]; if (!$this->model->where(['id' => $userId])->update($updateData)) { $this->error = 2036; DB::rollBack(); return false; } // 额度明细 $log = [ 'user_id' => $acceptId, 'source_id' => $userId, 'source_order_no' => $data['order_no'], 'user_type' => 3, 'type' => 5, 'coin_type' => 6, 'money' => $money, 'actual_money' => $money, 'balance' => $quota, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易额度充值', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } // 消息 $dateTime = date('Y-m-d H:i:s'); MessageService::make()->pushMessage($userId, '交易额度充值成功', "您在{$dateTime}(UTC+8)成功支付{$usdt}USDT充值{$money}交易额度", 3); DB::commit(); $this->error = 2037; return ['order_id' => $orderId, 'quota' => moneyFormat($quota + $money, 2), 'usdt' => moneyFormat($userUsdt - $usdt, 2)]; } /** * 交易额度提现处理 * @param $userId 用户 * @param $params * @return bool */ public function withdrawQuota($userId, $params) { $money = isset($params['money']) ? $params['money'] : 0; $coinType = isset($params['coin_type']) ? $params['coin_type'] : 0; if ($money <= 0) { $this->error = 2039; return false; } $info = $this->model->with(['member'])->where(['user_id' => $userId, 'mark' => 1]) ->select(['id', 'user_id', 'realname', 'mobile', 'usdt', 'quota', 'status']) ->first(); $usdt = isset($info['usdt']) ? floatval($info['usdt']) : 0; $quota = isset($info['quota']) ? floatval($info['quota']) : 0; $status = isset($info['status']) ? $info['status'] : 0; $tradeStatus = isset($info['trade_status']) ? $info['trade_status'] : 0; $acceptId = isset($info['accept_id']) ? $info['accept_id'] : 0; $userInfo = isset($info['member']) ? $info['member'] : []; if ($acceptId <= 0 || empty($info) || $status != 2) { $this->error = 2039; return false; } if (in_array($tradeStatus,[2,4])) { $this->error = 2015; return false; } // 提现账户 $trcUrl = isset($userInfo['trc_url']) ? $userInfo['trc_url'] : ''; if (empty($trcUrl)) { $this->error = 2403; return false; } DB::beginTransaction(); // USDT 提现 $payUsdt = 0; $orderNo = get_order_num('DP'); if ($coinType == 1) { $payUsdt = $money; if ($money > $usdt) { $this->error = lang(2040, ['money' => $usdt]); return false; } $updateData = ['usdt' => DB::raw("usdt - {$money}"), 'update_time' => time()]; if (!$this->model->where(['id' => $acceptId])->update($updateData)) { DB::rollBack(); $this->error = 2042; return false; } // 明细 $log = [ 'user_id' => $acceptId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'user_type' => 3, 'type' => 5, 'coin_type' => 1, 'money' => -$usdt, 'actual_money' => -$usdt, 'balance' => $usdt, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易余额提现', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } } // 额度提现 else if ($coinType == 6) { // 时间限制 $limitTime = ConfigService::make()->getConfigByCode('quota_withdraw_time'); $limitTime = $limitTime >= 0 ? $limitTime : 0; $lockQuota = BalanceLogModel::where(['user_id' => $acceptId, 'user_type' => 3, 'coin_type' => 6, 'status' => 1, 'mark' => 1]) ->where('pay_at', '>=', date('Y-m-d H:i:s', time() - $limitTime * 86400)) ->sum('actual_money'); if ($lockQuota > 0 && $money > ($quota - $lockQuota)) { $this->error = lang(2040, ['money' => ($quota - $lockQuota)]); return false; } $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $xdPrice = $xdPrice > 0 && $xdPrice <= 10000 ? $xdPrice : 100; $payUsdt = round($money / $xdPrice, 4); $updateData = ['quota' => DB::raw("quota - {$money}"), 'update_time' => time()]; if (!$this->model->where(['id' => $acceptId])->update($updateData)) { DB::rollBack(); $this->error = 2042; return false; } // 明细 $log = [ 'user_id' => $acceptId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'user_type' => 3, 'type' => 5, 'coin_type' => 6, 'money' => -$money, 'actual_money' => -$money, 'balance' => $quota, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易额度提现', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } } // 提现记录 $data = [ 'order_no' => $orderNo, 'user_id' => $acceptId, 'type' => 2, 'coin_type' => $coinType, 'user_type' => 3, 'money' => $money, 'actual_money' => $payUsdt, 'balance' => $coinType == 1 ? $usdt : $quota, 'date' => date('Y-m-d'), 'trc_url' => $trcUrl, 'create_time' => time(), 'update_time' => time(), 'status' => 1, 'mark' => 1, ]; if (!$id = BalanceLogModel::insertGetId($data)) { DB::rollBack(); $this->error = 2042; return false; } DB::commit(); // 站内消息 $dateTime = date('Y-m-d H:i:s'); $message = $coinType == 1 ? "您在{$dateTime}(UTC+8)申请提现{$money}USDT交易余额成功,请耐心等候审核!!!" : "您在{$dateTime}(UTC+8)申请提现{$money}交易额度成功,请耐心等候审核!!!"; MessageService::make()->pushMessage($userId, $coinType == 1 ? '交易余额提现申请成功' : '交易额度提现申请成功', $message); // 提现自动审核,低于该金额自动审核 $autoCheckUsdt = ConfigService::make()->getConfigByCode('withdraw_auto_money', 300); $autoCheckUsdt = $autoCheckUsdt > 0 ? $autoCheckUsdt : 0; if ($payUsdt <= $autoCheckUsdt) { // 打款处理 $result = WalletService::make()->usdtTrcTransfer($trcUrl, $payUsdt); $txID = isset($result['txId']) ? $result['txId'] : ''; $payAddress = isset($result['address']) ? $result['address'] : ''; if ($txID && $payAddress) { $updateData = ['hash'=> $txID,'wallet_url'=> $payAddress,'audit_remark'=>'自动审核打款','status'=>2,'update_time'=>time()]; if(BalanceLogModel::where(['user_id'=> $acceptId,'order_no'=> $orderNo])->update($updateData)){ $message = $coinType == 1 ? "您在{$dateTime}(UTC+8)申请提现{$money}USDT交易余额审核成功,请耐心等候打款到账!!!" : "您在{$dateTime}(UTC+8)申请提现{$money}交易额度审核成功,请耐心等候打款到账!!!"; MessageService::make()->pushMessage($userId, $coinType == 1 ? '交易余额提现审核成功' : '交易额度提现审核成功', $message); AccountLogModel::where(['source_order_no'=> $orderNo])->update(['hash'=> $txID,'update_time'=>time()]); } } } $this->error = 2043; return true; } /** * 余额提现 * @param $userId * @param $params * @return array|false */ public function withdraw($userId, $params) { $money = isset($params['money'])? floatval($params['money']) : 0; $payPassword = isset($params['pay_password'])? trim($params['pay_password']) : ''; $userType = isset($params['user_type']) && $params['user_type']? intval($params['user_type']) : 1; if($money<=0){ $this->error = 2401; return false; } if(!in_array($userType,[1,2,3])){ $this->error = 2404; return false; } $acceptor = $this->model->with(['member'])->where(['user_id' => $userId, 'mark' => 1]) ->select(['id', 'user_id', 'realname', 'mobile', 'usdt', 'quota', 'status','trade_status']) ->first(); // 获取承兑商信息 $userInfo = isset($acceptor['member']) ? $acceptor['member'] : []; $status = isset($userInfo['status'])? $userInfo['status'] : 0; $userUsdt = isset($userInfo['usdt'])? $userInfo['usdt'] : 0; if(isset($userInfo['pay_password'])){ $userPayPassword = $userInfo['pay_password']; }else{ $userPayPassword = DB::table('member')->where('id',$userId)->value('pay_password'); } $acceptorUsdt = isset($acceptor['usdt'])? $acceptor['usdt'] : 0; $acceptorId = isset($acceptor['id'])? $acceptor['id'] : 0; $acceptorTradeStatus = isset($acceptor['trade_status'])? $acceptor['trade_status'] : 0; if(empty($userInfo) || $status != 1){ $this->error = 2024; return false; } if($userType == 3 && (empty($acceptor) || !in_array($acceptorTradeStatus,[1,2]))){ $this->error = 2024; return false; } // 提现金额验证 $accountUsdt = $userType==1? $userUsdt : $acceptorUsdt; if ($money > $accountUsdt) { $this->error = web_lang(2402, ['money' => $accountUsdt]); return false; } // 提现账户 $trcUrl = isset($userInfo['trc_url']) ? $userInfo['trc_url'] : ''; if (empty($trcUrl)) { $this->error = 2403; return false; } if($userPayPassword != get_password($payPassword)){ $this->error = 2038; return false; } $cacheKey = "caches:member:withdraw:lock_{$userId}"; if(RedisService::get($cacheKey)){ $this->error = 1034; return false; } DB::beginTransaction(); RedisService::set($cacheKey, $userInfo, rand(2,3)); // 提现记录 $orderNo = get_order_num('DW'); $feeRate = ConfigService::make()->getConfigByCode('withdraw_fee_rate',5); $feeRate = $feeRate>0 && $feeRate<100? moneyFormat($feeRate/100,2) : 0; $fee = round($money*$feeRate, 2); $realUsdt = moneyFormat($money - $fee, 2); $data = [ 'order_no'=> $orderNo, 'user_id'=> $userId, 'type'=> 2, 'user_type'=> $userType, 'coin_type'=> 1, 'money'=> $money, 'actual_money'=> $realUsdt, 'fee'=> $fee, 'trc_url'=> $trcUrl, 'pay_type'=> 20, 'date'=> date('Y-m-d'), 'create_time'=> time(), 'update_time'=> time(), 'status'=> 1, 'mark'=> 1, ]; if(!$id = BalanceLogModel::insertGetId($data)){ DB::rollBack(); $this->error = 2405; RedisService::clear($cacheKey); return false; } // 商户扣款 if($userType == 3){ $updateData = [ 'usdt'=>DB::raw("usdt - {$money}"), 'update_time'=> time() ]; if(!AcceptorModel::where(['user_id'=> $userId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2406; RedisService::clear($cacheKey); return false; } // 明细 $log = [ 'user_id' => $acceptorId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 5, 'coin_type' => 1, 'user_type'=> 2, 'money' => -$money, 'actual_money' => -$money, 'balance' => $acceptorUsdt, 'create_time' => time(), 'update_time' => time(), 'remark' => "承兑商账户余额提现", 'status' => 1, 'mark' => 1, ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2407; DB::rollBack(); RedisService::clear($cacheKey); return false; } } // 用户扣款 else{ $updateData = ['usdt'=>DB::raw("usdt - {$money}"),'update_time'=> time()]; if(!MemberModel::where(['id'=> $userId,'mark'=>1])->update($updateData)){ DB::rollBack(); $this->error = 2406; RedisService::clear($cacheKey); return false; } // 明细 $log = [ 'user_id' => $userId, 'source_id' => 0, 'source_order_no' => $orderNo, 'type' => 5, 'coin_type' => 1, 'user_type'=> 1, 'money' => -$money, 'actual_money' => -$money, 'balance' => $userUsdt, 'create_time' => time(), 'update_time' => time(), 'remark' => "USDT余额提现", 'status' => 1, 'mark' => 1, ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2407; DB::rollBack(); RedisService::clear($cacheKey); return false; } } DB::commit(); // 站内消息 $dateTime = date('Y-m-d H:i:s'); $title = $userType == 1 ? 'USDT余额提现申请成功' : '承兑商余额提现申请成功'; $message = $userType == 1 ? "您在{$dateTime}(UTC+8)申请提现{$money}USDT余额成功,请耐心等候审核!!!" : "您在{$dateTime}(UTC+8)申请提现{$money}USDT承兑商余额成功,请耐心等候审核!!!"; MessageService::make()->pushMessage($userId, $title, $message); // 提现自动审核,低于该金额自动审核 $autoCheckUsdt = ConfigService::make()->getConfigByCode('withdraw_auto_money', 300); $autoCheckUsdt = $autoCheckUsdt > 0 ? $autoCheckUsdt : 0; if ($money <= $autoCheckUsdt) { // 打款处理 $result = WalletService::make()->usdtTrcTransfer($trcUrl, $realUsdt); $txID = isset($result['txId']) ? $result['txId'] : ''; $payAddress = isset($result['address']) ? $result['address'] : ''; if ($txID && $payAddress) { $updateData = ['hash'=> $txID,'wallet_url'=> $payAddress,'audit_remark'=>'自动审核打款','status'=>2,'update_time'=>time()]; if(BalanceLogModel::where(['order_no'=> $orderNo,'user_type'=> $userType])->update($updateData)){ $title = $userType == 1 ? 'USDT余额提现审核成功' : '承兑商余额提现审核成功'; $message = $userType == 1 ? "您在{$dateTime}(UTC+8)申请提现{$money}USDT余额审核成功,请耐心等候打款到账!!!" : "您在{$dateTime}(UTC+8)申请提现{$money}USDT承兑商余额审核成功,请耐心等候打款到账!!!"; MessageService::make()->pushMessage($userId, $title, $message); AccountLogModel::where(['source_order_no'=> $orderNo])->update(['hash'=> $txID,'update_time'=>time()]); // 平台明细 $log = [ 'user_id' => 0, 'source_id' => $userId, 'source_order_no' => $orderNo, 'type' => 5, 'coin_type' => 1, 'user_type'=> 4, 'money' => $fee, 'actual_money' => $fee, 'balance' => 0, 'create_time' => time(), 'update_time' => time(), 'hash' => $txID, 'remark' => "USDT余额提现", 'status' => 1, 'mark' => 1, ]; AccountLogModel::insertGetId($log); // 平台流水 FinanceService::make()->saveLog(0, $fee, 1); } } } $this->error = $title; RedisService::clear($cacheKey); return [ 'id'=> $id, 'money'=> $money, 'user_type'=> $userType, ]; } /** * 余额充值 * @param $userId * @param $params * @return array|false */ public function buyxd($userId, $params) { $payPassword = isset($params['pay_password'])? trim($params['pay_password']) : ''; $money = isset($params['money'])? moneyFormat($params['money'], 2) : 0; $quota = isset($params['quota'])? moneyFormat($params['quota'], 2) : 0; $coinType = isset($params['coin_type']) && $params['coin_type']? intval($params['coin_type']) : 2; $payType = 10; if($money<=0){ $this->error = 2031; return false; } $cacheKey = "caches:acceptor:buyxd:lock_{$userId}"; if(RedisService::get($cacheKey)){ $this->error = 1034; return false; } $acceptor = $this->model->with(['member'])->where(['user_id' => $userId, 'mark' => 1]) ->select(['id', 'user_id', 'realname', 'mobile', 'usdt', 'quota', 'status','trade_status']) ->first(); $userInfo = $acceptor['member']; $status = isset($userInfo['status'])? $userInfo['status'] : 0; $balance = isset($userInfo['balance'])? $userInfo['balance'] : 0; $userUsdt = isset($userInfo['usdt'])? $userInfo['usdt'] : 0; $userPayPassword = isset($userInfo['pay_password'])?$userInfo['pay_password']:DB::table('member')->where('id',$userId)->value('pay_password'); if(empty($userInfo) || $status != 1){ $this->error = 2024; return false; } if($userPayPassword != get_password($payPassword)){ $this->error = 2038; return false; } // 充值订单 $orderNo = get_order_num('C2C'); // $money = $usdt; // 星豆 DB::beginTransaction(); RedisService::set($cacheKey, $userInfo, rand(2,3)); if($coinType == 2){ $xdPrice = ConfigService::make()->getConfigByCode('xd_price',100); $xdPrice = $xdPrice>0 && $xdPrice <=10000? $xdPrice : 100; $money = round($xdPrice * $quota,2); } $data = [ 'user_id'=> $userId, 'acceptor_id'=>$params['acceptor_id'], 'acceptor_uid'=>$params['acceptor_id'], 'order_no'=> $orderNo, 'type'=> 1, 'coin_type'=> 2, 'price'=>$params['money'], 'number'=>$params['quota'], 'account_id'=>'', 'mobile'=>'', 'real_name'=>'', 'total'=>$params['money'], 'usdt_rate'=>'', 'currency'=>$params['currency'], 'pay_type'=>$payType, 'pay_money'=>$params['money'], 'pay_status'=>2, 'pay_time'=>now(), 'bonus_usdt'=>'', 'pay_img'=>'', 'create_time'=>now(), 'update_time'=>now(), 'is_settle'=>2, 'exception_status'=> 0, 'sell_exception_img'=> '', 'exception_img'=> '', 'exception_remark'=> '', 'remark'=> '', 'mark'=> 1, ]; if(!$orderId = TradeModel::insertGetId($data)){ RedisService::clear($cacheKey); $this->error = 2033; DB::rollBack(); return false; } // 扣除USDT $log = [ 'user_id'=> $userId, 'source_order_no'=> $data['order_no'], 'user_type'=> 1, 'type'=> 5, 'coin_type'=> 1, 'money'=> -$usdt, 'actual_money'=> -$usdt, 'balance'=> $userUsdt, 'date'=> date('Y-m-d'), 'create_time'=> time(), 'remark'=> '星豆余额充值扣除', 'status'=>1, 'mark'=>1 ]; if(!AccountLogModel::insertGetId($log)){ RedisService::clear($cacheKey); $this->error = 2029; DB::rollBack(); return false; } // 增加星豆余额 $log = [ 'user_id'=> $userId, 'source_order_no'=> $data['order_no'], 'user_type'=> 1, 'type'=> 5, 'coin_type'=> 2, 'money'=> $usdt, 'actual_money'=> $money, 'balance'=> $balance, 'date'=> date('Y-m-d'), 'create_time'=> time(), 'remark'=> '星豆余额充值', 'status'=>1, 'mark'=>1 ]; if(!AccountLogModel::insertGetId($log)){ RedisService::clear($cacheKey); $this->error = 2029; DB::rollBack(); return false; } // 消息 $dateTime = date('Y-m-d H:i:s'); MessageService::make()->pushMessage($userId,'星豆余额充值成功',"您在{$dateTime}(UTC+8)成功支付{$usdt}USDT充值{$money}星豆",3); DB::commit(); // 充值星豆任务 TaskService::make()->updateTask($userId,9, 0); $this->error = 2037; RedisService::clear($cacheKey); return ['order_id'=> $orderId,'balance'=> moneyFormat($balance + $money,2),'usdt'=> moneyFormat($userUsdt-$usdt, 2)]; } }