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.

160 lines
4.7 KiB

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