// +---------------------------------------------------------------------- namespace App\Services\Oapi; use App\Models\ApiModel; use App\Models\CapitalLogModel; use App\Models\MemberModel; use App\Models\MemberPaymentModel; use App\Models\TradeOrderModel; use App\Services\Api\MemberPaymentService; use App\Services\BaseService; use App\Services\ChatMessageService; use App\Services\Common\ApiService; use App\Services\Common\MemberService; use App\Services\ConfigService; use App\Services\RedisService; /** * 用户交易订单-服务类 * Class TradeOrderService * @package App\Services\Oapi */ class TradeOrderService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @since 2020/11/10 * TradeOrderService constructor. */ public function __construct() { $this->model = new TradeOrderModel(); $this->memberModel = new MemberModel(); $this->apiModel = new ApiModel(); $this->capitalModel = new CapitalLogModel(); $this->paymentModel = new MemberPaymentModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * @param $orderNo * @return array */ public function getInfoByNo($orderNo, $userId=0) { $info = $this->model->from('trade_order as a') ->leftJoin('member as b', 'b.id', '=', 'a.business_id') ->leftJoin('member as c', 'c.id', '=', 'a.user_id') ->leftJoin('user as u', 'u.user_id', '=', 'a.business_id') ->where(['order_no'=> $orderNo]) ->where(function ($query) use($userId){ $query->where(['a.mark' => 1])->where('a.status', '>=', 0); if($userId>0){ $query->where(['a.user_id'=> $userId]); } }) ->select(['a.*', 'b.username','b.realname','b.idcard_check','b.credit','u.bond', 'c.username as c_username','c.realname as c_realname']) ->first(); $info = $info? $info->toArray() : []; if($info){ $overTime = ConfigService::make()->getConfigByCode('trade_order_overtime'); $overTime = $overTime ? $overTime : 5; $info['idcardData'] = $info['idcard_data'] ? json_decode($info['idcard_data'], true) : []; $info['paymentData'] = $info['payment_data'] ? json_decode($info['payment_data'], true) : []; $info['create_time_text'] = $info['create_time'] ? datetime($info['create_time'], 'Y-m-d H:i:s') : ''; $info['update_time_text'] = $info['update_time'] ? datetime($info['update_time'], 'Y-m-d H:i:s') : ''; $info['time_text'] = $info['create_time'] ? datetime($info['create_time'], 'H:i') : ''; $info['utime_text'] = $info['update_time'] ? datetime($info['update_time'], 'H:i') : ''; $info['pay_time_text'] = $info['pay_time'] ? datetime($info['pay_time'], 'Y-m-d H:i') : ''; $info['username_text'] = $info['username'] ? format_account($info['username']) : ''; $info['c_username_text'] = $info['c_username'] ? format_account($info['c_username']) : ''; $info['exception_img'] = $info['exception_img'] ? get_image_url($info['exception_img']) : ''; $info['pay_img'] = $info['pay_img'] ? get_image_url($info['pay_img']) : ''; $info['paymentData']['qrcode'] = isset($info['paymentData']['qrcode']) && $info['paymentData']['qrcode'] ? get_image_url($info['paymentData']['qrcode']) : ''; $payType = isset($info['pay_type']) ? $info['pay_type'] : 0; $info['pay_name'] = isset($payTypes[$payType]) ? $payTypes[$payType] : '其他'; $info['chat_key'] = getChatKey($info['user_id'],$info['business_id']); $overTime = max(0, intval(strtotime($info['create_time'])) + $overTime * 60 - time()); $info['overtime_text'] = in_array($info['status'], [1, 2]) && $overTime ? date('i:s', $overTime) : '00:00'; $info['overtime'] = $overTime; } return $info; } /** * * @param $txid 币交易单号 * @return array */ public function getInfoByTradeHash($txid, $userId=0) { $info = $this->model->from('trade_order as a') ->leftJoin('member as b', 'b.id', '=', 'a.business_id') ->leftJoin('member as c', 'c.id', '=', 'a.user_id') ->leftJoin('user as u', 'u.user_id', '=', 'a.business_id') ->where(['txid'=> $txid]) ->where(function ($query) use($userId){ $query->where(['a.mark' => 1])->where('a.status', '>=', 0); if($userId>0){ $query->where(['a.user_id'=> $userId]); } }) ->select(['a.*', 'b.username','b.realname','b.idcard_check','b.credit','u.bond', 'c.username as c_username','c.realname as c_realname']) ->first(); $info = $info? $info->toArray() : []; if($info){ $overTime = ConfigService::make()->getConfigByCode('trade_order_overtime'); $overTime = $overTime ? $overTime : 5; $info['idcardData'] = $info['idcard_data'] ? json_decode($info['idcard_data'], true) : []; $info['paymentData'] = $info['payment_data'] ? json_decode($info['payment_data'], true) : []; $info['create_time_text'] = $info['create_time'] ? datetime($info['create_time'], 'Y-m-d H:i:s') : ''; $info['update_time_text'] = $info['update_time'] ? datetime($info['update_time'], 'Y-m-d H:i:s') : ''; $info['time_text'] = $info['create_time'] ? datetime($info['create_time'], 'H:i') : ''; $info['utime_text'] = $info['update_time'] ? datetime($info['update_time'], 'H:i') : ''; $info['pay_time_text'] = $info['pay_time'] ? datetime($info['pay_time'], 'Y-m-d H:i') : ''; $info['username_text'] = $info['username'] ? format_account($info['username']) : ''; $info['c_username_text'] = $info['c_username'] ? format_account($info['c_username']) : ''; $info['exception_img'] = $info['exception_img'] ? get_image_url($info['exception_img']) : ''; $info['pay_img'] = $info['pay_img'] ? get_image_url($info['pay_img']) : ''; $info['paymentData']['qrcode'] = isset($info['paymentData']['qrcode']) && $info['paymentData']['qrcode'] ? get_image_url($info['paymentData']['qrcode']) : ''; $payType = isset($info['pay_type']) ? $info['pay_type'] : 0; $info['pay_name'] = isset($payTypes[$payType]) ? $payTypes[$payType] : '其他'; $info['chat_key'] = getChatKey($info['user_id'],$info['business_id']); $overTime = max(0, intval(strtotime($info['create_time'])) + $overTime * 60 - time()); $info['overtime_text'] = in_array($info['status'], [1, 2]) && $overTime ? date('i:s', $overTime) : '00:00'; $info['overtime'] = $overTime; } return $info; } /** * 获取未支付或处理的订单数 * @param $userId * @param int $type * @return mixed */ public function checkOrderNoCatch($userId, $type = 1) { return $this->model->where(['user_id' => $userId, 'type' => $type, 'mark' => 1])->whereIn('status', [1, 2, 5, 7])->count('id'); } /** * 客户买入 * @param $userId * @param $params * @return false|int|number */ public function buy($userId, $params) { $num = isset($params['num']) ? floatval($params['num']) : 0; $tradeType = isset($params['trade_type']) ? intval($params['trade_type']) : 0; $apiId = isset($params['api_id']) ? intval($params['api_id']) : 0; $contactType = isset($params['contact_type']) ? intval($params['contact_type']) : 0; $usdtAddress = isset($params['usdt_address']) ? trim($params['usdt_address']) : ''; $ptOrderNo = isset($params['order_no']) ? trim($params['order_no']) : ''; $notifyUrl = isset($params['notify_url']) ? trim($params['notify_url']) : ''; $tradeType = $tradeType==3? $tradeType : 2; // BC平台需要注册登录 if ($userId <= 0 && $tradeType == 3) { $this->error = '1013'; return false; } if(empty($notifyUrl)){ $this->error = '6007'; return false; } if(empty($ptOrderNo)){ $this->error = '6006'; return false; } if($apiId<=0){ $this->error = '6005'; return false; } if(!in_array($contactType, [1,2])){ $this->error = '2209'; return false; } if(empty($usdtAddress)){ $this->error = '2235'; return false; } // 验证参数 $config = ConfigService::make()->getConfigOptionByGroup(5); $tradeOpen = isset($config['trade_usdt_open']) ? $config['trade_usdt_open'] : 0; $tradeMinNum = isset($config['trade_min_num']) ? $config['trade_min_num'] : 0; $tradeMaxNum = isset($config['trade_max_num']) ? $config['trade_max_num'] : 0; $trademinMoney = isset($config['trade_min_money']) ? $config['trade_min_money'] : 0; $tradeMaxMoney = isset($config['trade_max_money']) ? $config['trade_max_money'] : 0; $tradePrice = isset($config['usdt_buy_price']) ? $config['usdt_buy_price'] : 0; $tradeLimitNum = isset($config['trade_no_catch']) ? $config['trade_no_catch'] : 0; // 是否开启交易 if ($tradeOpen != 1) { $this->error = '1013'; return false; } if ($tradePrice <= 0) { $this->error = '3002'; return false; } // 验证数量或金额 if ($num < $tradeMinNum || $num > $tradeMaxNum) { $this->error = '3003'; return false; } $total = moneyFormat($num * $tradePrice, 6); // 用户信息,BC平台需要注册认证 if($tradeType == 3){ $userInfo = MemberService::make()->getInfo($userId); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; $idcardCheck = isset($userInfo['idcard_check']) ? $userInfo['idcard_check'] : 0; //$username = isset($userInfo['username']) && $userInfo['username'] ? format_account($userInfo['username']) : ''; if ($status != 1) { $this->error = '2009'; return false; } if ($idcardCheck != 1) { $this->error = '2014'; return false; } } // 客户身份信息 $idcardData = [ 'idcard' => isset($userInfo['idcard']) ? $userInfo['idcard'] : $params['idcard'], 'realname' => isset($userInfo['realname']) ? $userInfo['realname'] : $params['realname'], 'bank_name' => isset($params['bank_name']) ? $params['bank_name'] : $params['bank_name'], 'bank_card' => isset($params['bank_card']) ? $params['bank_card'] : $params['bank_card'], 'idcard_check' => isset($userInfo['idcard_check']) ? $userInfo['idcard_check'] : (($params['realname'] && $params['idcard'])? 1:2), 'idcard_front_img' => isset($userInfo['idcard_front_img']) ? $userInfo['idcard_front_img'] : '', 'idcard_back_img' => isset($userInfo['idcard_back_img']) ? $userInfo['idcard_back_img'] : '', 'idcard_hand_img' => isset($userInfo['idcard_hand_img']) ? $userInfo['idcard_hand_img'] : '', ]; $apiInfo = ApiService::make()->getInfo($apiId); $apiName = isset($apiInfo['account'])? $apiInfo['account'] : ''; if(empty($apiInfo)){ $this->error = '6005'; return false; } // 未处理订单 /*$noCatchOrder = $this->checkOrderNoCatch($userId, 1); if ($tradeLimitNum > 0 && $noCatchOrder >= $tradeLimitNum) { $this->error = lang(3005, ['num' => $tradeLimitNum]); return false; }*/ // 匹配交易商家 $businessInfo = \App\Services\Api\MemberService::make()->getTradeMember($num, 1, $userId); if (empty($businessInfo)) { $this->error = '3004'; return false; } if($businessInfo['usdt_num']<$num){ $this->error = '3004'; return false; } // 币商收款方式 $payment = MemberPaymentService::make()->getPayment($businessInfo['id']); if (empty($payment)) { $this->error = '3015'; return false; } $this->model->startTrans(); $orderNo = get_order_num('PT'); $data = [ 'user_id' => $userId, 'api_id' => $apiId, 'business_id' => $businessInfo['id'], 'order_no' => $orderNo, 'type' => 1, 'source' => $apiName, 'usdt_address' => $usdtAddress, 'pt_order_no' => $ptOrderNo, 'notify_url' => $notifyUrl, 'contact_type' => $contactType, 'trade_type' => $tradeType==2? $tradeType : 3, 'pay_type' => isset($params['pay_type']) ? floatval($params['pay_type']) : 1, 'price' => $tradePrice, 'num' => $num, 'total' => $total, 'payment_id' => isset($payment['id']) ? intval($payment['id']) : 0, 'idcard_data' => $idcardData ? json_encode($idcardData, 256) : '', 'payment_data' => $payment ? json_encode($payment, 256) : '', 'create_time' => time(), 'update_time' => time(), 'status' => 1, 'mark' => 1, ]; if (!$order = $this->model->edit($data)) { $this->model->rollBack(); $this->error = '3023'; return false; } if(!$this->memberModel->where(['id'=> $businessInfo['id']])->decrement('usdt_num', $num)){ $this->model->rollBack(); $this->error = '3020'; return false; } $data = [ 'order_no'=> $orderNo, 'user_id'=> $businessInfo['id'], 'type'=> 7, 'pay_type'=> 1, 'change_type'=> 2, 'num'=> $num, 'total'=> $total, 'balance'=> floatval($businessInfo['usdt_num']-$num), 'create_time'=> time(), 'update_time'=> time(), 'status'=> 1, 'mark'=>1, 'remark'=> '交易员卖给平台', ]; if(!$this->capitalModel->edit($data)){ $this->model->rollBack(); $this->error = '3014'; return false; } // 订单通知 $data = [ 'from_uid' => $userId, 'to_uid' => $businessInfo['id'], 'type' => 2, 'order_no' => $orderNo, 'chat_key' => getChatKey($userId, $businessInfo['id']), 'message' => "您有来自外来客户买单订单:{$orderNo}的消息,请尽快回复!", 'message_type' => 1, 'data_type' => 2, 'create_time' => time(), 'update_time' => time(), 'status' => 1, 'mark' => 1, ]; if (!ChatMessageService::make()->pushMessage($data)) { $this->model->rollBack(); $this->error = '3031'; return false; } $this->model->commit(); $host = env('WEB_URL',''); $host = $host? $host : request()->header('HOST'); $token = isset($params['token'])? $params['token'] : ''; $url = $host.'/h5/#/pages/h5/confirm?order_no='.$data['order_no'].'&token='.$token; return ['token'=> $token, 'order_no'=> $data['order_no'],'url'=> $url]; } /** * 客户卖出 * @param $userId * @param $params * @return false|int|number */ public function sell($userId, $params) { $num = isset($params['num']) ? floatval($params['num']) : 0; $tradeType = isset($params['trade_type']) ? intval($params['trade_type']) : 0; $apiId = isset($params['api_id']) ? intval($params['api_id']) : 0; $contactType = isset($params['contact_type']) ? intval($params['contact_type']) : 0; $usdtAddress = isset($params['usdt_address']) ? trim($params['usdt_address']) : ''; $txid = isset($params['txid']) ? trim($params['txid']) : ''; $ptOrderNo = isset($params['order_no']) ? trim($params['order_no']) : ''; $notifyUrl = isset($params['notify_url']) ? trim($params['notify_url']) : ''; $tradeType = $tradeType==3? $tradeType : 2; if ($userId <= 0 && $tradeType == 3) { $this->error = '1013'; return false; } if(empty($notifyUrl)){ $this->error = '6007'; return false; } if(empty($txid)){ $this->error = '6008'; return false; } if(empty($ptOrderNo)){ $this->error = '6006'; return false; } if($apiId<=0){ $this->error = '2209'; return false; } if(!in_array($contactType, [1,2])){ $this->error = '2209'; return false; } if(empty($usdtAddress)){ $this->error = '2235'; return false; } // 收款银行信息 $bankCard = isset($params['bank_card'])? $params['bank_card'] : ''; $bankName = isset($params['bank_name'])? $params['bank_name'] : ''; $realname = isset($params['realname'])? $params['realname'] : ''; if(empty($bankCard) || empty($bankName) || empty($realname)){ $this->error = '6009'; return false; } // 验证参数 $config = ConfigService::make()->getConfigOptionByGroup(5); $tradeOpen = isset($config['trade_usdt_open']) ? $config['trade_usdt_open'] : 0; $tradeMinNum = isset($config['trade_min']) ? $config['trade_min'] : 0; $tradeMaxNum = isset($config['trade_max']) ? $config['trade_max'] : 0; $tradePrice = isset($config['usdt_sell_price']) ? $config['usdt_sell_price'] : 0; $tradeLimitNum = isset($config['trade_no_catch']) ? $config['trade_no_catch'] : 0; // 是否开启交易 if ($tradeOpen != 1) { $this->error = '1013'; return false; } if ($tradePrice <= 0) { $this->error = '3002'; return false; } // 验证数量或金额 $total = moneyFormat($num * $tradePrice, 6); if ($num < $tradeMinNum || ($tradeMaxNum && $num > $tradeMaxNum)) { $this->error = '3003'; return false; } // 用户信息 if($tradeType == 3){ $userInfo = MemberService::make()->getInfo($userId); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; $idcardCheck = isset($userInfo['idcard_check']) ? $userInfo['idcard_check'] : 0; $username = isset($userInfo['username']) && $userInfo['username'] ? format_account($userInfo['username']) : ''; if ($status != 1) { $this->error = '2009'; return false; } if ($idcardCheck != 1) { $this->error = '2014'; return false; } } $idcardData = [ 'idcard' => isset($userInfo['idcard']) ? $userInfo['idcard'] : $params['idcard'], 'realname' => isset($userInfo['realname']) ? $userInfo['realname'] : $params['realname'], 'bank_name' => isset($params['bank_name']) ? $params['bank_name'] : $params['bank_name'], 'bank_card' => isset($params['bank_card']) ? $params['bank_card'] : $params['bank_card'], 'idcard_check' => isset($userInfo['idcard_check']) ? $userInfo['idcard_check'] : (($params['realname'] && $params['idcard'])? 1:2), 'idcard_front_img' => isset($userInfo['idcard_front_img']) ? $userInfo['idcard_front_img'] : '', 'idcard_back_img' => isset($userInfo['idcard_back_img']) ? $userInfo['idcard_back_img'] : '', 'idcard_hand_img' => isset($userInfo['idcard_hand_img']) ? $userInfo['idcard_hand_img'] : '', ]; $apiInfo = ApiService::make()->getInfo($apiId); $apiName = isset($apiInfo['account'])? $apiInfo['account'] : ''; if(empty($apiInfo)){ $this->error = '6005'; return false; } // 未处理订单 /*$noCatchOrder = $this->checkOrderNoCatch($userId, 2); if ($tradeLimitNum > 0 && $noCatchOrder >= $tradeLimitNum) { $this->error = lang(3005, ['num' => $tradeLimitNum]); return false; }*/ $paymentData = [ 'payment_id' => 0, 'type' => isset($params['type'])? intval($params['type']) : 1, 'logo' => isset($params['logo']) ? get_image_url($params['logo']) : '', 'real_name' => isset($params['realname'])? trim($params['realname']) : '', 'bank_name' => isset($params['bank_name'])? $params['bank_name'] : '', 'bank_card' => isset($params['bank_card'])? $params['bank_card'] : '', 'branch_name' => isset($params['branch_name'])? $params['branch_name'] : '', 'qrcode' => isset($params['qrcode']) && $params['qrcode'] ? get_image_url($params['qrcode']) : '', 'account' => isset($params['account'])? $params['account'] : '', ]; $orderNo = get_order_num('PS'); $data = [ 'user_id' => $userId, 'api_id' => $apiId, 'business_id' => 0, 'order_no' => $orderNo, 'txid' => $txid, 'type' => 2, 'source' => $apiName, 'usdt_address' => $usdtAddress, 'pt_order_no' => $ptOrderNo, 'notify_url' => $notifyUrl, 'contact_type' => $contactType, 'trade_type' => $tradeType==2? $tradeType : 3, 'pay_type' => isset($params['pay_type']) ? floatval($params['pay_type']) : 1, 'price' => $tradePrice, 'num' => $num, 'payment_id' => 0, 'idcard_data' => json_encode($idcardData, 256), 'payment_data' => json_encode($paymentData, 256), 'total' => $total, 'create_time' => time(), 'status' => 0, 'mark' => 1, ]; $this->model->startTrans(); if (!$order = $this->model->edit($data)) { $this->error = '3012'; $this->model->rollBack(); return false; } $this->model->commit(); $host = env('WEB_URL',''); $host = $host? $host : request()->header('HOST'); $token = isset($params['token'])? $params['token'] : ''; $url = $host.'/h5/#/pages/h5/confirm?order_no='.$data['order_no'].'&token='.$token; return ['token'=> $token, 'order_no'=> $data['order_no'],'url'=> $url]; } /** * 订单打款处理 * @param $userId 用户ID * @param $params 打款参数 * @return false */ public function pay($userId, $params) { $orderId = isset($params['id']) ? $params['id'] : 0; if ($orderId <= 0) { $this->error = '1013'; return false; } $orderInfo = $this->model->where(['id' => $orderId, 'mark' => 1, 'type' => 1]) ->whereIn('status', [1, 2, 5, 7]) ->select(['id', 'order_no','api_id','user_id', 'business_id', 'type','trade_type', 'payment_id', 'num', 'total', 'status']) ->first(); $type = isset($orderInfo['type']) ? $orderInfo['type'] : 0; $tradeType = isset($orderInfo['trade_type']) ? $orderInfo['trade_type'] : 0; $apiId = isset($orderInfo['api_id']) ? $orderInfo['api_id'] : 0; $orderUserId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0; if (empty($orderInfo)) { $this->error = '3016'; return false; } if($tradeType == 3 && ($userId<=0 || $orderUserId != $userId)){ $this->error = '6012'; return false; } if ($type != 1) { $this->error = '3024'; return false; } if(empty($apiId)){ $this->error = '6011'; return false; } // 用户信息 if($userId>0){ $userInfo = MemberService::make()->getInfo($userId); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; if ($status != 1) { $this->error = '2009'; return false; } } if($apiId>0){ $apiInfo = ApiService::make()->getInfo($apiId); if (empty($apiInfo)) { $this->error = '6011'; return false; } } $data = [ 'status' => 3, 'pay_type' => $params['pay_type'], 'pay_img' => $params['pay_img'], 'pay_remark' => $params['pay_remark'], 'pay_time' => time(), ]; if (!$this->model->where(['user_id' => $userId, 'id' => $orderId, 'mark' => 1])->update($data)) { $this->error = '3018'; return false; } return true; } /** * 订单确认处理 * @param $userId 用户ID * @param $params 打款参数 * @return false */ public function collection($userId, $params) { $orderId = isset($params['id']) ? $params['id'] : 0; if ($orderId <= 0) { $this->error = '1013'; return false; } $orderInfo = $this->model->where(['user_id' => $userId, 'id' => $orderId, 'mark' => 1, 'type' => 2]) ->select(['id', 'user_id', 'order_no', 'business_id', 'payment_id', 'type', 'num', 'total', 'status']) ->first(); $businessId = isset($orderInfo['business_id']) ? $orderInfo['business_id'] : 0; $tradeType = isset($orderInfo['type']) ? $orderInfo['type'] : 0; if (empty($orderInfo) || empty($businessId)) { $this->error = '3016'; return false; } if ($orderInfo['status'] != 3) { $this->error = '3026'; return false; } if ($tradeType != 2) { $this->error = '3024'; return false; } $this->model->startTrans(); // 订单状态更新 if (!$this->model->where(['user_id' => $userId, 'id' => $orderId, 'mark' => 1])->update(['status' => 4, 'update_time' => time()])) { $this->model->rollBack(); $this->error = '3023'; return false; } // 交易处理 if ($orderInfo['num'] > 0) { $info = $this->memberModel->where(['id' => $businessId, 'status' => 1, 'mark' => 1])->select(['id', 'username','usdt_num', 'user_type'])->first(); if (empty($info)) { $this->model->rollBack(); $this->error = '3019'; return false; } // 商家进币 if (!$this->memberModel->where(['id' => $businessId, 'mark' => 1])->increment('usdt_num', $orderInfo['num'])) { $this->model->rollBack(); $this->error = '3019'; return false; } // 明细处理 $data = [ 'order_no' => $orderInfo['order_no'], 'user_id' => $businessId, 'type' => 1, 'pay_type' => 1, 'change_type' => 1, 'num' => $orderInfo['num'], 'total' => $orderInfo['total'], 'balance' => floatval($info['usdt_num'] + $orderInfo['num']), 'create_time' => time(), 'remark' => '交易员买入', 'status' => 1, 'mark' => 1, ]; if (!$this->capitalModel->edit($data)) { $this->error = '3014'; $this->model->rollBack(); return false; } } $this->model->commit(); return true; } /** * 取消订单 * @param $userId * @param $params * @return false */ public function cancel($userId, $params) { $orderId = isset($params['id']) ? intval($params['id']) : 0; if ($orderId <= 0) { $this->error = '1013'; return false; } $orderInfo = $this->model->where(['user_id' => $userId, 'id' => $orderId, 'mark' => 1]) ->select(['id', 'order_no', 'business_id', 'type', 'num', 'total', 'status']) ->first(); $tradeType = isset($orderInfo['type']) ? $orderInfo['type'] : 0; $businessId = isset($orderInfo['business_id']) ? $orderInfo['business_id'] : 0; if (empty($orderInfo) || $businessId<=0) { $this->error = '3016'; return false; } if ($orderInfo['status'] == 3) { $this->error = '3027'; return false; } if ($orderInfo['status'] == 4) { $this->error = '3028'; return false; } if ($orderInfo['status'] == 7) { $this->error = '3030'; return false; } if (!in_array($orderInfo['status'], [1, 2])) { $this->error = '3029'; return false; } $this->model->startTrans(); // 订单状态更新 $updateData = ['status' => 8, 'update_time' => time(), 'exception_remark' => '客户取消']; if (!$this->model->where(['user_id' => $userId, 'id' => $orderId, 'mark' => 1])->update($updateData)) { $this->model->rollBack(); $this->error = '3023'; return false; } // 出售订单,USDT退回 if ($tradeType == 2 && $orderInfo['num']>0) { $info = $this->memberModel->where(['id' => $userId, 'status' => 1, 'mark' => 1])->select(['id', 'username', 'usdt_num', 'user_type'])->first(); if (empty($info)) { $this->model->rollBack(); $this->error = '3019'; return false; } // 退还币给客户 if (!$this->memberModel->where(['id' => $userId, 'mark' => 1])->increment('usdt_num', $orderInfo['num'])) { $this->model->rollBack(); $this->error = '3019'; return false; } // 明细处理 $data = [ 'order_no' => $orderInfo['order_no'], 'user_id' => $userId, 'type' => 3, 'pay_type' => 1, 'change_type' => 1, 'num' => $orderInfo['num'], 'total' => $orderInfo['total'], 'balance' => floatval($info['usdt_num'] + $orderInfo['num']), 'create_time' => time(), 'update_time' => time(), 'remark' => '客户取消退还', 'status' => 1, 'mark' => 1, ]; if (!$this->capitalModel->edit($data)) { $this->error = '3014'; $this->model->rollBack(); return false; } } // 买入取消 else if($tradeType == 1 && $orderInfo['num']>0){ $info = $this->memberModel->where(['id' => $businessId, 'status' => 1, 'mark' => 1])->select(['id', 'username', 'usdt_num', 'user_type'])->first(); if (empty($info)) { $this->model->rollBack(); $this->error = '3019'; return false; } // 退还币给客户 if (!$this->memberModel->where(['id' => $businessId, 'mark' => 1])->increment('usdt_num', $orderInfo['num'])) { $this->model->rollBack(); $this->error = '3019'; return false; } // 明细处理 $data = [ 'order_no' => $orderInfo['order_no'], 'user_id' => $businessId, 'type' => 3, 'pay_type' => 1, 'change_type' => 1, 'num' => $orderInfo['num'], 'total' => $orderInfo['total'], 'balance' => floatval($info['usdt_num'] + $orderInfo['num']), 'create_time' => time(), 'update_time' => time(), 'remark' => '客户取消退还', 'status' => 1, 'mark' => 1, ]; if (!$this->capitalModel->edit($data)) { $this->error = '3014'; $this->model->rollBack(); return false; } } $this->model->commit(); return true; } /** * 回调通知 * @param $notifyUrl * @param $data * @return bool */ public function notify($notifyUrl, $data) { if(empty($notifyUrl) || empty($data)){ return false; } $orderNo = isset($data['transaction_id'])? $data['transaction_id'] : ''; $cacheKey = "caches:notify:no_{$orderNo}"; if(RedisService::get($cacheKey.'_lock')){ return false; } RedisService::set($cacheKey.'_lock', ['url'=> $notifyUrl,'data'=> $data], rand(3, 5)); $result = curl_api($notifyUrl, $data,[], 10); RedisService::set($cacheKey, ['url'=> $notifyUrl,'data'=> $data,'result'=> $result], 7200); return true; } }