where('status',$status)->order('id desc')->paginate($limit); }else{ $list = RechargeModel::where('user_id',\support\Jwt\JwtToken::getCurrentId())->order('id desc')->paginate($limit); } return $this->success(__('successful'),$list->toArray()); } /** * 创建 * @Apidoc\Method("POST") * @Apidoc\Param("amount", type="string", require=true, desc="金额") * @Apidoc\Param("network", type="string", require=true, desc="网络") */ function create(){ return $this->create1(); } public function create2() { $user = \support\Jwt::getUser(); $data = [ 'user_id' => $user->id, 'amount' => input('amount',0), 'network' => input('network',''), 'status' => \app\enum\WithdrawlStatus::CREATED->value ]; //验证最小金额 if($data['amount'] < Config('site.recharge_minimum')){ return $this->error(__('Minimum recharge of %num%',[ '%num%' => Config('site.recharge_minimum') ])); } if (!$data['network'] || !in_array($data['network'],['BEP-20','TRC-20','wxpay','alipay','qqpay'])) { return $this->error(__('Network is incorrect')); } if(in_array($data['network'],['BEP-20','TRC-20'])){ $ing_count = RechargeModel::where('user_id',$data['user_id'])->where('status',\app\enum\RechargeStatus::CREATED->value)->count('id'); if($ing_count >= 2){ return $this->error(__('You have reached the limit of uncompleted orders ( %max% ). Please complete the existing orders before trying to create another one.',[ '%max%' => 2 ])); } Db::startTrans(); try { /** @var RechargeModel $order */ $order = RechargeModel::create($data); //$order->notify_url = Request()->domain().'/api/recharge/notify'; $order->notify_url = config('pay.notify_server').'/api/recharge/notify'; $order->out_trade_no = $order->id; $order->env = 'product'; $order->appid = Config('pay.appid'); $order->created_at = time(); $postdata = $order->toArray(); unset($postdata['id']); //转换成USDT $postdata['amount'] = bcdiv($order->amount,Config('site.money_to_usdt_rate'),4); //折扣 $postdata['amount'] = bcdiv($postdata['amount'],Config('site.usdt_recharge_discount'),4); $res = post(Config('pay.server').'/recharge/create',$postdata); \support\Log::alert("create res:".$res); //cp($res); $res = json_decode($res,true); if($res['code'] === 0){ $order->address = $res['data']['address']; }else{ Db::rollback(); return $this->error(__('Failed to create recharge order, please try again later')); } $order->allowField(['address'])->save(); Db::commit(); return $this->success(__('successful'),[ 'order' => $order ]); } catch (\Exception $e) { Db::rollback(); \support\Log::alert("create error".$e->getMessage()); return $this->error(__('Failed to create recharge order, please try again later')); } }else{ $sign = aesencode(json_encode($data)); return $this->success(__('successful'),[ 'order' => [ 'id' => 0, 'network' => $data['network'], 'amount' => $data['amount'], "url" => 'http://43.240.74.89:9595/pay/index?sign='.$sign ] ]); } } public function create1() { $user = \support\Jwt::getUser(); $data = [ 'user_id' => $user->id, 'amount' => input('amount',0), 'network' => input('network',''), 'status' => \app\enum\WithdrawlStatus::CREATED->value ]; //验证最小金额 if($data['amount'] < Config('site.recharge_minimum')){ return $this->error(__('Minimum recharge of %num%',[ '%num%' => Config('site.recharge_minimum') ])); } if (!$data['network'] || !in_array($data['network'],['BEP-20','TRC-20','wxpay','alipay','qqpay'])) { return $this->error(__('Network is incorrect')); } if(in_array($data['network'],['BEP-20','TRC-20'])){ $ing_count = RechargeModel::where('user_id',$data['user_id'])->where('status',\app\enum\RechargeStatus::CREATED->value)->count('id'); if($ing_count >= 2){ return $this->error(__('You have reached the limit of uncompleted orders ( %max% ). Please complete the existing orders before trying to create another one.',[ '%max%' => 2 ])); } } Db::startTrans(); try { /** @var RechargeModel $order */ $order = RechargeModel::create($data); if(in_array($data['network'],['BEP-20','TRC-20'])){ //$order->notify_url = Request()->domain().'/api/recharge/notify'; $order->notify_url = config('pay.notify_server').'/api/recharge/notify'; $order->out_trade_no = $order->id; $order->env = 'product'; $order->appid = Config('pay.appid'); $order->created_at = time(); $postdata = $order->toArray(); unset($postdata['id']); //转换成USDT $postdata['amount'] = bcdiv($order->amount,Config('site.money_to_usdt_rate'),4); //折扣 $postdata['amount'] = bcmul($postdata['amount'],Config('site.usdt_recharge_discount'),4); $res = post(Config('pay.server').'/recharge/create',$postdata); \support\Log::alert("create res:".$res); //cp($res); $res = json_decode($res,true); if($res['code'] === 0){ $order->address = $res['data']['address']; }else{ Db::rollback(); return $this->error(__('Failed to create recharge order, please try again later')); } $order->allowField(['address'])->save(); }else{ $postdata = [ "pid" => '144604', "type" => $order->network, "out_trade_no" => $order->id, "notify_url" => Config('pay.notify_server').'/api/recharge/notify_ok', "return_url" => Config('pay.notify_server').'/api/recharge/notify_ok', "name" => 'VIP会员', "money" => $order->amount, "device" => "mobile", "clientip" => request()->getRealIp() ]; $postdata['money'] = bcdiv($postdata['money'] ,Config('site.rmb_recharge_discount'),2); //\support\Log::alert("create postdata:".json_encode($postdata)); $this->getsign($postdata); $res = post('https://pay.yf2.cn/mapi.php',$postdata); \support\Log::alert("create res:".$res); $res = json_decode($res,true); if($res['code'] === 1){ if(isset($res['payurl'])){ $order->address = $res['qrcode']; }elseif(isset($res['qrcode'])){ $order->address = $res['qrcode']; }elseif(isset($res['urlscheme'])){ $order->address = $res['urlscheme']; } }else{ Db::rollback(); \support\Log::error(json_encode($res)); throw new \Exception($res['msg']); } $order->allowField(['address'])->save(); } Db::commit(); return $this->success(__('successful'),[ 'order' => $order ]); } catch (\Exception $e) { Db::rollback(); \support\Log::alert("create error".$e->getMessage()); return $this->error(__('Failed to create recharge order, please try again later')); } } /** * 更新 * @Apidoc\Method("POST") * @Apidoc\Param("id", type="int", require=true, desc="ID") * @Apidoc\Param("amount", type="string", require=true, desc="金额") * @Apidoc\Param("network", type="string", require=true, desc="网络") */ function update(){ $id = input('id'); $amount = input('amount'); $network = input('network'); $data = []; if(!$id){ return $this->error(__('Invalid parameters')); } /** @var RechargeModel $order */ $order = RechargeModel::where('id',$id)->find(); if(!$order){ return $this->error(__('Order not exsit')); } if($amount && $amount != $order->amount){ $data['amount'] = $amount; //验证最小金额 if($data['amount'] < Config('site.recharge_minimum')){ return $this->error(__('Minimum recharge of %num%',[ '%num%' => Config('site.recharge_minimum') ])); } $data['amount'] = bcdiv($data['amount'],Config('site.money_to_usdt_rate'),4); } if($network && $network != $order->network){ $data['network'] = $network; if (!$data['network'] || !in_array($data['network'],['BEP-20','TRC-20'])) { return $this->error(__('Network is incorrect')); } } if(empty($data)){ return $this->error(__('Invalid parameters')); } foreach($data as $field=>$value){ $order->$field = $value; } $data['out_trade_no'] = $order->id; $data['action'] = 'update'; $data['appid'] = Config('pay.appid'); $res = post(Config('pay.server').'/recharge/create',$data); //\support\Log::alert("update res:".$res); $res = json_decode($res,true); //cp($res); if($res['code'] === 0){ if($order->address != $res['data']['address']){ $order->address = $res['data']['address']; } }else{ return $this->error(__('Failed to create recharge order, please try again later')); } $order->save(); return $this->success(__('successful'),[ 'order' => $order ]); } /** * 详情 * @Apidoc\Query("id", type="string", require=true, desc="ID") */ public function detail(){ $appid = input('id'); $vo = RechargeModel::where('id',$appid)->find(); if($vo) { return $this->success(__('successful'),[ 'order' => $vo ]); } return $this->error(__("Record does not exist")); } /** * 转账成功异步通知 * @Apidoc\NotParse() * @Apidoc\NotDebug() */ public function notify(){ $data = aesdecode(input('data')); $data = json_decode($data,true); /** @var RechargeModel $vo */ $vo = RechargeModel::where('id',$data['out_trade_no'])->find(); if($vo){ if($data['result'] == 'SUCCESS'){ if($vo->status != \app\enum\RechargeStatus::COMPLETE->value){ try{ $vo->status = \app\enum\RechargeStatus::COMPLETE->value; $vo->txid = $data['txid']; $vo->real_amount = isset($data['real_amount']) ? $data['real_amount'] : 0; $vo->transfer_at = $data['transfer_at'] ?: time(); $vo->save(); //消除USDT和人民币的误差,因为USDT支付可能不是一模一样的金额 $money = bcmul($vo->amount ,Config('site.rmb_to_money_rate')); UserModel::money($vo->user_id,$money,\app\enum\BalanceType::RECHARGE,$vo->id); Hook('recharge.success',$vo); }catch(\Exception $e){ log_write('充值回调失败:'.$e->getMessage()); log_write($data); } } }else{ $vo->status = \app\enum\RechargeStatus::FAIL->value; $vo->txid = $data['txid']; $vo->reason = $data['reason']; $vo->save(); } } return response("SUCCESS"); } /** * 人民币转账成功异步通知 * @Apidoc\NotParse() * @Apidoc\NotDebug() */ public function notify_ok(){ $data = Input('post.'); $sign = get_pay_sign($data); if($sign != $data['sign']){ return response("FAIL"); } /** @var RechargeModel $vo */ $vo = RechargeModel::where('id',$data['out_trade_no'])->find(); if($vo && isset($data['trade_status'])){ if($data['trade_status'] === 'TRADE_SUCCESS'){ if($vo->status != \app\enum\RechargeStatus::COMPLETE->value){ try{ $vo->status = \app\enum\RechargeStatus::COMPLETE->value; $vo->txid = isset($data['trade_no']) ? $data['trade_no'] : ''; $vo->from='pay.yf2.cn'; $vo->real_amount = isset($data['money']) ? $data['money'] : 0; $vo->save(); $money = bcmul($vo->real_amount ,Config('site.rmb_to_money_rate')); UserModel::money($vo->user_id,$money,\app\enum\BalanceType::RECHARGE,$vo->id); Hook('recharge.success',$vo); }catch(\Exception $e){ log_write('充值回调失败:'.$e->getMessage()); log_write($data); return response("FAIL"); } } } } return response("SUCCESS"); } /** * 根据TXID更新用户余额,补单的功能 * @Apidoc\NotParse() * @Apidoc\NotDebug() * @return \support\Response */ function update_balance_by_txid(){ $user_id = \support\Jwt\JwtToken::getCurrentId(); $data = [ 'txid' => input('txid'), 'id' => input('id'), 'status' => \app\enum\WithdrawlStatus::CREATED->value ]; /** @var RechargeModel $vo */ $vo = RechargeModel::where('id',$data['id'])->find(); if($vo->user_id !=$user_id){ return $this->error(__('permission denied')); } //验证最小金额 if(!$data['txid']){ return $this->error(__('Invalid parameters')); } $res = get(Config('pay.server').'/Util/txid?txid='.$data['txid']); $res = json_decode($res,true); if($res['code'] !== 0){ return $this->error($res['msg']); } $vo->txid = $data['txid']; $vo->result = $res['result']; if($res['result'] == 'SUCCESS'){ $vo->from = $res['from']; $vo->real_amount = $res['real_amount']; $vo->pay_time = $res['timestamp']; $vo->status = \app\enum\RechargeStatus::COMPLETE->value; }else{ $vo->result = $res['from']; $vo->reason = $res['real_amount']; $vo->status = \app\enum\RechargeStatus::FAIL->value; } $vo->save(); return $this->success(__('successful')); } /** * 根据监视上报数据更新用户余额 * @Apidoc\NotParse() * @Apidoc\NotDebug() */ function updateUserBalance(Request $request){ $decimal_part = $request->post('decimal_part'); $data = [ 'user_id' => 0 , 'amount' => $request->post('amount'), 'network' => $request->post('chain'), 'address' => $request->post('to'), 'from' => $request->post('from'), 'txid' => $request->post('txid'), 'pay_time' => $request->post('pay_time'), 'created_at' => $request->post('pay_time'), ]; if($data['network'] == 'TRC-20'){ $data['user_id'] = UserModel::where('trc_recharge_address',$data['address'])->where('decimal_part',$decimal_part)->value('id'); }else{ $data['user_id'] = UserModel::where('bep_recharge_address',$data['address'])->where('decimal_part',$decimal_part)->value('id'); } if(!$data['user_id']){ return $this->success(__('user not exist')); } $data['real_amount'] = $data['amount']; //$data['pay_time'] = time(); $data['status'] = 2; $vo = RechargeModel::where('txid',$data['txid'])->find(); if($vo){ return $this->success(__('exist')); } Db::startTrans(); try{ $idata = RechargeModel::create($data); UserModel::score($data['user_id'],$data['amount'],\app\enum\BalanceType::RECHARGE,$idata['id'].''); Db::commit(); Hook('recharge.success',$idata); return $this->success(__('successful')); }catch(\Exception $e){ Db::rollback(); return $this->error($e->getMessage()); } } /** * 监视列表 * @Apidoc\NotParse() * @Apidoc\NotDebug() */ function watch_list(){ //$bep = UserModel::distinct(true)->column('LOWER(bep_recharge_address)'); //$trc = UserModel::distinct(true)->column('LOWER(trc_recharge_address)'); $bep = UserModel::distinct(true)->column('bep_recharge_address'); $trc = UserModel::distinct(true)->column('trc_recharge_address'); return $this->success(__('successful'),[ 'BEP-20'=>$bep, 'TRC-20'=>$trc, ]); } protected function getsign(&$data, $key = "3E7551E3707DFB6B6E8A6E83B01FF437") { return get_pay_sign($data,$key); } }