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.

249 lines
7.8 KiB

6 years ago
  1. <?php
  2. namespace App\Controller\v3;
  3. use App\Constants\v3\LogLabel;
  4. use App\Constants\v3\OrderType;
  5. use App\Controller\BaseController;
  6. use App\Model\v3\OrderMain;
  7. use App\Service\v3\Interfaces\CouponRebateServiceInterface;
  8. use App\Service\v3\Interfaces\DeviceServiceInterface;
  9. use App\Service\v3\Interfaces\FeiePrintServiceInterface;
  10. use App\Service\v3\Interfaces\MiniprogramServiceInterface;
  11. use App\Service\v3\Interfaces\MqttServiceInterface;
  12. use App\Service\v3\Interfaces\UserServiceInterface;
  13. use EasyWeChat\Factory;
  14. use Hyperf\DbConnection\Db;
  15. use Hyperf\Guzzle\CoroutineHandler;
  16. use Exception;
  17. use Hyperf\Di\Annotation\Inject;
  18. use Hyperf\HttpMessage\Stream\SwooleStream;
  19. use Symfony\Component\HttpFoundation\Request;
  20. class NotifyController extends BaseController
  21. {
  22. /**
  23. * @Inject
  24. * @var MqttServiceInterface
  25. */
  26. protected $mqttService;
  27. /**
  28. * @Inject
  29. * @var DeviceServiceInterface
  30. */
  31. protected $deviceService;
  32. /**
  33. * @Inject
  34. * @var MiniprogramServiceInterface
  35. */
  36. protected $miniprogramService;
  37. /**
  38. * @Inject
  39. * @var FeiePrintServiceInterface
  40. */
  41. protected $feiePrintService;
  42. /**
  43. * @Inject
  44. * @var UserServiceInterface
  45. */
  46. protected $userService;
  47. /**
  48. * @Inject
  49. * @var CouponRebateServiceInterface
  50. */
  51. protected $couponRebateService;
  52. /**
  53. * @Inject
  54. * @var OrderServiceInterface
  55. */
  56. protected $orderService;
  57. /**
  58. * @Inject
  59. * @var SeparateAccountsServiceInterface
  60. */
  61. protected $separateAccountsService;
  62. public function wxminiOnline()
  63. {
  64. $config = config('wxpay');
  65. $app = Factory::payment($config);
  66. $app['guzzle_handler'] = CoroutineHandler::class;
  67. $get = $this->request->getQueryParams();
  68. $post = $this->request->getParsedBody();
  69. $cookie = $this->request->getCookieParams();
  70. $files = $this->request->getUploadedFiles();
  71. $server = $this->request->getServerParams();
  72. $xml = $this->request->getBody()->getContents();
  73. $app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
  74. // 通知回调,进行业务处理
  75. $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
  76. Db::beginTransaction();
  77. try {
  78. // 支付失败或者通知失败
  79. if (
  80. empty($message)
  81. || $message['return_code'] != 'SUCCESS'
  82. || !isset($message['result_code'])
  83. || $message['result_code'] != 'SUCCESS'
  84. ) {
  85. $this->log->event(
  86. LogLabel::PAY_NOTIFY_WXMINI,
  87. $message
  88. );
  89. Db::rollBack();
  90. return $fail('Unknown error but FAIL');
  91. }
  92. // 查询订单
  93. $orderMain = OrderMain::query()
  94. ->where([
  95. 'global_order_id' => $message['out_trade_no'],
  96. 'type' => OrderType::ONLINE
  97. ])
  98. ->first();
  99. // 订单不存在
  100. if (empty($orderMain) || $orderMain->state == OrderMain::ORDER_STATE_DELIVERY) {
  101. $this->log->event(
  102. LogLabel::PAY_NOTIFY_WXMINI,
  103. ['global_order_id_fail' => $message['out_trade_no']]
  104. );
  105. Db::rollBack();
  106. return true;
  107. }
  108. $this->orderService->onlinePaid($message['out_trade_no']);
  109. $this->separateAccountsService->orderOnlinePaid($message['out_trade_no']);
  110. // 优惠券返券
  111. $this->couponRebateService->couponRebateInTask($orderMain->id);
  112. // 喇叭通知,兼容旧音响,MQTT+IOT
  113. $res = $this->mqttService->speakToStore($orderMain->id);
  114. $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->id);
  115. // 公众号模板消息
  116. $res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->id);
  117. // 打印订单,自动打印
  118. $res = $this->feiePrintService->feiePrint($orderMain->global_order_id);
  119. Db::commit();
  120. return true;
  121. } catch (Exception $e) {
  122. $this->log->event(
  123. LogLabel::PAY_NOTIFY_WXMINI,
  124. ['exception_fail' => $e->getMessage()]
  125. );
  126. Db::rollBack();
  127. return $fail('Exception');
  128. }
  129. });
  130. return $this->response
  131. ->withHeader('Content-Type', 'text/xml')
  132. ->withStatus(200)
  133. ->withBody(new SwooleStream($response->getContent()));
  134. }
  135. public function wxminiOffline()
  136. {
  137. $config = config('wxpay');
  138. $app = Factory::payment($config);
  139. $app['guzzle_handler'] = CoroutineHandler::class;
  140. $get = $this->request->getQueryParams();
  141. $post = $this->request->getParsedBody();
  142. $cookie = $this->request->getCookieParams();
  143. $files = $this->request->getUploadedFiles();
  144. $server = $this->request->getServerParams();
  145. $xml = $this->request->getBody()->getContents();
  146. $app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
  147. // 通知回调,进行业务处理
  148. $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
  149. Db::beginTransaction();
  150. try {
  151. // 支付失败或者通知失败
  152. if (
  153. empty($message)
  154. || $message['return_code'] != 'SUCCESS'
  155. || !isset($message['result_code'])
  156. || $message['result_code'] != 'SUCCESS'
  157. ) {
  158. $this->log->event(
  159. LogLabel::PAY_NOTIFY_WXMINI,
  160. $message
  161. );
  162. Db::rollBack();
  163. return $fail('Unknown error but FAIL');
  164. }
  165. // 查询订单
  166. $orderMain = OrderMain::query()
  167. ->where([
  168. 'global_order_id' => $message['out_trade_no'],
  169. 'type' => OrderMain::ORDER_TYPE_OFFLINE
  170. ])
  171. ->first();
  172. // 订单不存在
  173. if (empty($orderMain)) {
  174. $this->log->event(
  175. LogLabel::PAY_NOTIFY_WXMINI,
  176. ['global_order_id_fail' => $message['out_trade_no']]
  177. );
  178. Db::rollBack();
  179. return true;
  180. }
  181. $orderPaid = $this->orderService->offlinePaid($message['out_trade_no']);
  182. $separate = $this->separateAccountsService->orderOfflinePaid($message['out_trade_no']);
  183. // 喇叭通知,兼容旧音响,MQTT+IOT
  184. $res = $this->mqttService->speakToStore($orderMain->id);
  185. $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->id);
  186. // 公众号模板消息
  187. $res = $this->miniprogramService->sendTemMsgForOfflineOrder($orderMain->id);
  188. Db::commit();
  189. return true;
  190. } catch (Exception $e) {
  191. $this->log->event(
  192. LogLabel::PAY_NOTIFY_WXMINI,
  193. ['exception_fail' => $e->getMessage()]
  194. );
  195. Db::rollBack();
  196. return $fail('Exception');
  197. }
  198. });
  199. return $this->response
  200. ->withHeader('Content-Type', 'text/xml')
  201. ->withStatus(200)
  202. ->withBody(new SwooleStream($response->getContent()));
  203. }
  204. }