Payment.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <?php
  2. namespace app\weixin\model;
  3. use app\weixin\model\Member as MemberModel;
  4. use app\weixin\service\Award;
  5. use app\weixin\service\PRedis;
  6. use think\Db;
  7. class Payment
  8. {
  9. /**
  10. * 返回给微信
  11. */
  12. public static function rebackOk(){
  13. echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
  14. exit;
  15. }
  16. /**
  17. * 处理订单
  18. * @param $outTradeNo 订单号
  19. * @param array $notifyData 回调数据
  20. * @return bool
  21. */
  22. public static function catchOrder($outTradeNo, $notifyData=[]){
  23. Db::startTrans();
  24. // 更新订单支付状态信息
  25. $payMoney = isset($notifyData['total_fee'])? moneyFormat($notifyData['total_fee']): 0;
  26. $orderPayMoney = moneyFormat($payMoney/100);
  27. $orderInfo = Books::getInfo(['order_sn'=> $outTradeNo]);
  28. PRedis::set('orders:books:info_'.$outTradeNo, ['order'=> $orderInfo,'notify'=> $notifyData], 600);
  29. $userId = isset($orderInfo['uid'])? intval($orderInfo['uid']) : 0;
  30. if(empty($userId)){
  31. return false;
  32. }
  33. $bookAt = time();
  34. $updateData = [
  35. 'pay_type'=> isset($notifyData['pay_type'])? intval($notifyData['pay_type']) : 1,
  36. 'transaction_id'=> isset($notifyData['transaction_id'])? $notifyData['transaction_id'] : '',
  37. 'status'=> 2,
  38. 'book_at'=> date('Y-m-d H:i:s', $bookAt),
  39. ];
  40. PRedis::set('orders:books:update_'.$outTradeNo, ['order'=> $updateData,'notify'=> $notifyData], 600);
  41. $res = Books::saveData(['order_sn'=> $outTradeNo], $updateData);
  42. if(!$res){
  43. PRedis::set('orders:books:error_'.$outTradeNo, ['order'=> $updateData,'notify'=> $notifyData,'error'=> '更新订单支付数据失败'], 600);
  44. Db::rollback();
  45. return false;
  46. }
  47. // 账户明细
  48. $memberInfo = Member::getInfo(['id'=> $userId],'id,openid,redheart,user_nickname,real_name');
  49. $redheart = isset($memberInfo['redheart'])? intval($memberInfo['redheart']) : 0;
  50. $accountData = [
  51. 'type' => 2,
  52. 'account_type' => 4,
  53. 'change_type' => 2,
  54. 'user_id' => $userId,
  55. 'money' => moneyFormat($orderPayMoney, 2),
  56. 'balance' => $redheart,
  57. 'created_at' => date('Y-m-d H:i:s'),
  58. 'remark' => "微信支付活动报名:单号[{$outTradeNo}],活动:{$orderInfo['aid']},金额" . $orderPayMoney,
  59. ];
  60. PRedis::set('payments:books:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600);
  61. AccountLog::insertGetId($accountData);
  62. Db::commit();
  63. // 发送报名提交成功消息
  64. $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : '';
  65. $nickname = isset($memberInfo['user_nickname']) ? $memberInfo['user_nickname'] : '';
  66. $bookNo = isset($orderInfo['book_num'])? trim($orderInfo['book_num']) : '无';
  67. $money = isset($orderInfo['money'])? floatval($orderInfo['money']) : 0;
  68. $credit = isset($orderInfo['credit'])? floatval($orderInfo['credit']) : 0;
  69. $bookStatus = Books::where(['order_sn'=> $outTradeNo])->value('status');
  70. if($bookStatus != 2){
  71. return false;
  72. }
  73. if($openid) {
  74. $aid = isset($orderInfo['aid'])? intval($orderInfo['aid']) : 0;
  75. $activityInfo = Activity::where(['id'=> $aid])
  76. ->field('id,starttime,title,address')
  77. ->find();
  78. $title = isset($activityInfo['title'])? trim($activityInfo['title']) : '无';
  79. $address = isset($activityInfo['address'])? trim($activityInfo['address']) : '无';
  80. $bookAt = $bookAt? date('Y.m.d H:i', $bookAt) : date('Y.m.d H:i');
  81. $params = [
  82. 'title' => "我们已经收到您的报名,稍后会进行审核,请留意后续的通知哦!\n\n姓名:\t{$nickname}(昵称)\n\n支付单号:\t{$outTradeNo}\n\n支付金额:\t{$orderPayMoney}",
  83. 'remark' => "转发积姻缘,把活动分享给身边的朋友,一起来脱单哦!",
  84. 'type' => 'book',
  85. 'keywords' => [
  86. 'keyword1' => [
  87. 'value' => $title,
  88. 'color' => '#173177',
  89. ],
  90. 'keyword2' => [
  91. 'value' => $bookAt,
  92. 'color' => '#173177',
  93. ],
  94. 'keyword3' => [
  95. 'value' => '待审核',
  96. 'color' => '#173177',
  97. ],
  98. 'keyword4' => [
  99. 'value' => "活动费用{$money}元,活动守时金{$credit}元。",
  100. 'color' => '#173177',
  101. ],
  102. ],
  103. 'url' => url('/weixin/activity/bookdetail?id='.$aid, '', '', true),
  104. ];
  105. PRedis::set('payments:books:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600);
  106. Wechat::sendTplMsg($openid, $params);
  107. }
  108. return true;
  109. }
  110. /**
  111. * 充值结果处理
  112. * @param $outTradeNo
  113. * @param array $notifyData
  114. * @return bool
  115. * @throws \think\Exception
  116. * @throws \think\db\exception\DataNotFoundException
  117. * @throws \think\db\exception\ModelNotFoundException
  118. * @throws \think\exception\DbException
  119. * @throws \think\exception\PDOException
  120. */
  121. public static function catchRechargeOrder($outTradeNo, $notifyData=[]){
  122. try {
  123. db()->startTrans();
  124. // 更新订单支付状态信息
  125. $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0;
  126. $orderPayMoney = moneyFormat($payMoney / 100);
  127. $orderInfo = db('user_recharge_log')
  128. ->where(['order_sn' => $outTradeNo])
  129. ->field('money,pay_money,user_id,order_sn')
  130. ->find();
  131. $orderSn = isset($orderInfo['order_sn']) ? $orderInfo['order_sn'] : '';
  132. $userId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0;
  133. $num = isset($orderInfo['money']) ? $orderInfo['money'] : 0;
  134. $updateData = [
  135. 'pay_money' => $orderPayMoney,
  136. 'transaction_id' => isset($notifyData['transaction_id']) ? $notifyData['transaction_id'] : '',
  137. 'status' => 2,
  138. 'pay_at' => date('Y-m-d H:i:s'),
  139. ];
  140. PRedis::set('payments:redheart:catchOrder_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600);
  141. $res = db('user_recharge_log')->where(['order_sn' => $outTradeNo])->update($updateData);
  142. if (!$res) {
  143. PRedis::set('payments:redheart:updateError_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600);
  144. db()->rollback();
  145. return false;
  146. }
  147. // 更新账户
  148. if ($userId && $num > 0) {
  149. $memberInfo = Member::where(['id' => $userId])->field('openid,redheart')->find();
  150. $redheart = isset($memberInfo['redheart']) ? intval($memberInfo['redheart']) : 0;
  151. $data = ['updated_at' => date('Y-m-d H:i:s'), 'redheart' => intval($redheart + $num)];
  152. if (!Member::where(['id' => $userId])->update($data)) {
  153. db()->rollback();
  154. return false;
  155. }
  156. $accountData = [
  157. 'type' => 1,
  158. 'account_type' => 1,
  159. 'change_type' => 1,
  160. 'user_id' => $userId,
  161. 'money' => intval($num),
  162. 'balance' => $redheart,
  163. 'created_at' => date('Y-m-d H:i:s'),
  164. 'remark' => "微信支付爱心充值:单号[{$outTradeNo}],数量{$num},金额" . $orderPayMoney,
  165. ];
  166. PRedis::set('payments:redheart:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600);
  167. db('account_log')->insertGetId($accountData);
  168. // 发送充值成功消息
  169. $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : '';
  170. if($openid) {
  171. $params = [
  172. 'title' => "恭喜您充值成功",
  173. 'remark' => "感谢您的使用,点击详情查看充值明细",
  174. 'type' => 'redheart',
  175. 'keywords' => [
  176. 'keyword1' => [
  177. 'value' => moneyFormat($orderPayMoney, 2),
  178. 'color' => '#173177',
  179. ],
  180. 'keyword2' => [
  181. 'value' => date('Y.m.d H:i'),
  182. 'color' => '#173177',
  183. ],
  184. 'keyword3' => [
  185. 'value' => '微信支付',
  186. 'color' => '#173177',
  187. ],
  188. ],
  189. 'url' => url('/weixin/account/index', '', '', true),
  190. ];
  191. PRedis::set('payments:redheart:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600);
  192. Wechat::sendTplMsg($openid, $params);
  193. }
  194. }
  195. // 操作日志
  196. UserLog::saveLog(['user_id' => $userId, 'type' => 2, 'content' => "充值爱心:{$num}个"]);
  197. db()->commit();
  198. // 分销收益结算
  199. $inviteInfo = MemberModel::getInviteInfo($userId);
  200. $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0;
  201. if($inviteInfo && $inviteId>0){
  202. PRedis::set('markets:recharge:entry' . $outTradeNo, ['notify' => $notifyData, 'inviteInfo'=> $inviteInfo, 'params' => $params], 7200);
  203. Award::marketAward($inviteId, $userId, 8, $orderPayMoney);
  204. }
  205. return true;
  206. } catch (\Exception $exception){
  207. PRedis::set('payments:redheart:error:'.$outTradeNo, $exception, 600);
  208. db()->rollback();
  209. return false;
  210. }
  211. }
  212. /**
  213. * 微信支付
  214. * @param $orderId 订单ID
  215. * @param $orderInfo 订单信息
  216. * @param array $userInfo 用户信息
  217. * @return array
  218. */
  219. public static function wechatPay($orderId, $orderInfo, $userInfo=[]){
  220. $prepayId = isset($orderInfo['prepay_id']) ? trim($orderInfo['prepay_id']) : '';
  221. $orderStatus = isset($orderInfo['status']) ? trim($orderInfo['status']) : 0;
  222. $userId = isset($userInfo['id']) ? intval($userInfo['id']) : 0;
  223. if($orderStatus != 1){
  224. return 5007;
  225. }
  226. $orderSn = isset($orderInfo['order_sn'])? $orderInfo['order_sn'] : '';
  227. if(empty($orderSn)){
  228. return 1012;
  229. }
  230. $orderSn = isset($orderInfo['order_sn'])? $orderInfo['order_sn'] : '';
  231. if(empty($orderSn)){
  232. showJson(1004, 1012);
  233. }
  234. // 支付金额
  235. $orderMoney = isset($orderInfo['money']) ? moneyFormat($orderInfo['money']) : 0.00;
  236. $credit = isset($orderInfo['credit']) ? moneyFormat($orderInfo['credit']) : 0.00;
  237. $orderAmount = moneyFormat($orderMoney + $credit);
  238. if ($orderMoney <= 0) {
  239. return 5008;
  240. }
  241. if ($prepayId && $orderStatus == 1) {
  242. // 查询订单状态
  243. $queryResult = Wechat::queryOrder($orderSn);
  244. PRedis::set('payments:books:queryOrder_'.$orderSn, $queryResult, 600);
  245. if ($queryResult && Payment::catchOrder($orderInfo['order_sn'], $queryResult)) {
  246. return 5009;
  247. } else {
  248. $orderSn = makeTradeNo('BK', $userId);
  249. $saveData = ['order_sn' => $orderSn, 'remark' => '订单重新发起支付,原单号:' . $orderInfo['order_sn']];
  250. PRedis::set('payments:books:makeSn_'.$orderInfo['order_sn'], $saveData);
  251. Books::saveData(['id' => $orderId], $saveData);
  252. }
  253. }
  254. // 获取OPENID
  255. $openid = session('openid');
  256. if (empty($openid)) {
  257. $openid = Member::where(['id' => $userId])->value('openid');
  258. }
  259. $order = [
  260. 'orderNo' => $orderSn,
  261. 'amount' => $orderAmount,
  262. 'openid' => $openid,
  263. 'body' => '报名订单支付',
  264. ];
  265. $params = Wechat::jsapiUnifiedorder($order);
  266. PRedis::set('payments:books:payParams_'.$orderSn,['order'=> $order, 'params'=> $params,'date'=> date('Y-m-d H:i:s')], 600);
  267. $code = isset($params['code']) ? $params['code'] : '';
  268. if ($code == 'error') {
  269. return $params['message'];
  270. }
  271. // 更新订单参数
  272. $prepayId = isset($params['prepay_id'])? $params['prepay_id'] : '';
  273. Books::saveData(['id' => $orderId], ['prepay_id' => $prepayId]);
  274. unset($params['prepay_id']);
  275. return $params;
  276. }
  277. /**
  278. * VIP套餐支付处理
  279. * @param $outTradeNo
  280. * @param $notifyData
  281. * @param $taskNo
  282. * @return bool|string
  283. * @throws \think\Exception
  284. * @throws \think\db\exception\DataNotFoundException
  285. * @throws \think\db\exception\ModelNotFoundException
  286. * @throws \think\exception\DbException
  287. * @throws \think\exception\PDOException
  288. */
  289. public static function catchVip($outTradeNo, $notifyData, $taskNo){
  290. // 验证订单是否存在
  291. $where = ['order_sn' => $outTradeNo, 'type'=> 4];
  292. $orderInfo = db('user_recharge_log')
  293. ->field('money,pay_money,user_id,order_sn,status')
  294. ->where($where)
  295. ->find();
  296. if(empty($orderInfo)){
  297. PRedis::set('payments:vip:errorMoney_'.$taskNo, ['result'=> $notifyData, 'error'=> $outTradeNo.'订单不存在'], 600);
  298. return false;
  299. }
  300. // 订单已处理
  301. PRedis::set('payments:vip:order_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo], 600);
  302. $orderStatus = isset($orderInfo['status']) ? intval($orderInfo['status']) : 0;
  303. // 验证订单状态是否可处理
  304. if ($orderStatus != 1) {
  305. db('user_recharge_log')->where($where)->update(['remark'=> '订单已处理']);
  306. Payment::rebackOk();
  307. return true;
  308. }
  309. // 验证订单金额是否正确
  310. $payDebug = config('weixin.payDebug');
  311. $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0;
  312. $orderMoney = isset($orderInfo['pay_money']) ? moneyFormat($orderInfo['pay_money']) : 0.00;
  313. if (!$payDebug && $orderMoney * 100 != $payMoney) {
  314. $error = ['remark'=> "订单金额错误:\n支付金额:" . $payMoney . "\n订单金额:" . $orderMoney];
  315. PRedis::set('payments:vip:errorMoney_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo,'error'=> $error], 600);
  316. db('user_recharge_log')->where($where)->update($error);
  317. return '支付金额错误';
  318. }
  319. try {
  320. db()->startTrans();
  321. // 更新订单支付状态信息
  322. $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0;
  323. $orderPayMoney = moneyFormat($payMoney / 100);
  324. $userId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0;
  325. $num = isset($orderInfo['money']) ? $orderInfo['money'] : 0;
  326. $updateData = [
  327. 'pay_money' => $orderPayMoney,
  328. 'transaction_id' => isset($notifyData['transaction_id']) ? $notifyData['transaction_id'] : '',
  329. 'status' => 2,
  330. 'pay_at' => date('Y-m-d H:i:s'),
  331. ];
  332. PRedis::set('payments:vip:catchOrder_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600);
  333. $res = db('user_recharge_log')->where($where)->update($updateData);
  334. if (!$res) {
  335. PRedis::set('payments:vip:updateError_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600);
  336. db()->rollback();
  337. return false;
  338. }
  339. // 更新账户
  340. if ($userId && $num > 0) {
  341. $dateTime = strtotime(date('Y-m-d 00:00:00'));
  342. $memberInfo = Member::where(['id' => $userId])->field('openid,vip_auth,vip_expire')->find();
  343. $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0;
  344. $vipExpire = isset($memberInfo['vip_expire']) ? intval($memberInfo['vip_expire']) : 0;
  345. $newVipExpire = $vipExpire>$dateTime && $vipAuth? $vipExpire + $num*30*24*3600+86400 : $dateTime+$num*30*24*3600+86400;
  346. $data = ['updated_at' => date('Y-m-d H:i:s'), 'vip_auth'=> 1, 'vip_expire' => $newVipExpire];
  347. if (!Member::where(['id' => $userId])->update($data)) {
  348. db()->rollback();
  349. return false;
  350. }
  351. $num = intval($num);
  352. $accountData = [
  353. 'type' => 6,
  354. 'account_type' => 4,
  355. 'change_type' => 1,
  356. 'user_id' => $userId,
  357. 'money' => $num,
  358. 'balance' => 0,
  359. 'created_at' => date('Y-m-d H:i:s'),
  360. 'remark' => "购买VIP:单号[{$outTradeNo}],时长{$num}个月,支付金额" . $orderPayMoney,
  361. ];
  362. PRedis::set('payments:vip:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600);
  363. db('account_log')->insertGetId($accountData);
  364. // 发送充值成功消息
  365. $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : '';
  366. if($openid) {
  367. $monthTxt = $num ==6? '半年' : ($num == 12? '一年' : $num.'个月');
  368. $params = [
  369. 'title' => "恭喜您购买{$monthTxt}VIP成功\n\n到期时间:\t".date('Y.m.d',$newVipExpire).'到期',
  370. 'remark' => "感谢您的使用,点击详情查看购买明细",
  371. 'type' => 'pay',
  372. 'keywords' => [
  373. 'keyword1' => [
  374. 'value' => moneyFormat($orderPayMoney, 2),
  375. 'color' => '#173177',
  376. ],
  377. 'keyword2' => [
  378. 'value' => date('Y.m.d H:i'),
  379. 'color' => '#173177',
  380. ],
  381. ],
  382. 'url' => url('/weixin/account/index', '', '', true),
  383. ];
  384. PRedis::set('payments:vip:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600);
  385. Wechat::sendTplMsg($openid, $params);
  386. }
  387. }
  388. // 操作日志
  389. UserLog::saveLog(['user_id' => $userId, 'type' => 3, 'content' => "购买VIP:{$num}个月"]);
  390. db()->commit();
  391. // 分销收益结算
  392. $inviteInfo = MemberModel::getInviteInfo($userId);
  393. $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0;
  394. if($inviteInfo && $inviteId>0){
  395. PRedis::set('markets:vip:entry' . $outTradeNo, ['notify' => $notifyData, 'inviteInfo'=> $inviteInfo, 'params' => $params], 7200);
  396. Award::marketAward($inviteId, $userId, 2, $orderPayMoney);
  397. }
  398. Payment::rebackOk();
  399. return true;
  400. } catch (\Exception $exception){
  401. PRedis::set('payments:vip:error:'.$outTradeNo, $exception, 600);
  402. db()->rollback();
  403. return $exception->getMessage();
  404. }
  405. }
  406. /**
  407. * 人工牵线支付处理
  408. * @param $outTradeNo
  409. * @param $notifyData
  410. * @param $taskNo
  411. * @return bool|string
  412. * @throws \think\Exception
  413. * @throws \think\db\exception\DataNotFoundException
  414. * @throws \think\db\exception\ModelNotFoundException
  415. * @throws \think\exception\DbException
  416. * @throws \think\exception\PDOException
  417. */
  418. public static function catchHand($outTradeNo, $notifyData, $taskNo){
  419. // 验证订单是否存在
  420. $where = ['order_sn' => $outTradeNo, 'type'=> 5];
  421. $orderInfo = db('user_recharge_log')
  422. ->field('money,pay_money,user_id,order_sn,status')
  423. ->where($where)
  424. ->find();
  425. if(empty($orderInfo)){
  426. PRedis::set('payments:hand:errorMoney_'.$taskNo, ['result'=> $notifyData, 'error'=> $outTradeNo.'订单不存在'], 600);
  427. return false;
  428. }
  429. // 订单已处理
  430. PRedis::set('payments:hand:order_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo], 600);
  431. $orderStatus = isset($orderInfo['status']) ? intval($orderInfo['status']) : 0;
  432. // 验证订单状态是否可处理
  433. if ($orderStatus != 1) {
  434. db('user_recharge_log')->where($where)->update(['remark'=> '订单已处理']);
  435. Payment::rebackOk();
  436. return true;
  437. }
  438. // 验证订单金额是否正确
  439. $payDebug = config('weixin.payDebug');
  440. $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0;
  441. $orderMoney = isset($orderInfo['pay_money']) ? moneyFormat($orderInfo['pay_money']) : 0.00;
  442. if (!$payDebug && $orderMoney * 100 != $payMoney) {
  443. $error = ['remark'=> "订单金额错误:\n支付金额:" . $payMoney . "\n订单金额:" . $orderMoney];
  444. PRedis::set('payments:hand:errorMoney_'.$taskNo, ['result'=> $notifyData, 'order'=> $orderInfo,'error'=> $error], 600);
  445. db('user_recharge_log')->where($where)->update($error);
  446. return '支付金额错误';
  447. }
  448. try {
  449. db()->startTrans();
  450. // 更新订单支付状态信息
  451. $payMoney = isset($notifyData['total_fee']) ? moneyFormat($notifyData['total_fee']) : 0;
  452. $orderPayMoney = moneyFormat($payMoney / 100);
  453. $userId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0;
  454. $num = isset($orderInfo['money']) ? $orderInfo['money'] : 0;
  455. $updateData = [
  456. 'pay_money' => $orderPayMoney,
  457. 'transaction_id' => isset($notifyData['transaction_id']) ? $notifyData['transaction_id'] : '',
  458. 'status' => 2,
  459. 'pay_at' => date('Y-m-d H:i:s'),
  460. ];
  461. PRedis::set('payments:hand:catchOrder_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600);
  462. $res = db('user_recharge_log')->where($where)->update($updateData);
  463. if (!$res) {
  464. PRedis::set('payments:hand:updateError_' . $outTradeNo, ['notify' => $notifyData, 'update' => $updateData], 600);
  465. db()->rollback();
  466. return false;
  467. }
  468. // 更新账户
  469. if ($userId && $num > 0) {
  470. $dateTime = date('Y-m-d');
  471. $memberInfo = Member::where(['id' => $userId])->field('openid,vip_auth,vip_expire')->find();
  472. $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0;
  473. $vipExpire = isset($memberInfo['vip_expire']) ? intval($memberInfo['vip_expire']) : 0;
  474. $newVipExpire = $vipExpire>$dateTime && $vipAuth? ($vipExpire-$dateTime) + $num*30*24*3600+86400 : $dateTime+$num*30*24*3600+86400;
  475. $data = ['updated_at' => date('Y-m-d H:i:s'), 'vip_auth'=> 1, 'vip_expire' => $newVipExpire];
  476. if (!Member::where(['id' => $userId])->update($data)) {
  477. db()->rollback();
  478. return false;
  479. }
  480. $accountData = [
  481. 'type' => 7,
  482. 'account_type' => 4,
  483. 'change_type' => 1,
  484. 'user_id' => $userId,
  485. 'money' => $num,
  486. 'balance' => 0,
  487. 'created_at' => date('Y-m-d H:i:s'),
  488. 'remark' => "购买人工牵线服务:单号[{$outTradeNo}],支付金额" . $orderPayMoney,
  489. ];
  490. PRedis::set('payments:hand:account_' . $outTradeNo, ['notify' => $notifyData, 'log' => $accountData,'user'=> $memberInfo], 600);
  491. db('account_log')->insertGetId($accountData);
  492. // 发送充值成功消息
  493. $openid = isset($memberInfo['openid']) ? $memberInfo['openid'] : '';
  494. if($openid) {
  495. $monthTxt = $num ==6? '半年' : ($num == 12? '一年' : $num.'个月');
  496. $params = [
  497. 'title' => "恭喜您购买{$monthTxt}人工牵线服务成功",
  498. 'remark' => "感谢您的使用,点击详情查看购买明细",
  499. 'type' => 'pay',
  500. 'keywords' => [
  501. 'keyword1' => [
  502. 'value' => moneyFormat($orderPayMoney, 2),
  503. 'color' => '#173177',
  504. ],
  505. 'keyword2' => [
  506. 'value' => date('Y.m.d H:i'),
  507. 'color' => '#173177',
  508. ],
  509. ],
  510. 'url' => url('/weixin/account/index', '', '', true),
  511. ];
  512. PRedis::set('payments:hand:message_' . $outTradeNo, ['notify' => $notifyData, 'params' => $params], 600);
  513. Wechat::sendTplMsg($openid, $params);
  514. }
  515. }
  516. // 操作日志
  517. UserLog::saveLog(['user_id' => $userId, 'type' => 3, 'content' => "购买人工牵线服务:支付{$orderPayMoney}元"]);
  518. db()->commit();
  519. // 分销收益结算
  520. $inviteInfo = MemberModel::getInviteInfo($userId);
  521. $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0;
  522. if($inviteInfo && $inviteId>0){
  523. PRedis::set('markets:hand:entry' . $outTradeNo, ['notify' => $notifyData, 'inviteInfo'=> $inviteInfo, 'params' => $params], 7200);
  524. Award::marketAward($inviteId, $userId, 3, $orderPayMoney);
  525. }
  526. Payment::rebackOk();
  527. return true;
  528. } catch (\Exception $exception){
  529. PRedis::set('payments:hand:error:'.$outTradeNo, $exception, 600);
  530. db()->rollback();
  531. return $exception->getMessage();
  532. }
  533. }
  534. }