|
|
<?php
namespace App\Controller\v3;
use App\Constants\v3\LogLabel;use App\Constants\v3\OrderState;use App\Constants\v3\OrderType;use App\Constants\v3\Payment;use App\Controller\BaseController;use App\Model\v3\Goods;use App\Model\v3\GoodsActivity;use App\Model\v3\Order;use App\Model\v3\OrderGoods;use App\Model\v3\OrderMain;use App\Model\v3\User;use App\Service\v3\Interfaces\BadgeServiceInterface;use App\Service\v3\Interfaces\CouponRebateServiceInterface;use App\Service\v3\Interfaces\CouponServiceInterface;use App\Service\v3\Interfaces\DeviceServiceInterface;use App\Service\v3\Interfaces\FeiePrintServiceInterface;use App\Service\v3\Interfaces\FinancialRecordServiceInterface;use App\Service\v3\Interfaces\GoodsActivityServiceInterface;use App\Service\v3\Interfaces\MiniprogramServiceInterface;use App\Service\v3\Interfaces\MqttServiceInterface;use App\Service\v3\Interfaces\OrderOfflineServiceInterface;use App\Service\v3\Interfaces\OrderOnlineServiceInterface;use App\Service\v3\Interfaces\OrderStatisticsServiceInterface;use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;use App\Service\v3\Interfaces\UserInfoServiceInterface;use EasyWeChat\Factory;use Hyperf\DbConnection\Db;use Hyperf\Guzzle\CoroutineHandler;use Exception;use Hyperf\Di\Annotation\Inject;use Hyperf\HttpMessage\Stream\SwooleStream;use Symfony\Component\HttpFoundation\Request;
class NotifyController extends BaseController{
/** * @Inject * @var MqttServiceInterface */ protected $mqttService;
/** * @Inject * @var DeviceServiceInterface */ protected $deviceService;
/** * @Inject * @var MiniprogramServiceInterface */ protected $miniprogramService;
/** * @Inject * @var FeiePrintServiceInterface */ protected $feiePrintService;
/** * @Inject * @var CouponRebateServiceInterface */ protected $couponRebateService;
/** * @Inject * @var OrderOnlineServiceInterface */ protected $orderOnlineService;
/** * @Inject * @var OrderOfflineServiceInterface */ protected $orderOfflineService;
/** * @Inject * @var SeparateAccountsServiceInterface */ protected $separateAccountsService;
/** * @Inject * @var CouponServiceInterface */ protected $couponService;
/** * @Inject * @var FinancialRecordServiceInterface */ protected $financialService;
/** * @Inject * @var BadgeServiceInterface */ protected $badgeService;
/** * @Inject * @var GoodsActivityServiceInterface */ protected $goodsActivityService;
/** * @Inject * @var OrderStatisticsServiceInterface */ protected $orderStatisticsService;
/** * @Inject * @var UserInfoServiceInterface */ protected $userInfoService;
public function wxminiOnline() {
$config = config('wxpay'); $app = Factory::payment($config); $app['guzzle_handler'] = CoroutineHandler::class;
$get = $this->request->getQueryParams(); $post = $this->request->getParsedBody(); $cookie = $this->request->getCookieParams(); $files = $this->request->getUploadedFiles(); $server = $this->request->getServerParams(); $xml = $this->request->getBody()->getContents();
$app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
// 通知回调,进行业务处理
$response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
Db::beginTransaction(); try { // 支付失败或者通知失败
if ( empty($message) || $message['return_code'] != 'SUCCESS' || !isset($message['result_code']) || $message['result_code'] != 'SUCCESS' ) { $this->log->event( LogLabel::ORDER_ONLINE_PAY_NOTIFY_LOG, $message ); Db::rollBack(); return $fail('Unknown error but FAIL'); }
// 查询订单
$orderMain = OrderMain::query() ->where(['global_order_id' => $message['out_trade_no'],'type' => OrderType::ONLINE,'state' => OrderState::UNPAID]) ->first();
// 订单不存在
if (empty($orderMain)) { $this->log->event( LogLabel::ORDER_ONLINE_PAY_NOTIFY_LOG, ['global_order_id_fail' => $message['out_trade_no']] ); Db::rollBack(); return true; }
$this->orderOnlineService->doByPaid($orderMain->global_order_id); $this->separateAccountsService->orderOnlinePaid($orderMain->global_order_id);
Db::commit();
//记录当前市场的当天外卖订单数
$this->orderStatisticsService->setForMarket($orderMain->market_id);
// 优惠券返券
$this->couponRebateService->couponRebateInTask($orderMain->global_order_id);
// 喇叭通知,兼容旧音响,MQTT+IOT
$res = $this->mqttService->speakToStore($orderMain->global_order_id); $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->global_order_id);
// 打印订单,自动打印
$res = $this->feiePrintService->feiePrint($orderMain->global_order_id);
// 记录badge
$orderChildIds = Order::query()->where(['order_main_id' => $orderMain->global_order_id])->pluck('store_id'); $this->badgeService->doByOrder($orderMain->user_id, $orderChildIds, $orderMain->global_order_id, OrderState::PAID);
// 公众号模板消息
$res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->global_order_id);
co(function () use ($orderMain) { $openid = User::query()->where(['id' => $orderMain->user_id])->value('openid'); $unionid = $this->userInfoService->getPaidUnionId($openid, ['mch_id' => config('wxpay.mch_id'), 'out_trade_no' => $orderMain->global_order_id]); if ($unionid) { User::query()->where(['id' => $orderMain->user_id, 'openid' => $openid])->update(['unionid' => $unionid]); } });
return true;
} catch (Exception $e) {
$this->log->event( LogLabel::ORDER_ONLINE_PAY_NOTIFY_LOG, ['exception_fail' => $e->getMessage()] ); Db::rollBack(); return $fail('Exception'); }
});
return $this->response ->withHeader('Content-Type', 'text/xml') ->withStatus(200) ->withBody(new SwooleStream($response->getContent()));
}
public function wxminiOffline() {
$config = config('wxpay'); $app = Factory::payment($config); $app['guzzle_handler'] = CoroutineHandler::class;
$get = $this->request->getQueryParams(); $post = $this->request->getParsedBody(); $cookie = $this->request->getCookieParams(); $files = $this->request->getUploadedFiles(); $server = $this->request->getServerParams(); $xml = $this->request->getBody()->getContents();
$app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
// 通知回调,进行业务处理
$response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
Db::beginTransaction(); try { // 支付失败或者通知失败
if ( empty($message) || $message['return_code'] != 'SUCCESS' || !isset($message['result_code']) || $message['result_code'] != 'SUCCESS' ) { $this->log->event( LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG, $message ); Db::rollBack(); return $fail('Unknown error but FAIL'); }
// 查询订单
$orderMain = OrderMain::query() ->where([ 'global_order_id' => $message['out_trade_no'], 'type' => OrderType::OFFLINE, 'state' => OrderState::UNPAID ]) ->first();
// 订单不存在
if (empty($orderMain)) { $this->log->event( LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG, ['global_order_id_fail' => $message['out_trade_no']] ); Db::rollBack(); return true; }
$orderPaid = $this->orderOfflineService->doByPaid($orderMain->global_order_id); $separate = $this->separateAccountsService->orderOfflinePaid($orderMain->global_order_id);
Db::commit();
// 喇叭通知,兼容旧音响,MQTT+IOT
$res = $this->mqttService->speakToStore($orderMain->global_order_id); $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->global_order_id);
// 公众号模板消息
$res = $this->miniprogramService->sendTemMsgForOfflineOrder($orderMain->global_order_id);
co(function () use ($orderMain) { $openid = User::query()->where(['id' => $orderMain->user_id])->value('openid'); $unionid = $this->userInfoService->getPaidUnionId($openid, ['mch_id' => config('wxpay.mch_id'), 'out_trade_no' => $orderMain->global_order_id]); if ($unionid) { User::query()->where(['id' => $orderMain->user_id, 'openid' => $openid])->update(['unionid' => $unionid]); } });
return true;
} catch (Exception $e) {
$this->log->event( LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG, ['exception_fail' => $e->getMessage()] ); Db::rollBack(); return $fail('Exception'); }
});
return $this->response ->withHeader('Content-Type', 'text/xml') ->withStatus(200) ->withBody(new SwooleStream($response->getContent())); }
public function wxminiRefund() {
$config = config('wxpay'); $app = Factory::payment($config); $app['guzzle_handler'] = CoroutineHandler::class;
$get = $this->request->getQueryParams(); $post = $this->request->getParsedBody(); $cookie = $this->request->getCookieParams(); $files = $this->request->getUploadedFiles(); $server = $this->request->getServerParams(); $xml = $this->request->getBody()->getContents();
$app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
// 通知回调,进行业务处理
$response = $app->handleRefundedNotify(function ($message, $reqInfo, $fail) use ($app) {
Db::beginTransaction(); try { // 支付失败或者通知失败
if ( empty($message) || $message['return_code'] != 'SUCCESS' || !isset($reqInfo['refund_status']) || $reqInfo['refund_status'] != 'SUCCESS' ) { $this->log->event( LogLabel::ORDER_REFUND_NOTIFY_LOG, array_merge($message, $reqInfo) ); Db::rollBack(); return $fail('Unknown error but FAIL'); }
// 查询订单
$orderMain = OrderMain::query() ->whereNotIn('state', [OrderState::UNPAID]) ->where(['global_order_id' => $reqInfo['out_trade_no'], 'pay_type' => Payment::WECHAT]) ->first();
// 订单不存在
if (empty($orderMain)) { $this->log->event( LogLabel::ORDER_REFUND_NOTIFY_LOG, ['global_order_id_fail' => $reqInfo['out_trade_no']] ); Db::rollBack(); return true; }
// 添加退款时间
$orderMain->refund_time = time(); $orderMain->state = OrderState::REFUNDED; $orderMain->save();
// 退款返还优惠券
$this->couponService->orderRefundCoupons($orderMain->global_order_id);
// 处理特价商品缓存
$orderChildren = Order::query()->where(['order_main_id' => $orderMain->global_order_id])->get()->toArray(); $orderGoods = OrderGoods::query() // ->where(['activity_type' => 2])
->whereIn('order_id', array_values(array_column($orderChildren, 'id')))->get()->toArray(); foreach ($orderGoods as $key => &$item) {
if ($item['activity_type'] == 2) { # 活动商品
$this->goodsActivityService->clearCacheRecord($item['goods_id'], $item['number'], $orderMain->user_id); $goods = GoodsActivity::find($item['goods_id']); } else { $goods = Goods::find($item['goods_id']); } $goods->inventory = $goods->inventory + $item['number']; $goods->sales = $goods->sales - $item['number']; $goods->save(); }
// 添加用户的流水
$this->financialService->userByOLOrderRefund($orderMain->user_id, $orderMain->global_order_id, $orderMain->money);
Db::commit();
// 记录badge
$orderChildIds = array_values(array_column($orderChildren, 'store_id')); $this->badgeService->doByOrder($orderMain->user_id, $orderChildIds, $orderMain->global_order_id, OrderState::REFUNDED); return true;
} catch (Exception $e) {
$this->log->event( LogLabel::ORDER_REFUND_NOTIFY_LOG, ['exception_fail' => $e->getMessage()] ); Db::rollBack(); return $fail('Exception'); }
});
return $this->response ->withHeader('Content-Type', 'text/xml') ->withStatus(200) ->withBody(new SwooleStream($response->getContent())); }}
|