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.
383 lines
13 KiB
383 lines
13 KiB
<?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\Order;
|
|
use App\Model\v3\OrderGoods;
|
|
use App\Model\v3\OrderMain;
|
|
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\SeparateAccountsServiceInterface;
|
|
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;
|
|
|
|
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);
|
|
|
|
// 优惠券返券
|
|
$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->miniprogramService->sendTemMsgForOnlineOrder($orderMain->global_order_id);
|
|
|
|
// 打印订单,自动打印
|
|
$res = $this->feiePrintService->feiePrint($orderMain->global_order_id);
|
|
|
|
Db::commit();
|
|
|
|
// 记录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);
|
|
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);
|
|
|
|
// 喇叭通知,兼容旧音响,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);
|
|
|
|
Db::commit();
|
|
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()
|
|
->whereIn('state', [OrderState::PAID, OrderState::DELIVERY, OrderState::COMPLETED, OrderState::EVALUATED, OrderState::REFUNDING])
|
|
->where(['global_order_id' => $message['global_order_id'], 'pay_type' => Payment::WECHAT, 'refund_time' => 0])
|
|
->first();
|
|
|
|
// 订单不存在
|
|
if (empty($orderMain)) {
|
|
$this->log->event(
|
|
LogLabel::ORDER_REFUND_NOTIFY_LOG,
|
|
['global_order_id_fail' => $message['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();
|
|
foreach ($orderGoods as $key => &$item) {
|
|
$this->goodsActivityService->clearCacheRecord($item['goods_id'], $item['number'], $orderMain->userId);
|
|
}
|
|
|
|
// 添加用户的流水
|
|
$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()));
|
|
}
|
|
}
|