| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- <?php
- namespace app\common\service;
- use app\common\model\PaymentModel;
- use app\common\model\ScoreLogModel;
- use app\common\model\ServicesOrderModel;
- use app\common\model\ShopGoodsModel;
- use app\common\model\ShopOrderGoodsModel as OrderGoods;
- use app\common\model\ShopOrderModel;
- use app\common\model\ThirdpayBackModel;
- use app\common\model\UserModel;
- use think\facade\Db;
- use utils\RedisCache;
- /**
- * 支付服务 by wes
- * Class PaymentService
- * @package app\common\service
- */
- class PaymentService
- {
- protected static $instance = null;
- protected $cacheTime = 7200;
- protected $payWayArr = [
- 1=>'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;
- }
- }
|