PaymentController.php 20 KB

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