'; exit; } /** * 处理订单 * @param $outTradeNo 订单号 * @param array $notifyData 回调数据 * @return bool */ public static function catchOrder($outTradeNo, $notifyData=[]){ Db::startTrans(); // 更新订单支付状态信息 $payMoney = isset($notifyData['total_fee'])? moneyFormat($notifyData['total_fee']): 0; $orderPayMoney = moneyFormat($payMoney/100); $orderInfo = Books::getInfo(['order_sn'=> $outTradeNo]); PRedis::set('orders:books:info_'.$outTradeNo, ['order'=> $orderInfo,'notify'=> $notifyData], 600); $userId = isset($orderInfo['uid'])? intval($orderInfo['uid']) : 0; if(empty($userId)){ return false; } $bookAt = time(); $updateData = [ 'pay_type'=> isset($notifyData['pay_type'])? intval($notifyData['pay_type']) : 1, 'transaction_id'=> isset($notifyData['transaction_id'])? $notifyData['transaction_id'] : '', 'status'=> 2, 'book_at'=> date('Y-m-d H:i:s', $bookAt), ]; PRedis::set('orders:books:update_'.$outTradeNo, ['order'=> $updateData,'notify'=> $notifyData], 600); $res = Books::saveData(['order_sn'=> $outTradeNo], $updateData); if(!$res){ PRedis::set('orders:books:error_'.$outTradeNo, ['order'=> $updateData,'notify'=> $notifyData,'error'=> '更新订单支付数据失败'], 600); Db::rollback(); return false; } // 账户明细 $memberInfo = Member::getInfo(['id'=> $userId],'id,openid,redheart,user_nickname,real_name'); $redheart = isset($memberInfo['redheart'])? intval($memberInfo['redheart']) : 0; $accountData = [ 'type' => 2, 'account_type' => 4, 'change_type' => 2, 'user_id' => $userId, 'money' => moneyFormat($orderPayMoney, 2), 'balance' => $redheart, 'created_at' => date('Y-m-d H:i:s'), 'remark' => "微信支付活动报名:单号[{$outTradeNo}],活动:{$orderInfo['aid']},金额" . $orderPayMoney, ]; PRedis::set('payments:books:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600); AccountLog::insertGetId($accountData); Db::commit(); // 发送报名提交成功消息 $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : ''; $nickname = isset($memberInfo['user_nickname']) ? $memberInfo['user_nickname'] : ''; $bookNo = isset($orderInfo['book_num'])? trim($orderInfo['book_num']) : '无'; $money = isset($orderInfo['money'])? floatval($orderInfo['money']) : 0; $credit = isset($orderInfo['credit'])? floatval($orderInfo['credit']) : 0; $bookStatus = Books::where(['order_sn'=> $outTradeNo])->value('status'); if($bookStatus != 2){ return false; } if($openid) { $aid = isset($orderInfo['aid'])? intval($orderInfo['aid']) : 0; $activityInfo = Activity::where(['id'=> $aid]) ->field('id,starttime,title,address') ->find(); $title = isset($activityInfo['title'])? trim($activityInfo['title']) : '无'; $address = isset($activityInfo['address'])? trim($activityInfo['address']) : '无'; $bookAt = $bookAt? date('Y.m.d H:i', $bookAt) : date('Y.m.d H:i'); $params = [ 'title' => "我们已经收到您的报名,稍后会进行审核,请留意后续的通知哦!\n\n姓名:\t{$nickname}(昵称)\n\n支付单号:\t{$outTradeNo}\n\n支付金额:\t{$orderPayMoney}", 'remark' => "转发积姻缘,把活动分享给身边的朋友,一起来脱单哦!", 'type' => 'book', 'keywords' => [ 'keyword1' => [ 'value' => $title, 'color' => '#173177', ], 'keyword2' => [ 'value' => $bookAt, 'color' => '#173177', ], 'keyword3' => [ 'value' => '待审核', 'color' => '#173177', ], 'keyword4' => [ 'value' => "活动费用{$money}元,活动守时金{$credit}元。", 'color' => '#173177', ], ], 'url' => url('/weixin/activity/bookdetail?id='.$aid, '', '', true), ]; PRedis::set('payments:books:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600); Wechat::sendTplMsg($openid, $params); } return true; } /** * 充值结果处理 * @param $outTradeNo * @param array $notifyData * @return bool * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException * @throws \think\exception\PDOException */ public static function catchRechargeOrder($outTradeNo, $notifyData=[]){ try { db()->startTrans(); // 更新订单支付状态信息 $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0; $orderPayMoney = moneyFormat($payMoney / 100); $orderInfo = db('user_recharge_log') ->where(['order_sn' => $outTradeNo]) ->field('money,pay_money,give_num,user_id,source_id,order_sn') ->find(); $orderSn = isset($orderInfo['order_sn']) ? $orderInfo['order_sn'] : ''; $userId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0; $num = isset($orderInfo['money']) ? $orderInfo['money'] : 0; $giveNum = isset($orderInfo['give_num']) ? $orderInfo['give_num'] : 0; $updateData = [ 'pay_money' => $orderPayMoney, 'transaction_id' => isset($notifyData['transaction_id']) ? $notifyData['transaction_id'] : '', 'status' => 2, 'pay_at' => date('Y-m-d H:i:s'), ]; PRedis::set('payments:redheart:catchOrder_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600); $res = db('user_recharge_log')->where(['order_sn' => $outTradeNo])->update($updateData); if (!$res) { PRedis::set('payments:redheart:updateError_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600); db()->rollback(); return false; } // 更新账户 if ($userId && $num > 0) { $memberInfo = Member::where(['id' => $userId])->field('openid,redheart')->find(); $redheart = isset($memberInfo['redheart']) ? intval($memberInfo['redheart']) : 0; $data = ['updated_at' => date('Y-m-d H:i:s'), 'redheart' => intval($redheart + intval($num+$giveNum))]; PRedis::set('payments:redheart:update_account' . $outTradeNo, ['notify' => $notifyData, 'update' => $data], 600); if (!Member::where(['id' => $userId])->update($data)) { db()->rollback(); return false; } $accountData = [ 'type' => 1, 'account_type' => 1, 'change_type' => 1, 'user_id' => $userId, 'money' => intval($num+$giveNum), 'balance' => $redheart, 'created_at' => date('Y-m-d H:i:s'), 'remark' => "微信支付爱心充值:单号[{$outTradeNo}],数量{$num}".($giveNum? ",赠送{$giveNum}":'').",金额" . $orderPayMoney, ]; PRedis::set('payments:redheart:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600); db('account_log')->insertGetId($accountData); // 发送充值成功消息 $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : ''; if($openid) { $params = [ 'title' => "恭喜您充值成功", 'remark' => "感谢您的使用,点击详情查看充值明细", 'type' => 'redheart', 'keywords' => [ 'keyword1' => [ 'value' => moneyFormat($orderPayMoney, 2), 'color' => '#173177', ], 'keyword2' => [ 'value' => date('Y.m.d H:i'), 'color' => '#173177', ], 'keyword3' => [ 'value' => '微信支付', 'color' => '#173177', ], ], 'url' => url('/weixin/account/index', '', '', true), ]; PRedis::set('payments:redheart:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600); Wechat::sendTplMsg($openid, $params); } } // 操作日志 UserLog::saveLog(['user_id' => $userId, 'type' => 2, 'content' => "充值爱心:{$num}个"]); db()->commit(); // 分销收益结算 $inviteInfo = MemberModel::getInviteInfo($userId); $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0; if($inviteInfo && $inviteId>0){ PRedis::set('markets:recharge:entry' . $outTradeNo, ['notify' => $notifyData, 'inviteInfo'=> $inviteInfo, 'params' => $params], 7200); Award::marketAward($inviteId, $userId, 8, $orderPayMoney); } return true; } catch (\Exception $exception){ PRedis::set('payments:redheart:error:'.$outTradeNo, $exception, 600); db()->rollback(); return false; } } /** * 微信支付 * @param $orderId 订单ID * @param $orderInfo 订单信息 * @param array $userInfo 用户信息 * @return array */ public static function wechatPay($orderId, $orderInfo, $userInfo=[]){ $prepayId = isset($orderInfo['prepay_id']) ? trim($orderInfo['prepay_id']) : ''; $orderStatus = isset($orderInfo['status']) ? trim($orderInfo['status']) : 0; $userId = isset($userInfo['id']) ? intval($userInfo['id']) : 0; if($orderStatus != 1){ return 5007; } $orderSn = isset($orderInfo['order_sn'])? $orderInfo['order_sn'] : ''; if(empty($orderSn)){ return 1012; } $orderSn = isset($orderInfo['order_sn'])? $orderInfo['order_sn'] : ''; if(empty($orderSn)){ showJson(1004, 1012); } // 支付金额 $orderMoney = isset($orderInfo['money']) ? moneyFormat($orderInfo['money']) : 0.00; $credit = isset($orderInfo['credit']) ? moneyFormat($orderInfo['credit']) : 0.00; $orderAmount = moneyFormat($orderMoney + $credit); if ($orderMoney <= 0) { return 5008; } if ($prepayId && $orderStatus == 1) { // 查询订单状态 $queryResult = Wechat::queryOrder($orderSn); PRedis::set('payments:books:queryOrder_'.$orderSn, $queryResult, 600); if ($queryResult && Payment::catchOrder($orderInfo['order_sn'], $queryResult)) { return 5009; } else { $orderSn = makeTradeNo('BK', $userId); $saveData = ['order_sn' => $orderSn, 'remark' => '订单重新发起支付,原单号:' . $orderInfo['order_sn']]; PRedis::set('payments:books:makeSn_'.$orderInfo['order_sn'], $saveData); Books::saveData(['id' => $orderId], $saveData); } } // 获取OPENID $openid = session('openid'); if (empty($openid)) { $openid = Member::where(['id' => $userId])->value('openid'); } $order = [ 'orderNo' => $orderSn, 'amount' => $orderAmount, 'openid' => $openid, 'body' => '报名订单支付', ]; $params = Wechat::jsapiUnifiedorder($order); PRedis::set('payments:books:payParams_'.$orderSn,['order'=> $order, 'params'=> $params,'date'=> date('Y-m-d H:i:s')], 600); $code = isset($params['code']) ? $params['code'] : ''; if ($code == 'error') { return $params['message']; } // 更新订单参数 $prepayId = isset($params['prepay_id'])? $params['prepay_id'] : ''; Books::saveData(['id' => $orderId], ['prepay_id' => $prepayId]); unset($params['prepay_id']); return $params; } /** * VIP套餐支付处理 * @param $outTradeNo * @param $notifyData * @param $taskNo * @return bool|string * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException * @throws \think\exception\PDOException */ public static function catchVip($outTradeNo, $notifyData, $taskNo){ // 验证订单是否存在 $where = ['order_sn' => $outTradeNo, 'type'=> 4]; $orderInfo = db('user_recharge_log') ->field('money,pay_money,user_id,order_sn,status') ->where($where) ->find(); if(empty($orderInfo)){ PRedis::set('payments:vip:errorMoney_'.$taskNo, ['result'=> $notifyData, 'error'=> $outTradeNo.'订单不存在'], 600); return false; } // 订单已处理 PRedis::set('payments:vip:order_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo], 3600); $orderStatus = isset($orderInfo['status']) ? intval($orderInfo['status']) : 0; // 验证订单状态是否可处理 if ($orderStatus != 1) { db('user_recharge_log')->where($where)->update(['remark'=> '订单已处理']); Payment::rebackOk(); return true; } // 验证订单金额是否正确 $payDebug = config('weixin.payDebug'); $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0; $orderMoney = isset($orderInfo['pay_money']) ? moneyFormat($orderInfo['pay_money']) : 0.00; if (!$payDebug && $orderMoney * 100 != $payMoney) { $error = ['remark'=> "订单金额错误:\n支付金额:" . $payMoney . "\n订单金额:" . $orderMoney]; PRedis::set('payments:vip:errorMoney_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo,'error'=> $error], 600); db('user_recharge_log')->where($where)->update($error); return '支付金额错误'; } try { db()->startTrans(); // 更新订单支付状态信息 $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0; $orderPayMoney = moneyFormat($payMoney / 100); $userId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0; $num = isset($orderInfo['money']) ? $orderInfo['money'] : 0; $updateData = [ 'pay_money' => $orderPayMoney, 'transaction_id' => isset($notifyData['transaction_id']) ? $notifyData['transaction_id'] : '', 'status' => 2, 'pay_at' => date('Y-m-d H:i:s'), ]; PRedis::set('payments:vip:catchOrder_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 3600); $res = db('user_recharge_log')->where($where)->update($updateData); if (!$res) { PRedis::set('payments:vip:updateError_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 3600); db()->rollback(); return false; } // 更新账户 if ($userId && $num > 0) { $dateTime = strtotime(date('Y-m-d 00:00:00')); $memberInfo = Member::where(['id' => $userId])->field('openid,vip_auth,user_nickname,vip_expire')->find(); $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0; $vipExpire = isset($memberInfo['vip_expire']) && !empty($memberInfo['vip_expire'])? intval($memberInfo['vip_expire']) : 0; $newVipExpire = $vipExpire>$dateTime && $vipAuth? $vipExpire + $num*30*24*3600+86400 : $dateTime+$num*30*24*3600+86400; if($newVipExpire - time() > 200*24*3600){ $siteInfo = cmf_get_site_info(); $customOpenid = isset($siteInfo['custom_openid'])? trim($siteInfo['custom_openid']) : ''; if($customOpenid){ $params = [ 'title' => '用户'.$memberInfo['user_nickname']."购买VIP成功,由于到期时间超过6个月,请留意\n\n购买时长:\t{$num}个月\n续费前时间:\t".date('Y.m.d',$vipExpire)."\n"."到期时间:\t".date('Y.m.d',$newVipExpire)."\n", 'remark' => "请到后台留意查看该用户购买或续费是否正常", 'type' => 'pay', 'keywords' => [ 'keyword1' => [ 'value' => moneyFormat($orderPayMoney, 2), 'color' => '#173177', ], 'keyword2' => [ 'value' => date('Y.m.d H:i'), 'color' => '#173177', ], ], 'url' => '', ]; PRedis::set('payments:custom:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 3600); Wechat::sendTplMsg($customOpenid, $params); } } $data = ['vip_time'=> date('Y-m-d H:i:s'), 'vip_auth'=> 1, 'vip_expire' => $newVipExpire]; PRedis::set("accounts:vipUpdate:{$userId}_".$outTradeNo, ['data'=> $data,'info'=> $memberInfo,'new'=> $newVipExpire], 20 * 24 * 3600); if (!Member::where(['id' => $userId])->update($data)) { db()->rollback(); return false; } $num = intval($num); $accountData = [ 'type' => 6, 'account_type' => 4, 'change_type' => 1, 'user_id' => $userId, 'money' => $orderPayMoney, 'balance' => 0, 'created_at' => date('Y-m-d H:i:s'), 'remark' => "购买VIP:单号[{$outTradeNo}],时长{$num}个月,支付金额" . $orderPayMoney, ]; PRedis::set('payments:vip:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600); db('account_log')->insertGetId($accountData); // 发送充值成功消息 $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : ''; if($openid) { $monthTxt = $num ==6? '半年' : ($num == 12? '一年' : $num.'个月'); $params = [ 'title' => "恭喜您购买{$monthTxt}VIP成功\n\n到期时间:\t".date('Y.m.d',$newVipExpire).'到期', 'remark' => "感谢您的使用,点击详情查看购买明细", 'type' => 'pay', 'keywords' => [ 'keyword1' => [ 'value' => moneyFormat($orderPayMoney, 2), 'color' => '#173177', ], 'keyword2' => [ 'value' => date('Y.m.d H:i'), 'color' => '#173177', ], ], 'url' => url('/weixin/account/index', '', '', true), ]; PRedis::set('payments:vip:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 3600); Wechat::sendTplMsg($openid, $params); } } // 提交 db()->commit(); // 操作日志 UserLog::saveLog(['user_id' => $userId, 'type' => 3, 'content' => "购买VIP:{$num}个月,支付金额:{$orderPayMoney},原到期时间:{$vipExpire}"]); // 分销收益结算 $inviteInfo = MemberModel::getInviteInfo($userId); $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0; if($inviteInfo && $inviteId>0){ PRedis::set('markets:vip:entry' . $outTradeNo, ['notify' => $notifyData, 'inviteInfo'=> $inviteInfo, 'params' => $params], 7200); Award::marketAward($inviteId, $userId, 2, $orderPayMoney); } Payment::rebackOk(); return true; } catch (\Exception $exception){ PRedis::set('payments:vip:error:'.$outTradeNo, $exception, 3600); db()->rollback(); return $exception->getMessage(); } } /** * 人工牵线支付处理 * @param $outTradeNo * @param $notifyData * @param $taskNo * @return bool|string * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException * @throws \think\exception\PDOException */ public static function catchHand($outTradeNo, $notifyData, $taskNo){ // 验证订单是否存在 $where = ['order_sn' => $outTradeNo, 'type'=> 5]; $orderInfo = db('user_recharge_log') ->field('money,pay_money,user_id,order_sn,status') ->where($where) ->find(); if(empty($orderInfo)){ PRedis::set('payments:hand:errorMoney_'.$taskNo, ['result'=> $notifyData, 'error'=> $outTradeNo.'订单不存在'], 600); return false; } // 订单已处理 PRedis::set('payments:hand:order_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo], 600); $orderStatus = isset($orderInfo['status']) ? intval($orderInfo['status']) : 0; // 验证订单状态是否可处理 if ($orderStatus != 1) { db('user_recharge_log')->where($where)->update(['remark'=> '订单已处理']); Payment::rebackOk(); return true; } // 验证订单金额是否正确 $payDebug = config('weixin.payDebug'); $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0; $orderMoney = isset($orderInfo['pay_money']) ? moneyFormat($orderInfo['pay_money']) : 0.00; if (!$payDebug && $orderMoney * 100 != $payMoney) { $error = ['remark'=> "订单金额错误:\n支付金额:" . $payMoney . "\n订单金额:" . $orderMoney]; PRedis::set('payments:hand:errorMoney_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo,'error'=> $error], 600); db('user_recharge_log')->where($where)->update($error); return '支付金额错误'; } try { db()->startTrans(); // 更新订单支付状态信息 $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0; $orderPayMoney = moneyFormat($payMoney / 100); $userId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0; $num = isset($orderInfo['money']) ? $orderInfo['money'] : 0; $updateData = [ 'pay_money' => $orderPayMoney, 'transaction_id' => isset($notifyData['transaction_id']) ? $notifyData['transaction_id'] : '', 'status' => 2, 'pay_at' => date('Y-m-d H:i:s'), ]; PRedis::set('payments:hand:catchOrder_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600); $res = db('user_recharge_log')->where($where)->update($updateData); if (!$res) { PRedis::set('payments:hand:updateError_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600); db()->rollback(); return false; } // 更新账户 if ($userId && $num > 0) { $dateTime = date('Y-m-d'); $memberInfo = Member::where(['id' => $userId])->field('openid,vip_auth,vip_expire')->find(); $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0; $vipExpire = isset($memberInfo['vip_expire']) ? intval($memberInfo['vip_expire']) : 0; $newVipExpire = $vipExpire>$dateTime && $vipAuth? ($vipExpire-$dateTime) + $num*30*24*3600+86400 : $dateTime+$num*30*24*3600+86400; $data = ['updated_at' => date('Y-m-d H:i:s'), 'vip_auth'=> 1, 'vip_expire' => $newVipExpire]; if (!Member::where(['id' => $userId])->update($data)) { db()->rollback(); return false; } $accountData = [ 'type' => 7, 'account_type' => 4, 'change_type' => 1, 'user_id' => $userId, 'money' => $num, 'balance' => 0, 'created_at' => date('Y-m-d H:i:s'), 'remark' => "购买人工牵线服务:单号[{$outTradeNo}],支付金额" . $orderPayMoney, ]; PRedis::set('payments:hand:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600); db('account_log')->insertGetId($accountData); // 发送充值成功消息 $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : ''; if($openid) { $params = [ 'title' => "恭喜您购买人工牵线服务成功", 'remark' => "感谢您的使用,点击详情查看购买明细", 'type' => 'pay', 'keywords' => [ 'keyword1' => [ 'value' => moneyFormat($orderPayMoney, 2), 'color' => '#173177', ], 'keyword2' => [ 'value' => date('Y.m.d H:i'), 'color' => '#173177', ], ], 'url' => url('/weixin/account/index', '', '', true), ]; PRedis::set('payments:hand:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600); Wechat::sendTplMsg($openid, $params); } } // 操作日志 UserLog::saveLog(['user_id' => $userId, 'type' => 3, 'content' => "购买人工牵线服务:支付{$orderPayMoney}元"]); db()->commit(); // 分销收益结算 $inviteInfo = MemberModel::getInviteInfo($userId); $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0; if($inviteInfo && $inviteId>0){ PRedis::set('markets:hand:entry' . $outTradeNo, ['notify' => $notifyData, 'inviteInfo'=> $inviteInfo, 'params' => $params], 7200); Award::marketAward($inviteId, $userId, 3, $orderPayMoney); } Payment::rebackOk(); return true; } catch (\Exception $exception){ PRedis::set('payments:hand:error:'.$outTradeNo, $exception, 600); db()->rollback(); return $exception->getMessage(); } } }