'wxpay', 2=>'alipay', 3=>'balancePay', 14=>'huifuPay', 15=>'sqzpay', 16=>'sqzAliPay', 17=>'sqzWxPay', 18=>'sqzYljk', 19=>'usdtPay', 20=>'yswkPay', 22=>'dkpay', 56=>'ysftyPay', 66=>'dkysf', ]; protected $model = null; public function __construct() { $this->model = new PaymentModel(); } /** * 静态化入口 * @return static|null */ public static function make() { if(!self::$instance){ self::$instance = new static(); } return self::$instance; } /** * 获取支付方式标识 * @param $payType 支付类型 * @return string */ public function getPayCode($payType) { return isset($this->payWayArr[$payType])? $this->payWayArr[$payType] : 'defpay'; } /** * 按状态获取支付单数量 * @param $uid * @param $orderType * @param $state * @param int $time 时间/小时,默认2小时 * @return array|mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getPaymentCountByState($uid, $orderSn='', $orderType, $state, $time = 2) { $cacheKey = "caches:paymentCall:u{$uid}_ot{$orderType}_s{$state}_{$time}_{$orderSn}"; $data = RedisCache::get($cacheKey); if($data){ return $data; } $where = []; if($orderType){ $where['order_type'] = $orderType; } if($state){ $where['state'] = $state; } $data = $this->model->where($where)->where(function ($query) use($time,$orderSn){ if($time>0){ $query->where('creat_at','>=', time() - $time * 3600); } if($orderSn){ $query->where('remarks',$orderSn); } })->count('id'); if($data){ RedisCache::set($cacheKey, $data, rand(3,5)); } return $data; } /** * 验证订单是否已支付 * @param $uid * @param $orderSn * @return array|mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function checkPaymentState($uid, $orderSn) { $cacheKey = "caches:paymentState:u{$uid}_sn{$orderSn}"; $data = RedisCache::get($cacheKey); if($data){ return $data; } $data = $this->model->where(['state'=> 6])->where(function ($query) use($orderSn){ if($orderSn){ $query->where('remarks', $orderSn); } })->value('id'); if($data){ RedisCache::set($cacheKey, $data, rand(2,3)); } return $data; } /** * 获取支付信息(有缓存) * @param $outTradeNo * @param int $state * @param string $field * @param false $cache * @return array|mixed */ public function getCacheInfo($outTradeNo, $state=7, $field='', $cache = false) { $cacheKey = "caches:payment:info:otn{$outTradeNo}_{$state}".($field? '_'.md5($field):''); $data = RedisCache::get($cacheKey); if($data && $cache){ return $data; } $where = ['out_trade_no'=> $outTradeNo]; if($state){ $where['state'] = $state; } $field = $field? $field : 'id,out_trade_no,uid,total_fee,state,trade_type,out_trade_no1,hy_token_id,syl_sureorderid,hy_bill_no,is_retreat,pay_way,order_type,sid,remarks,trade_no'; $data = $this->model->where($where) ->field($field) ->order('creat_at desc') ->findOrEmpty(); if($data && $cache){ RedisCache::set($cacheKey, $data, rand(5,10)); } return $data; } /** * 支付回调处理 * @param $outTradeNo * @param $payMoney * @param $payType * @param $content * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function payBack($outTradeNo, $payMoney, $payType, $content) { $nowTime = date('Y-m-d H:i:s'); $params = $content? json_decode($content, true):[]; $payCode = PaymentService::make()->getPayCode($payType); $cacheKey = "caches:payNotify:{$payCode}:otn_{$outTradeNo}:"; RedisCache::set($cacheKey.'catch', ['params'=>$params,'date'=> $nowTime], $this->cacheTime); // 验证支付请求信息 $payInfo = PaymentService::make()->getCacheInfo($outTradeNo, 0); $payId = isset($payInfo['id'])? $payInfo['id']:0; $payUid = isset($payInfo['uid'])? $payInfo['uid']:0; $payState = isset($payInfo['state'])? intval($payInfo['state']):0; $totalFee = isset($payInfo['total_fee'])? floatval($payInfo['total_fee']):0; $orderSn = isset($payInfo['remarks'])? trim($payInfo['remarks']):''; $orderType = isset($payInfo['order_type'])? intval($payInfo['order_type']) : 0; if (!$payInfo || $payUid<=0 || empty($orderSn) || $payState!= 7) { $error = empty($payInfo) || !$payId || empty($orderSn)? "单号{$orderSn}支付信息不存在或参数错误":"单号{$orderSn}已经回调支付"; $logData = ['params'=>$params,'payInfo'=>$payInfo,'msg'=> $error,'date'=> $nowTime]; RedisCache::set($cacheKey.'error', $logData, $this->cacheTime); sr_throw($error); } // 验证支付金额 if($payMoney < $totalFee || $totalFee<=0){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'msg'=> "单号{$orderSn}支付金额错误",'date'=> $nowTime]; RedisCache::set($cacheKey.'error', $logData, $this->cacheTime); sr_throw("单号{$orderSn}支付金额错误"); } // 更新支付状态 if(!PaymentModel::where('id', $payId)->update(['state' => 6, 'pay_at' => $nowTime])){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'msg'=> "单号{$orderSn}更新支付状态失败",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("单号{$orderSn}更新支付状态失败"); } // 第三方回调数据 $data = [ 'out_order_no' => $outTradeNo, 'content' => $content, 'create_time' => sr_getcurtime(time()), 'type' => $payType, 'uid' => $payUid, 'money' => $payMoney ]; if(!ThirdpayBackModel::insertGetid($data)){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'third'=>$data,'msg'=> "单号{$orderSn}处理第三方回调数据错误",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("单号{$orderSn}处理第三方回调数据错误"); } /* TODO 服务商订单处理 */ if ($orderType == 6) { // 获取验证订单信息 $orderInfo = ServiceOrderService::make()->getInfoBySn($orderSn, $payUid); $orderId = isset($orderInfo['order_id'])? $orderInfo['order_id'] : 0; $orderMoney = isset($orderInfo['payment'])? floatval($orderInfo['payment']) : 0; $orderStatus = isset($orderInfo['status'])? intval($orderInfo['status']) : 0; if(empty($orderInfo) || $orderId<=0 || $orderMoney<=0){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'msg'=> "服务商订单{$orderSn}不存在或参数错误",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("服务商订单{$orderSn}不存在或参数错误"); } // 验证订单状态 if($orderStatus != 1){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'msg'=> "服务商订单{$orderSn}订单已处理",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("服务商订单{$orderSn}订单已处理"); } // 更新订单状态 if(!ServicesOrderModel::where('order_id', $orderId)->update(['status' => 2, 'pay_type' => $payType, 'updated_time' => $nowTime])){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'msg'=> "服务商订单{$orderSn}更新状态错误",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("服务商订单{$orderSn}更新状态错误"); } // 更新用户服务商有效期 $date = sr_getcurtime(time(), 'Y-m-d'); $expireDay = date('Y-m-d', strtotime("$date +1 month")); if(!UserModel::where('id', $payUid)->update(['store_type' => 1,'store_expire_time' => $expireDay,'update_time'=>time()])){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'storeExpire'=>$expireDay,'msg'=> "服务商订单{$orderSn}更新用户服务商有效期错误",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("服务商订单{$orderSn}更新用户服务商有效期错误"); } $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'storeExpire'=>$expireDay,'msg'=> "服务商订单{$orderSn}支付回调处理成功",'date'=> $nowTime]; RedisCache::set($cacheKey."success_{$orderSn}", $logData, $this->cacheTime); } /** TODO 商城订单处理 **/ elseif ($orderType == 4) { // 获取验证订单信息 $orderInfo = ShopOrderService::make()->getInfoBySn($orderSn, $payUid); $orderId = isset($orderInfo['order_id'])? $orderInfo['order_id'] : 0; $orderMoney = isset($orderInfo['payment'])? floatval($orderInfo['payment']) : 0; $orderStatus = isset($orderInfo['status'])? intval($orderInfo['status']) : -1; if(empty($orderInfo) || $orderId<=0 || $orderMoney<=0){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}不存在或参数错误",'date'=> $nowTime]; RedisCache::set($cacheKey."error_{$orderSn}", $logData, $this->cacheTime); sr_throw("商城订单{$orderSn}不存在或参数错误"); } // 验证订单状态 if($orderStatus != 0){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}订单已处理",'date'=> $nowTime]; RedisCache::set($cacheKey."error_{$orderSn}", $logData, $this->cacheTime); sr_throw("商城订单{$orderSn}订单已处理"); } // 更新订单状态 if(!ShopOrderModel::where('order_id', $orderId)->update(['status' => 1, 'pay_type' => $payType, 'updated_time' => $nowTime])){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'order'=>$orderInfo,'msg'=> "服务商订单{$orderSn}更新状态错误",'date'=> $nowTime]; RedisCache::set($cacheKey.'_error', $logData, $this->cacheTime); sr_throw("服务商订单{$orderSn}更新状态错误"); } // 增加订单商品销量 $updateSale = ShopOrderModel::alias('a') ->leftJoin('shop_order_goods og', 'og.order_id=a.order_id') ->leftJoin('shop_goods g', 'g.goods_id=og.goods_id') ->where(['a.order_id' => $orderId, 'a.user_id' => $payUid]) ->update([ 'g.sales_volume' => Db::raw('g.sales_volume + og.num'), 'g.real_sales_volume' => Db::raw('g.real_sales_volume + og.num'), ]); if (!$updateSale) { Db::rollback(); $logData = ['params' => $params, 'orderInfo' => $orderInfo, 'payInfo' => $payInfo, 'error' => "商城订单{$orderSn}更新商品销量失败", 'date' => $date]; RedisCache::set($cacheKey . "error_{$orderSn}", $logData, 7200); sr_throw("商城订单{$orderSn}更新商品销量失败"); } // 更新用户交易额(消费) $userInfo = UserService::make()->getCacheInfo($payUid,'id,mobile,score,money,path', false); $upperPath = isset($userInfo['path'])? $userInfo['path'] : ''; if($userInfo && !UserModel::where('id', $payUid)->inc('total_income', $totalFee)->inc('total_team_income',$totalFee)->update()){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'user'=>$userInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}更新用户交易数据错误",'date'=> $nowTime]; RedisCache::set($cacheKey."error_{$orderSn}", $logData, $this->cacheTime); sr_throw("商城订单{$orderSn}更新用户交易数据错误"); } // 更新团队交易额数据 if($upperPath && !UserModel::whereIn('id', explode(',', $upperPath))->inc('total_team_income',$totalFee)->update()){ $logData = ['params'=>$params,'payInfo'=>$payInfo,'user'=>$userInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}更新用户上级交易数据错误",'date'=> $nowTime]; RedisCache::set($cacheKey."error_{$orderSn}", $logData, $this->cacheTime); sr_throw("商城订单{$orderSn}更新用户上级交易数据错误"); } // 赠送积分处理 $rebateScore = isset($orderInfo['rebate_score']) ? floatval($orderInfo['rebate_score']) : 0; if ($rebateScore > 0 && $userInfo) { // 更新用户账户积分 if (!UserModel::where('id', $payUid)->inc('score', $rebateScore)->update()) { $logData = ['params'=>$params,'payInfo'=>$payInfo,'user'=>$userInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}赠送积分处理错误",'date'=> $nowTime]; RedisCache::set($cacheKey."error_{$orderSn}", $logData, $this->cacheTime); sr_throw("商城订单{$orderSn}赠送积分处理错误"); } // 处理积分流水明细 $userScore = isset($userInfo['score']) ? floatval($userInfo['score']) : 0; $data = [ 'uid' => $payUid, 'type' => 3, 'score' => $rebateScore, 'create_at' => sr_getcurtime(time()), 'state' => 12, 'before_score' => $userScore, 'after_score' => floatval($userScore + $rebateScore), 'from_id' => $payId, 'uid2' => 0 ]; if (!ScoreLogModel::insertGetId($data)) { $logData = ['params'=>$params,'payInfo'=>$payInfo,'user'=>$userInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}赠送积分明细处理错误",'date'=> $nowTime]; RedisCache::set($cacheKey."error_{$orderSn}", $logData, $this->cacheTime); sr_throw("商城订单{$orderSn}赠送积分明细处理错误"); } } $logData = ['params'=>$params,'payInfo'=>$payInfo,'user'=>$userInfo,'order'=>$orderInfo,'msg'=> "商城订单{$orderSn}回调处理成功",'date'=> $nowTime]; RedisCache::set($cacheKey."success_{$orderSn}", $logData, $this->cacheTime); } return true; } }