You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
5.1 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. <?php
  2. namespace App\Controller;
  3. use App\Constants\ErrorCode;
  4. use App\Model\Order;
  5. use App\Model\OrderGoods;
  6. use App\Model\OrderMain;
  7. use App\Request\WxminiPayRequest;
  8. use Hyperf\Di\Annotation\Inject;
  9. use App\Service\PurchaseLimitServiceInterface;
  10. use EasyWeChat\Factory;
  11. use Hyperf\DbConnection\Db;
  12. use Hyperf\Guzzle\CoroutineHandler;
  13. use App\Constants\LogLabel;
  14. use App\Commons\Log;
  15. class PaymentController extends BaseController
  16. {
  17. /**
  18. * @Inject
  19. * @var PurchaseLimitServiceInterface
  20. */
  21. protected $purchaseLimitService;
  22. public function wxminiPayOnline(WxminiPayRequest $request){
  23. $data = $request->validated();
  24. $config = config('wxpay');
  25. $app = Factory::payment($config);
  26. $app['guzzle_handler'] = CoroutineHandler::class;
  27. // 待支付的,未超时(15min,900sec)的订单
  28. $orderMain = OrderMain::query()
  29. ->where(['state' => OrderMain::ORDER_STATE_UNPAY, 'id' => $data['order_id']])
  30. ->where('time', '>=', date('Y-m-d H:i:s', (time()-900)))
  31. ->first();
  32. if (empty($orderMain)) {
  33. return $this->result(ErrorCode::PAY_FAILURE, $data,'订单不存在或已失效');
  34. }
  35. //查询订单商品信息
  36. $order = Order::query()
  37. ->where('order_main_id',$data['order_id'])
  38. ->select('id')
  39. ->get()
  40. ->toArray();
  41. $orderGoods = OrderGoods::query()
  42. ->whereIn('order_id',$order)
  43. ->get();
  44. //判断是否有购买多个特价商品
  45. $result = $this->purchaseLimitService->PurchaseLimit($orderGoods);
  46. if(!$result){
  47. Db::rollBack();
  48. $this->log->event(LogLabel::ORDER_LOG, ['msg'=> '支付失败,同一订单不能存在多个特价商品','global_order_id' => $orderMain->global_order_id]);
  49. return $this->result(ErrorCode::PAY_FAILURE, $data,'同一订单不能存在多个特价商品');
  50. }
  51. $payMoney = bcmul(floatval($orderMain->money), 100, 0);
  52. if (env('APP_ENV') != 'prod') {
  53. $payMoney = 0.01;
  54. }
  55. $result = $app->order->unify([
  56. 'body' => '懒族生活 - 外卖下单',
  57. 'out_trade_no' => $orderMain->global_order_id,
  58. 'total_fee' => $payMoney,
  59. 'notify_url' => config('site_host') . '/wechat/notify/wxminionline',
  60. 'trade_type' => 'JSAPI',
  61. 'openid' => $data['openid'],
  62. ]);
  63. // 返回支付参数给前端
  64. $parameters = [
  65. 'appId' => $result['appid'],
  66. 'timeStamp' => '' . time() . '',
  67. 'nonceStr' => uniqid(),
  68. 'package' => 'prepay_id=' . $result['prepay_id'],
  69. 'signType' => 'MD5'
  70. ];
  71. $parameters['paySign'] = $this->signture($parameters, $config['key']);
  72. return $this->success($parameters);
  73. }
  74. public function wxminiPayOffline(WxminiPayRequest $request){
  75. $data = $request->validated();
  76. $config = config('wxpay');
  77. $app = Factory::payment($config);
  78. $app['guzzle_handler'] = CoroutineHandler::class;
  79. // 待支付的,未超时(15min,900sec)的订单
  80. $orderMain = OrderMain::query()
  81. ->where(['dm_state' => OrderMain::ORDER_STATE_UNPAY, 'id' => $data['order_id']])
  82. ->first();
  83. if (empty($orderMain)) {
  84. return $this->result(ErrorCode::PAY_FAILURE, $data,'订单不存在或已失效');
  85. }
  86. $result = $app->order->unify([
  87. 'body' => '懒族生活 - 当面支付',
  88. 'out_trade_no' => $orderMain->global_order_id,
  89. 'total_fee' => bcmul(floatval($orderMain->money), 100, 0),
  90. 'notify_url' => config('site_host') . '/wechat/notify/wxminioffline',
  91. 'trade_type' => 'JSAPI',
  92. 'openid' => $data['openid'],
  93. ]);
  94. // 返回支付参数给前端
  95. $parameters = [
  96. 'appId' => $result['appid'],
  97. 'timeStamp' => '' . time() . '',
  98. 'nonceStr' => uniqid(),
  99. 'package' => 'prepay_id=' . $result['prepay_id'],
  100. 'signType' => 'MD5'
  101. ];
  102. $parameters['paySign'] = $this->signture($parameters, $config['key']);
  103. return $this->success($parameters);
  104. }
  105. /**
  106. * 支付参数加签
  107. * @param $parameters
  108. * @param $key
  109. * @return string
  110. */
  111. private function signture($parameters, $key)
  112. {
  113. // 按字典序排序参数
  114. ksort($parameters);
  115. // http_query
  116. $queryParams = $this->http_query($parameters);
  117. // 加入KEY
  118. $queryParams = $queryParams . "&key=" . $key;
  119. // MD5加密
  120. $queryParams = md5($queryParams);
  121. // 字符转为大写
  122. return strtoupper($queryParams);
  123. }
  124. /**
  125. * 参数转为http query字串
  126. * @param $parameters
  127. * @return string
  128. */
  129. private function http_query($parameters) {
  130. $http_query = [];
  131. foreach ($parameters as $key => $value) {
  132. $http_query[] = $key.'='.$value;
  133. }
  134. return implode('&', $http_query);
  135. }
  136. }