PaymentController.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Http\Models\Coupon;
  4. use App\Http\Models\CouponLog;
  5. use App\Http\Models\Goods;
  6. use App\Http\Models\Order;
  7. use App\Http\Models\Payment;
  8. use App\Http\Models\User;
  9. use Illuminate\Http\Request;
  10. use Response;
  11. use Redirect;
  12. use Cache;
  13. use Log;
  14. use DB;
  15. class PaymentController extends Controller
  16. {
  17. protected static $config;
  18. private $accessToken;
  19. function __construct()
  20. {
  21. self::$config = $this->systemConfig();
  22. $this->accessToken = $this->getAccessToken();
  23. }
  24. // 获取accessToken
  25. private function getAccessToken()
  26. {
  27. if (Cache::has('YZY_TOKEN')) {
  28. return Cache::get('YZY_TOKEN')['access_token'];
  29. }
  30. $clientId = self::$config['youzan_client_id'];
  31. $clientSecret = self::$config['youzan_client_secret'];
  32. $type = 'self';
  33. $keys['kdt_id'] = self::$config['kdt_id'];
  34. $token = (new \Youzan\Open\Token($clientId, $clientSecret))->getToken($type, $keys);
  35. Cache::put('YZY_TOKEN', $token, 10000);
  36. return $token['access_token'];
  37. }
  38. // 创建支付单
  39. public function create(Request $request)
  40. {
  41. $goods_id = intval($request->get('goods_id'));
  42. $coupon_sn = $request->get('coupon_sn');
  43. $goods = Goods::query()->where('id', $goods_id)->where('status', 1)->first();
  44. if (!$goods) {
  45. return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:商品或服务已下架']);
  46. }
  47. // 判断是否开启有赞云支付
  48. if (!self::$config['is_youzan']) {
  49. return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:系统并未开启在线支付功能']);
  50. }
  51. // 判断是否存在同个商品的未支付订单
  52. $existsOrder = Order::query()->where('goods_id', $goods_id)->where('status', 0)->first();
  53. if ($existsOrder) {
  54. return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:尚有未支付的订单,请先去支付']);
  55. }
  56. // 使用优惠券
  57. if ($coupon_sn) {
  58. $coupon = Coupon::query()->where('sn', $coupon_sn)->where('is_del', 0)->where('status', 0)->first();
  59. if (!$coupon) {
  60. return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:优惠券不存在']);
  61. }
  62. // 计算实际应支付总价
  63. $totalPrice = $coupon->type == 2 ? $goods->price * $coupon->discount : $goods->price - $coupon->amount;
  64. $totalPrice = $totalPrice > 0 ? $totalPrice : 0;
  65. } else {
  66. $totalPrice = $goods->price;
  67. }
  68. DB::beginTransaction();
  69. try {
  70. $user = $request->session()->get('user');
  71. $orderId = date('ymdHis') . mt_rand(100000, 999999);
  72. $sn = makeRandStr(12);
  73. // 生成订单
  74. $order = new Order();
  75. $order->orderId = $orderId;
  76. $order->user_id = $user['id'];
  77. $order->goods_id = $goods_id;
  78. $order->coupon_id = !empty($coupon) ? $coupon->id : 0;
  79. $order->totalOriginalPrice = $goods->price;
  80. $order->totalPrice = $totalPrice;
  81. $order->expire_at = date("Y-m-d H:i:s", strtotime("+" . $goods->days . " days"));
  82. $order->is_expire = 0;
  83. $order->pay_way = 2;
  84. $order->status = 0;
  85. $order->save();
  86. // 生成支付单
  87. $client = new \Youzan\Open\Client($this->accessToken);
  88. $method = 'youzan.pay.qrcode.create';
  89. $apiVersion = '3.0.0';
  90. $params = [
  91. 'qr_name' => $goods->name, // 商品名
  92. 'qr_price' => $totalPrice, // 单位分
  93. 'qr_source' => $orderId, // 本地订单号
  94. 'qr_type' => 'QR_TYPE_DYNAMIC'
  95. ];
  96. $result = $client->get($method, $apiVersion, $params);
  97. if (isset($result['error_response'])) {
  98. Log::error('【有赞云】创建二维码失败:' . $result['error_response']['msg']);
  99. throw new \Exception($result['error_response']['msg']);
  100. }
  101. $payment = new Payment();
  102. $payment->sn = $sn;
  103. $payment->user_id = $user['id'];
  104. $payment->oid = $order->oid;
  105. $payment->orderId = $orderId;
  106. $payment->pay_way = 1;
  107. $payment->amount = $order->totalPrice;
  108. $payment->qr_id = $result['response']['qr_id'];
  109. $payment->qr_url = $result['response']['qr_url'];
  110. $payment->qr_code = $result['response']['qr_code'];
  111. $payment->status = 0;
  112. $payment->save();
  113. DB::commit();
  114. return Response::json(['status' => 'success', 'data' => $sn, 'message' => '创建支付单成功']);
  115. } catch (\Exception $e) {
  116. DB::rollBack();
  117. Log::error('创建支付订单失败:' . $e->getMessage());
  118. return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:' . $e->getMessage()]);
  119. }
  120. }
  121. // 支付单详情
  122. public function detail(Request $request, $sn)
  123. {
  124. if (empty($sn)) {
  125. return Redirect::to('user/goodsList');
  126. }
  127. $user = $request->session()->get('user');
  128. $payment = Payment::query()->with(['order', 'order.goods'])->where('sn', $sn)->where('user_id', $user['id'])->first();
  129. if (!$payment) {
  130. return Redirect::to('user/goodsList');
  131. }
  132. $order = Order::query()->where('oid', $payment->oid)->first();
  133. if (!$order) {
  134. $request->session()->flash('errorMsg', '订单不存在');
  135. return Response::view('payment/' . $sn);
  136. }
  137. $view['payment'] = $payment;
  138. return Response::view('payment/detail', $view);
  139. }
  140. // 获取订单支付状态
  141. public function getStatus(Request $request)
  142. {
  143. $sn = $request->get('sn');
  144. if (empty($sn)) {
  145. return Response::json(['status' => 'fail', 'data' => '', 'message' => '请求失败']);
  146. }
  147. $user = $request->session()->get('user');
  148. $payment = Payment::query()->where('sn', $sn)->where('user_id', $user['id'])->first();
  149. if (!$payment) {
  150. return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败']);
  151. }
  152. if ($payment->status) {
  153. return Response::json(['status' => 'success', 'data' => '', 'message' => '支付成功']);
  154. } else if ($payment->status < 0) {
  155. return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败']);
  156. } else {
  157. return Response::json(['status' => 'fail', 'data' => '', 'message' => '等待支付']);
  158. }
  159. }
  160. }