MiniPayController.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Events\HelpOrderEvent;
  4. use App\Events\NewOrder;
  5. use App\Events\RetailOutboundEvent;
  6. use App\Models\Amount;
  7. use App\Models\DwbsUser;
  8. use App\Models\Goods;
  9. use App\Models\GoodSku;
  10. use App\Models\IntegralW;
  11. use App\Models\Order;
  12. use App\Models\OrderW;
  13. use App\Models\OrderDetailW;
  14. use App\Models\StoreGoods;
  15. use App\Models\StoreGoodsSku;
  16. use App\Models\Store;
  17. use App\Models\User;
  18. use App\Models\UserW;
  19. use App\Models\VipLogW;
  20. use App\Models\LogW;
  21. use EasyWeChat\Factory;
  22. use Carbon\Carbon;
  23. use Illuminate\Http\Request;
  24. use Illuminate\Support\Facades\Auth;
  25. use Illuminate\Support\Facades\DB;
  26. use Illuminate\Support\Facades\Log;
  27. class MiniPayController extends Controller
  28. {
  29. public function pay(Request $request)
  30. {
  31. $order_no=$request->input('order_no');
  32. try{
  33. DB::transaction(function()use($order_no, &$order ,&$seconds){
  34. $order=OrderW::where('order_no',$order_no)->lockForUpdate()->first();
  35. $seconds=Carbon::now()->subSeconds(60)->toDateTimeString();//限制调起支付60秒
  36. if(empty($order)){
  37. throw new \Exception("订单有误");
  38. }
  39. if($order->prepare_pay_at >= $seconds){
  40. throw new \Exception("订单正在支付中");
  41. }
  42. $order->prepare_pay_at=Carbon::now();
  43. $order->save();
  44. });
  45. }catch(\Exception $e){
  46. return $this->error('450001',$e->getMessage());
  47. }
  48. $store=Store::where('id',$order->store_id)->first();
  49. if(empty($store)){
  50. return $this->error('450001','店铺不存在或者已被删除');
  51. }
  52. if($store->status==1){
  53. return $this->error('450001','店铺已被禁用');
  54. }
  55. if(empty($order)){
  56. return $this->error('450001','订单有误');
  57. }
  58. if($order->apply_cancel == 2){
  59. return $this->error('450001','订单已取消');
  60. }
  61. if($order->is_pay != 0 || $order->status != 0){
  62. return $this->error('450001','订单状态有误');
  63. }
  64. if($order->account <= 0){
  65. return $this->error('450001','支付金额有误');
  66. }
  67. $openid=User::where('id',Auth::user()->id)->value('openid');
  68. $options = $this->options($order->store_id);
  69. $payment = Factory::payment($options);
  70. $jssdk = $payment->jssdk;
  71. Log::info(round($order->account/1000,2));
  72. Log::info(round($order->account/10));
  73. $two_minutes=Carbon::now()->addSeconds(55)->toDateTimeString();//限制支付时间55秒
  74. $cancel_time=Carbon::parse($order->created_at)->addMinutes(59)->toDateTimeString();//系统自动取消时间前一分钟
  75. if(Carbon::now() >= $cancel_time){
  76. return $this->error('450001','订单将被取消');
  77. }
  78. if($two_minutes <= $cancel_time){
  79. $expire=date("YmdHis",strtotime($two_minutes));
  80. }else{
  81. $expire=date("YmdHis",strtotime($cancel_time));
  82. }
  83. Log::info('ASASS'.$expire);
  84. $attributes = [
  85. 'time_expire' => $expire,
  86. 'trade_type' => 'JSAPI', // 支付方式,小程序支付使用JSAPI
  87. 'body' => '订单支付', // 订单说明
  88. 'out_trade_no' => mt_rand('1000','9999').'_'.$order_no, // 自定义订单号
  89. 'total_fee' => $order->account*100, // 单位:分
  90. 'sub_openid' => $openid, // 当前用户的openId
  91. 'profit_sharing' => 'Y'
  92. ];
  93. $result = $payment->order->unify($attributes);
  94. if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
  95. $prepayId = $result['prepay_id'];
  96. $config = $jssdk->sdkConfig($prepayId);
  97. return response()->json([
  98. 'error_code'=>200,
  99. 'msg'=>'成功',
  100. 'data'=>$config
  101. ]);
  102. }
  103. if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) {
  104. Log::info('订单支付失败:'.$order->user_id.'/'.$order_no.'/'.$order->account.'/'.$result['return_msg']);
  105. return response()->json([
  106. 'error_code'=>401,
  107. 'msg'=> $result['return_msg'],
  108. ]);
  109. }
  110. Log::info('订单支付失败:'.$order->user_id.'/'.$order_no.'/'.$order->money.'/'.$result['err_code_des']);
  111. return response()->json([
  112. 'error_code'=>401,
  113. 'msg'=> $result['err_code_des'],
  114. ]);
  115. }
  116. protected function options($id){
  117. return [
  118. 'app_id' => 'wxf536016d4923e584',//config('wechat.payment.default.app_id'),
  119. 'mch_id' => config('wechat.payment.default.mch_id'),
  120. 'sub_mch_id' => Store::where('id',$id)->value('sub_mchid'),
  121. 'key' => config('wechat.payment.default.key'),
  122. 'notify_url' => url('api/payment/notify')
  123. ];
  124. }
  125. public function notify(Request $request)
  126. {
  127. Log::info('支付完成开始微信回调');
  128. $options = [
  129. 'app_id' => 'wxf536016d4923e584',//config('wechat.payment.default.app_id'),
  130. 'mch_id' => config('wechat.payment.default.mch_id'),
  131. 'key' => config('wechat.payment.default.key'),
  132. 'notify_url' => url('api/payment/notify')
  133. ];
  134. $payment = Factory::payment($options);
  135. $response = $payment->handlePaidNotify(function ($message, $fail)
  136. {
  137. // 根据返回的订单号查询订单数据
  138. Log::error($message);
  139. LogW::create([
  140. 'content'=>json_encode($message),
  141. 'type'=>1
  142. ]);
  143. $rand_no=explode('_',$message['out_trade_no'])[0];
  144. $message['out_trade_no']=explode('_',$message['out_trade_no'])[1];
  145. $order=OrderW::where('order_no',$message['out_trade_no'])->first();
  146. if ($order->is_pay==1){
  147. Log::info('订单号为:'.$message['out_trade_no'].'已经支付');
  148. return true;
  149. }
  150. if (!$order || $order->status == 1) {
  151. Log::info('订单不存在:'.$message['out_trade_no'].'/'.$message['transaction_id'].'/'.$message['result_code']);
  152. return true;//订单不存在 或者 订单已支付
  153. }
  154. if ($message['result_code'] === 'FAIL') { //支付失败
  155. Log::warning('[wechat-pay]:' . json_encode($message, true));
  156. return true;
  157. }
  158. if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
  159. // 支付成功后的业务逻辑
  160. if($message['result_code'] === 'SUCCESS') {
  161. $total_fee=round($message['total_fee']/100,2);
  162. DB::connection('mysql_w')->transaction(function()use($order,$message,$total_fee,$rand_no){
  163. //修改订单状态
  164. $order->status = 1;
  165. $order->is_help = 1;
  166. $order->is_pay = 1;
  167. $order->pay_type = 1;
  168. $order->pay_money = $total_fee;
  169. $order->rand_no = $rand_no;
  170. $order->pay_open_id = $message['openid'];
  171. $order->self_pay = 1;
  172. $order->wechat_pay_no = $message['transaction_id'];
  173. $order->pay_at = $message['time_end'];
  174. $order->save();
  175. //学分变更
  176. $integral=$order->total*5;
  177. $inte=IntegralW::where('order_no',$order->order_no)->where('store_id',$order->store_id)->where('type',1)->first();
  178. if(empty($inte)){
  179. IntegralW::create([
  180. 'store_id'=>$order->store_id,
  181. 'order_no'=>$order->order_no,
  182. 'num'=>$order->total,
  183. 'integral'=>$integral,
  184. 'integral_double'=>$integral,
  185. 'type'=>1,
  186. 'remark'=>'下单成功',
  187. ]);
  188. }
  189. //店铺信息
  190. Log::info($message['out_trade_no']);
  191. Log::info($total_fee);
  192. $store=Store::where('id',$order->store_id)->lockForUpdate()->first();
  193. $start_money= $store->pending_amount;
  194. $store->pending_amount += $total_fee;
  195. $store->integral += $integral;
  196. $store->cycle_inte += $integral;
  197. $store->save();
  198. //规格销量
  199. $details=OrderDetailW::where('order_no',$order->order_no)->get();
  200. foreach($details as $key=>$val){
  201. $where=[];
  202. $where['goods_id']=$val->goods_id;
  203. $where['size']=$val->size;
  204. $where['type']=$val->type;
  205. $sku=StoreGoodsSku::where($where)->lockForUpdate()->first();
  206. $sku->sale_num += $val->num;
  207. $sku->save();
  208. //商品销量
  209. $goods=StoreGoods::where('id',$val->goods_id)->lockForUpdate()->first();
  210. $goods->sale_num += $val->num;
  211. $goods->save();
  212. }
  213. //用户vip变更
  214. $vipLog=VipLogW::where('user_id',$order->user_id)
  215. ->where('store_id',$order->store_id)->first();
  216. /*张奇新增**/
  217. // UserW::where('id',$order->user_id)->update(['is_vip'=>1]);
  218. if(empty($vipLog) && $order->total>=2){
  219. VipLogW::create([
  220. 'user_id'=>$order->user_id,
  221. 'store_id'=>$store->id,
  222. 'order_no'=>$message['out_trade_no']
  223. ]);
  224. OrderW::where('order_no',$message['out_trade_no'])->update([
  225. 'vip'=>1
  226. ]);
  227. }
  228. //支付日志
  229. Amount::create([
  230. 'user_id' => $order->user_id,
  231. 'store_id' => $order->store_id,
  232. 'order_no' => $message['out_trade_no'],
  233. 'transaction_id'=> $message['transaction_id'],
  234. 'money' => $total_fee,
  235. 'type' => 1, //支付
  236. 'status' => 1, //成功
  237. 'service_fee' => 0,
  238. 'start_money' => $start_money,
  239. 'end_money' => $store->pending_amount,
  240. 'start_amount' => $store->available_amount,//支付前可用金额
  241. 'end_amount' => $store->available_amount,//支付后可用金额
  242. 'remark' => '收款',
  243. ]);
  244. },5);
  245. //减库存
  246. DB::connection('mysql')->transaction(function()use($order) {
  247. event(new RetailOutboundEvent($order->order_no));
  248. },5);
  249. //代下单通知客户
  250. $user=UserW::where('id',$order->user_id)->first();
  251. $agent_id=Store::where('id',$order->store_id)->value('user_id');
  252. $agent = User::where('id',$agent_id)->first();
  253. if($user->openId){
  254. $data['openid']=$user->openId;
  255. $data['data']=[
  256. 'first' =>'代理【'.$agent->nickname .'】已帮您下单成功,请及时查看订单',
  257. 'keyword1' => $order->order_no,
  258. 'keyword2' => number_format($order->account, 2),
  259. 'keyword3' => $order->op_name,
  260. 'keyword4' => $agent->mobile,
  261. 'remark' => '点击链接进入系统,查看详情',
  262. ];
  263. event(new HelpOrderEvent($data));
  264. }
  265. //代下单通知代理
  266. //新订单通知
  267. // $store=Store::where('id',$order->store_id)->first();
  268. // $user=User::where('id',$store->user_id)->first();
  269. if($agent->openid){
  270. $data['openid']=$agent->openid;
  271. $data['data']=[
  272. 'first' => '您有新的客户订单,请及时处理',
  273. 'keyword1' => $user->nickname,
  274. 'keyword2' => number_format($order->account, 2),
  275. 'keyword3' => $order->order_no,
  276. 'keyword4' => $order->created_at
  277. ];
  278. event(new NewOrder($data));
  279. }
  280. }
  281. return true;
  282. }else{
  283. Log::info('通信失败');
  284. return $fail('通信失败,请稍后再通知我');
  285. }
  286. });
  287. return $response;
  288. }
  289. public function GetPay(){
  290. // 根据返回的订单号查询订单数据
  291. // $message=['appid' => 'wx5224793b7dc7f7b7',
  292. // 'bank_type' => 'OTHERS',
  293. // 'cash_fee' => '153700',
  294. // 'fee_type' => 'CNY',
  295. // 'is_subscribe' => 'Y',
  296. // 'mch_id' => '1603992271',
  297. // 'nonce_str' => '60628be3521c8',
  298. // 'openid' => 'ogTajwF_jHXaMTNcXLy1zT_XW-VU',
  299. // 'out_trade_no' => '2657_DX21033010243392320927494',
  300. // 'result_code' => 'SUCCESS',
  301. // 'return_code' => 'SUCCESS',
  302. // 'sign' => '8CC558CED364CB2384F188EBEF5D3255',
  303. // 'sub_mch_id' => '1607799110',
  304. // 'time_end' => '20210330102440',
  305. // 'total_fee' => '153700',
  306. // 'trade_type' => 'JSAPI',
  307. // 'transaction_id' => '4200000896202103308732225144',];
  308. // Log::error($message);
  309. Log::error('主动回调');
  310. $rand_no=explode('_',$message['out_trade_no'])[0];
  311. $message['out_trade_no']=explode('_',$message['out_trade_no'])[1];
  312. $order=OrderW::where('order_no',$message['out_trade_no'])->first();
  313. if (!$order || $order->status == 1) {
  314. Log::info('订单不存在:'.$message['out_trade_no'].'/'.$message['transaction_id'].'/'.$message['result_code']);
  315. return true;//订单不存在 或者 订单已支付
  316. }
  317. if ($message['result_code'] === 'FAIL') { //支付失败
  318. Log::warning('[wechat-pay]:' . json_encode($message, true));
  319. return true;
  320. }
  321. if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
  322. // 支付成功后的业务逻辑
  323. if($message['result_code'] === 'SUCCESS') {
  324. $total_fee=round($message['total_fee']/100,2);
  325. DB::connection('mysql_w')->transaction(function()use($order,$message,$total_fee,$rand_no){
  326. //修改订单状态
  327. $order->status = 1;
  328. $order->is_pay = 1;
  329. $order->pay_type = 1;
  330. $order->pay_money = $total_fee;
  331. $order->rand_no = $rand_no;
  332. $order->pay_open_id = $message['openid'];
  333. $order->self_pay = 1;
  334. $order->wechat_pay_no = $message['transaction_id'];
  335. $order->pay_at = $message['time_end'];
  336. $order->save();
  337. //店铺信息
  338. $store=Store::where('id',$order->store_id)->lockForUpdate()->first();
  339. $start_money= $store->pending_amount;
  340. Log::error($store->pending_amount);
  341. Log::error($total_fee);
  342. $store->pending_amount += $total_fee;
  343. $store->save();
  344. //规格销量
  345. $details=OrderDetailW::where('order_no',$order->order_no)->get();
  346. foreach($details as $key=>$val){
  347. $where=[];
  348. $where['goods_id']=$val->goods_id;
  349. $where['size']=$val->size;
  350. $where['type']=$val->type;
  351. $sku=StoreGoodsSku::where($where)->lockForUpdate()->first();
  352. $sku->sale_num += $val->num;
  353. $sku->save();
  354. //商品销量
  355. $goods=StoreGoods::where('id',$val->goods_id)->lockForUpdate()->first();
  356. $goods->sale_num += $val->num;
  357. $goods->save();
  358. }
  359. //用户vip变更
  360. $vipLog=VipLogW::where('user_id',$order->user_id)
  361. ->where('store_id',$order->store_id)->first();
  362. /*张奇新增**/
  363. UserW::where('id',$order->user_id)->update(['is_vip'=>1]);
  364. if(empty($vipLog) && $order->total>=2){
  365. VipLogW::create([
  366. 'user_id'=>$order->user_id,
  367. 'store_id'=>$store->id,
  368. 'order_no'=>$message['out_trade_no']
  369. ]);
  370. OrderW::where('order_no',$message['out_trade_no'])->update([
  371. 'vip'=>1
  372. ]);
  373. }
  374. //支付日志
  375. Amount::create([
  376. 'user_id' => $order->user_id,
  377. 'store_id' => $order->store_id,
  378. 'order_no' => $message['out_trade_no'],
  379. 'transaction_id'=> $message['transaction_id'],
  380. 'money' => $total_fee,
  381. 'type' => 1, //支付
  382. 'status' => 1, //成功
  383. 'service_fee' => 0,
  384. 'start_money' => $start_money,
  385. 'end_money' => $store->pending_amount,
  386. 'start_amount' => $store->available_amount,//支付前可用金额
  387. 'end_amount' => $store->available_amount,//支付后可用金额
  388. 'remark' => '收款',
  389. ]);
  390. },5);
  391. //减库存
  392. DB::connection('mysql')->transaction(function()use($order) {
  393. event(new RetailOutboundEvent($order->order_no));
  394. },5);
  395. //代下单通知客户
  396. $user=UserW::where('id',$order->user_id)->first();
  397. $agent_id=Store::where('id',$order->store_id)->value('user_id');
  398. $agent = User::where('id',$agent_id)->first();
  399. if($user->openId){
  400. $data['openid']=$user->openId;
  401. $data['data']=[
  402. 'first' =>'代理【'.$agent->nickname .'】已帮您下单成功,请及时查看订单',
  403. 'keyword1' => $order->order_no,
  404. 'keyword2' => number_format($order->account, 2),
  405. 'keyword3' => $order->op_name,
  406. 'keyword4' => $agent->mobile,
  407. 'remark' => '点击链接进入系统,查看详情',
  408. ];
  409. event(new HelpOrderEvent($data));
  410. }
  411. //代下单通知代理
  412. //新订单通知
  413. // $store=Store::where('id',$order->store_id)->first();
  414. // $user=User::where('id',$store->user_id)->first();
  415. if($agent->openid){
  416. $data['openid']=$agent->openid;
  417. $data['data']=[
  418. 'first' => '您有新的客户订单,请及时处理',
  419. 'keyword1' => $user->nickname,
  420. 'keyword2' => number_format($order->account, 2),
  421. 'keyword3' => $order->order_no,
  422. 'keyword4' => $order->created_at
  423. ];
  424. event(new NewOrder($data));
  425. }
  426. }
  427. return true;
  428. }
  429. }
  430. }