with('userInfo') ->whereNotNull('tx_hash') ->where('status',OfflineRechargeRecordModel::StatusConfirm) ->order('id') ->limit(10) ->select(); if (empty($order_list)) { return '暂无可用订单'; } $bonus_arr = Config::get('bonus'); $pay_address = Env::get('rental.pay_address'); foreach ($order_list as $item) { dump($item['order_no'],true,'开始处理订单'); // 请求api,判断是否到账 $result = $this->updateOrderPayStatus($item, $pay_address); dump($result,true,'校验结果'); $insert_data = [ 'order_no' => $item['order_no'], 'user_id' => $item['user_id'], 'hash' => $item['tx_hash'], 'result' => 1, 'fail_reason' => '成功', ]; if($result['code'] == 0){//失败 $insert_data['fail_reason'] = $result['msg']; $insert_data['result'] = 0; $check_count = (new OfflineRechargePayLogModel())->where('order_no', $item['order_no'])->count(); if($check_count >= self::CheckCount){ //扫描次数是否大于 5次,则改订单支付失败 //更新支付记录 (new OfflineRechargeRecordModel()) ->where('id', $item['id']) ->update([ 'status' => OfflineRechargeRecordModel::StatusFail,//支付失败 'note' => '支付失败,校验次数:' . self::CheckCount, 'update_time' => time(), ]); } } // 记录执行记录 $log_id = (new OfflineRechargePayLogModel())->insertGetId($insert_data); //增加业绩或发放佣金 if($result['code'] == 1 && $item['cha_bao'] > 0){ switch ($item['order_type']){ case 1://产品 $uid = $item['user_id']; $amount= $item['amount']; $num = $item['cha_bao']; // 启动事务 Db::startTrans(); try { //充值茶宝 (new LedgerWalletModel)->changeWalletAccount($uid, Asset::TOKEN, $num, LedgerTokenChangeModel::Recharge, $item['id']); // // // 更新自己(有效会员时间)和所有上级的信息(有效直推人数和团队总算力) // (new UserModel())->updateForRental($uid, $power); // //// // 发放直推USDT收益 // (new LedgerWalletModel)->sendUsdtProfit($uid, $amount); // // // 发放直推算力收益 // (new LedgerWalletModel)->sendDirectProfit($uid, $power); // // 间推奖 // (new LedgerWalletModel)->sendGenerateProfit($uid, $amount); // // 发放见点奖 // (new LedgerWalletModel)->sendRegBonus($uid); // 提交事务 Db::commit(); } catch (Exception $e) { // 回滚事务 Db::rollback(); return $e->getMessage(); } dump($item['order_no'],true,'处理结束'); break; case 2://服务器 break; } } } } /* * 扫描收款地址 */ public function updateOrderPayStatus($pay_info, $to_address) { $pay_info['from_address'] = strtolower($pay_info['from_address']); if($pay_info['from_address'] != strtolower($pay_info['user_info']['address'])){ return _error('from_adress不一致:用户地址:' . $pay_info['user_info']['address'] . ',充值表地址' . $pay_info['from_address']); } $get_transaction_info = (new MyBscApi())->getInfoByTransactionHash($pay_info['tx_hash']); if($get_transaction_info['code'] == 0){ return $get_transaction_info; } $hash_info = $get_transaction_info['data']; if(!$hash_info['success']){ return _error('交易失败'); } //$pay_info['from_address'] = strtolower($pay_info['user_info']['address']); $pay_info['to_address'] = strtolower($to_address); $hash_info['from_address'] = strtolower($hash_info['from_address']); $hash_info['to_address'] = strtolower($hash_info['to_address']); if(!($hash_info['from_address'] == $pay_info['from_address'])){ return _error('from_adress不一致:用户地址:' . $pay_info['from_address'] . ',链上' . $hash_info['from_address']); } if(!($hash_info['to_address'] == $pay_info['to_address'])){ return _error('to_adress不一致:用户地址:' . $pay_info['to_address'] . ',链上' . $hash_info['to_address']); } if(!($hash_info['contract_address'] == '0x55d398326f99059fF775485246999027B3197955')){ return _error('合约地址不是USDT,链上' . $hash_info['contract_address']); } if(!($hash_info['amount'] - $pay_info['amount'] == 0)){ return _error('金额不一致:订单金额:' . $pay_info['amount'] . ',链上' . $hash_info['amount']); } //更新订单 Db::startTrans(); try { //更新支付记录 (new OfflineRechargeRecordModel()) ->where('id', $pay_info['id']) ->update([ 'status'=> OfflineRechargeRecordModel::StatusSuccess,//支付成功 'update_time' => time(), ]); // 提交事务 Db::commit(); } catch (Exception $e) { // 回滚事务 Db::rollback(); return _error('提交失败:' . $e->getMessage()); } return _success(''); } public function scanOrders() { $recharges = (new OfflineRechargeRecordModel()) ->where('status',OfflineRechargeRecordModel::StatusConfirm) ->order('id') ->limit(10) ->select(); if (!is_null($recharges)) { foreach ($recharges as $v) { $vArr = $v->toArray(); // 请求api $result = $this->verifyTxHash($vArr); // 记录执行记录 (new OfflineRechargeVerifyModel())->insert([ 'order_id' => $vArr['id'], 'user_id' => $vArr['user_id'], 'result' => $result == '', 'fail_reason' => $result, 'create_time' => time(), ]); } } } /** * 取消订单 * * 同时会有判断是否恢复订单 * @return void */ public function cancelOrder() { $times = 60*10;//十分钟 //筛选10分钟前创建订单却未支付的订单 $order_info = (new OfflineRechargeRecordModel()) ->field('r.id,r.user_id,u.address,r.create_time,r.amount') ->alias('r') ->join('user u','u.id = r.user_id') ->where('r.status',OfflineRechargeRecordModel::StatusDefault) ->where('r.create_time', '<', time() - $times) ->order('r.id') ->find(); if(empty($order_info)){ dump('本次没有未处理订单'); return; } $to_address = Env::get('rental.pay_address'); $get_block = (new BscApi())->getBlockNoByTime($order_info['create_time']); if($get_block['code'] == 0){ \think\Log::info($get_block['msg'] . date('Y-m-d H:i:s')); dump($get_block, true, '获取区块高度有误'); return; } //获取开始预约前的区块高度 $start_block = $get_block['data']; dump('对应区块高度:' . $start_block); $pay_info = (new BscApi())->getTransactionRecordsByAddress($order_info['address'], $to_address, $start_block); dump($pay_info); if($pay_info['code'] != 1) { dump($pay_info['msg'], true, '获取交易数据失败'); return; } $pay_data = $pay_info['data']; if (empty($pay_data)) {//无交易记录,则取消 $result = (new OfflineRechargeRecordModel()) ->where('id', $order_info['id']) ->update([ 'status' => OfflineRechargeRecordModel::StatusFail, 'update_time' => time(), 'note' => '无交易记录,则取消', ]); return; } //找出金额匹配的交易数据 $pay_arr = []; foreach ($pay_data as $pay) { if ($pay['amount'] - $order_info['amount'] == 0) { $pay_arr[] = $pay; } } if (empty($pay_arr)) { $result = (new OfflineRechargeRecordModel()) ->where('id', $order_info['id']) ->update([ 'status' => OfflineRechargeRecordModel::StatusFail, 'update_time' => time(), 'note' => '有交易记录,金额不匹配,则取消', ]); return; } //判断匹配上金额的数据,有没有存在 foreach ($pay_arr as $pay) { $check = (new OfflineRechargeRecordModel()) ->where('tx_hash', $pay['hash']) ->count(); if ($check == 0 && $pay['time'] > $order_info['create_time']) { //hash不存在,并且交易时间大于订单创建时间,则捡回订单,改成待确认 $result = (new OfflineRechargeRecordModel()) ->where('id', $order_info['id']) ->update([ 'status' => OfflineRechargeRecordModel::StatusConfirm, 'tx_hash' => $pay['hash'], 'update_time' => time(), 'note' => '捡回订单', ]); return; } } $result = (new OfflineRechargeRecordModel()) ->where('id', $order_info['id']) ->update([ 'status' => OfflineRechargeRecordModel::StatusFail, 'update_time' => time(), 'note' => '有交易记录,hash已存在或交易时间小于订单创建时间,则取消', ]); return; } }