Browse Source

当面付支付通知

master
weigang 5 years ago
parent
commit
e952ee31ea
  1. 167
      app/Controller/NotifyController.php
  2. 9
      app/Model/StoreAccount.php
  3. 66
      app/Service/MiniprogramService.php
  4. 32
      app/Service/MiniprogramServiceInterface.php
  5. 76
      app/Service/UserService.php
  6. 28
      app/Service/UserServiceInterface.php

167
app/Controller/NotifyController.php

@ -10,11 +10,14 @@ use App\Model\OrderMain;
use App\Model\OrderSalesStatistic;
use App\Model\SpecCombination;
use App\Model\Store;
use App\Model\StoreAccount;
use App\Model\SystemConfig;
use App\Model\Users;
use App\Service\DeviceServiceInterface;
use App\Service\FeiePrintServiceInterface;
use App\Service\MiniprogramService;
use App\Service\MqttServiceInterface;
use App\Service\UserServiceInterface;
use EasyWeChat\Factory;
use Hyperf\DbConnection\Db;
use Hyperf\Guzzle\CoroutineHandler;
@ -50,6 +53,12 @@ class NotifyController extends BaseController
*/
protected $feiePrintService;
/**
* @Inject
* @var UserServiceInterface
*/
protected $userService;
public function wxminiOnline()
{
@ -202,33 +211,159 @@ class NotifyController extends BaseController
$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) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
$message
);
Db::beginTransaction();
try {
// 支付失败或者通知失败
if (
empty($message)
|| $message['return_code'] != 'SUCCESS'
|| !isset($message['result_code'])
|| $message['result_code'] != 'SUCCESS'
) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
$message
);
Db::rollBack();
$fail('Unknown error but FAIL');
}
// 查询订单
$orderMain = OrderMain::query()
->where(['global_order_id' => $message['out_trade_no'], 'type' => OrderMain::ORDER_TYPE_OFFLINE, 'state' => OrderMain::ORDER_STATE_UNPAY])
->where('time', '>=', date('Y-m-d H:i:s', (time()-900)))
->first();
// 查询订单
$orderMain = OrderMain::query()
->where([
'global_order_id' => $message['out_trade_no'],
'type' => OrderMain::ORDER_TYPE_OFFLINE
])
->first();
if (empty($orderMain)) {
// 去查一下微信订单
$wxOrder = $app->order->queryByOutTradeNumber($orderMain->global_order_id);
// 订单不存在
if (empty($orderMain)) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
['global_order_id_fail' => $message['out_trade_no']]
);
Db::rollBack();
return true;
}
// 修改订单、子订单状态
$currentTime = time();
$orderMain->state = OrderMain::ORDER_STATE_UNTAKE;
$orderMain->dm_state = OrderMain::ORDER_STATE_UNTAKE;
$orderMain->time_pay = $currentTime;
$orderMain->pay_time = date('Y-m-d H:i:s', $currentTime);
$orderMain->save();
// 查询子订单,当面付目前实际上只有一个子订单
$orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time'])
->where(['order_main_id' => $orderMain->id])
->get()
->toArray();
// 商户钱包、流水资金、奖励、发布模板消息处理
foreach ($orders as $key => $orderItem) {
$recordBase = [
'user_id' => $orderItem['user_id'],
'order_id' => $orderItem['id'],
'store_id' => $orderItem['store_id'],
'type' => 1,
'time' => date('Y-m-d H:i:s', $currentTime),
'add_time' => $currentTime,
];
// 钱包
$store = Store::find($orderItem['store_id']);
$store->store_wallet = bcadd($store->store_wallet, $orderItem['money'], 2);
$store->save();
// 流水
$record = [
'money' => $orderItem['money'],
'note' => '当面付订单收入',
'category' => 2,
];
StoreAccount::query()->insert(array($recordBase, $record));
// 平台新用户奖励给商户
$isStageNewUser = $this->userService->isStageNewUser($orderItem['user_id']);
$needAward = false;
$awardAmount = 0;
if ($isStageNewUser) {
$awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_new_user'])->value('value');
// 流水
$record = [
'money' => $awardAmount,
'note' => '新用户下单成功,平台奖励',
'category' => 3,
];
$needAward = true;
} else {
$isStoreFirstOrderToday = $this->userService->isStoreFirstOrderToday($orderItem['user_id'],$orderItem['store_id'],$orderItem['id']);
if ($isStoreFirstOrderToday) {
$awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_each_order'])->value('value');
// 流水
$record = [
'money' => $awardAmount,
'note' => '用户下单成功,平台奖励',
'category' => 4,
];
$needAward = true;
}
}
if ($needAward && $awardAmount) {
// 奖励钱包
$store->refresh();
$store->award_money = bcadd($store->award_money, $awardAmount, 2);
$store->save();
// 流水
StoreAccount::query()->insert(array($recordBase, $record));
// 发布公众号消息
$openid = Users::query()->where(['id' => $store['user_id']])->value('openid');
$res = $this->miniprogramService->sendTemMsgForAward($record['money'], $record['note'], $openid, $recordBase['time']);
}
}
// 喇叭通知,兼容旧音响,MQTT+IOT
$res = $this->mqttSpeakerService->speakToStore($orderMain->id);
$res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->id);
// 公众号模板消息
$res = $this->miniprogramService->sendTemMsgForOfflineOrder($orderMain->id);
Db::commit();
return true;
} catch (Exception $e) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
$wxOrder
['exception_fail' => $e->getMessage()]
);
// return true;
Db::rollBack();
$fail('Exception');
}
});
$response->send();
return $this->response
->withHeader('Content-Type', 'text/xml')
->withStatus(200)
->withBody(new SwooleStream($response->getContent()));
}
}

9
app/Model/StoreAccount.php

@ -0,0 +1,9 @@
<?php
namespace App\Model;
class StoreAccount extends Model
{
protected $table = 'ims_cjdc_store_account';
public $timestamps = false;
}

66
app/Service/MiniprogramService.php

@ -15,6 +15,9 @@ use Hyperf\Guzzle\CoroutineHandler;
class MiniprogramService implements MiniprogramServiceInterface
{
/**
* @inheritDoc
*/
public function sendTemMsgForOnlineOrder($order_main_id)
{
@ -34,8 +37,6 @@ class MiniprogramService implements MiniprogramServiceInterface
$goods_temp_all = [];
foreach ($order_children as $key => &$item) {
$item = (array)$item;
// 订单商品
$order_goods = OrderGoods::query()->select(['name', 'number', 'spec', 'good_unit'])
->where(['order_id' => $item['id']])
@ -91,6 +92,67 @@ class MiniprogramService implements MiniprogramServiceInterface
}
/**
* @inheritDoc
*/
public function sendTemMsgForOfflineOrder($order_main_id)
{
// 查询子订单,用于发消息给商户
$order_children = Order::query()->select(['id', 'order_num', 'store_id', 'money', 'time'])
->where(['order_main_id' => $order_main_id])
->get()
->toArray();
foreach ($order_children as $key => &$item) {
// 商户/门店的openid
$store = Store::query()->select(['id', 'name', 'user_id'])
->where(['id' => $item['store_id']])
->first()->toArray();
$store['openid'] = Users::query()
->where(['id' => $store['user_id']])
->value('openid');
// 模板数据
$data_store = [
'first' => '您有新订单收入!订单编号:'.$item['order_num'],
'keyword' => [
$store['name']?:'',
$item['time']?:'',
'暂无',
$item['money']
],
'remark' => '感谢您的使用!'
];
$ret_store = $this->sendTempMsg($store['openid'], 'lxVbC6PVpKbiO44bYqLmacl-BaME70D47Q0jn2Link0',$data_store);
}
}
/**
* @inheritDoc
*/
public function sendTemMsgForAward($money, $note, $openid, $time)
{
// 模板数据发送消息给用户
$data_user = [
'first' => '恭喜!您有一笔新的奖励收入!',
'keyword' => [
$money,
$note,
$time
],
'remark' => '感谢您的使用!'
];
// 获取用户openid,发送给用户
$ret_user = $this->sendTempMsg($openid,'ypZ7xdHUjWrRG8P-MD42dhpp6kUlh4Unoh7eTSrLZEg', $data_user);
}
/**
* @inheritDoc
*/
public function sendTempMsg($openid, $template_id, $data, $redirect_url = '', $applet_config = ['appid' => '', 'pagepath' => ''])
{
// 先拼个基础的

32
app/Service/MiniprogramServiceInterface.php

@ -4,6 +4,38 @@ namespace App\Service;
interface MiniprogramServiceInterface
{
/**
* 外卖线上订单模板消息
* @param $order_main_id
* @return mixed
*/
public function sendTemMsgForOnlineOrder($order_main_id);
/**
* 当面线下订单模板消息
* @param $order_main_id
* @return mixed
*/
public function sendTemMsgForOfflineOrder($order_main_id);
/**
* 奖励模板消息
* @param $money
* @param $note
* @param $openid
* @param $time
* @return mixed
*/
public function sendTemMsgForAward($money, $note, $openid, $time);
/**
* 发送模板消息
* @param $openid
* @param $template_id
* @param $data
* @param string $redirect_url
* @param string[] $applet_config
* @return mixed
*/
public function sendTempMsg($openid, $template_id, $data, $redirect_url = '', $applet_config = ['appid' => '', 'pagepath' => '']);
}

76
app/Service/UserService.php

@ -0,0 +1,76 @@
<?php
namespace App\Service;
use App\Model\Order;
use App\Model\OrderMain;
use App\Model\Users;
class UserService implements UserServiceInterface
{
/**
* 是否平台新用户
* 在很多奖励的地方会需要用到这个查询
* 判定条件:
* 没有在平台下过单(包括线上和线下)
* @param $user_id
* @return mixed|void
*/
public function isStageNewUser($user_id): bool
{
$exist = OrderMain::query()
->where(['user_id' => $user_id])
->where(function ($query){
$query->where('state', 'in', [4,5,10])
->orWhere('dm_state', 'in', [2,3]);
})
->exists();
return !$exist;
}
/**
* 根据用户的openid更新unionid信息
* 如果没有找到用户,则不做任何处理
* @param $openid
* @param $unionid
* @return array
*/
public function saveUserUnionid($openid,$unionid)
{
$result = [
'status' => false,
'msg' => '用户不存在或者已存在相同unionid'
];
// 查询用户是否存在
$userinfo = Users::select('id','unionid')->where('openid',$openid)->first();
if($userinfo && $userinfo->unionid != $unionid){
$userinfo->unionid = $unionid;
if($res = $userinfo->save()){
$result['status'] = true;
$result['msg'] = '更改用户unionid信息成功';
$result['res'] = $res;
}else{
$result['msg'] = '更改用户unionid信息失败';
}
}
return $result;
}
/**
* @inheritDoc
*/
public function isStoreFirstOrderToday($user_id, $store_id, $current_order_id, $limit_amount = 3)
{
return !Order::query()
->where(['user_id' => $user_id, 'store_id' => $store_id, 'dm_state' => 2])
->where('time_add', '>=', date('Y-m-d 00:00:00'))
->where('time_add', '<=', date('Y-m-d 23:59:59'))
->where('money', '>=', $limit_amount)
->where('id', '!=', $current_order_id)
->exists();
}
}

28
app/Service/UserServiceInterface.php

@ -0,0 +1,28 @@
<?php
namespace App\Service;
interface UserServiceInterface
{
/**
* 是否平台新用户
* @param $user_id
* @return mixed
*/
public function isStageNewUser($user_id): bool;
public function saveUserUnionid($openid,$unionid);
/**
* 是否店铺当日首单
* @param $user_id
* @param $store_id
* @param $current_order_id
* @param int $limit_amount
* @return mixed
*/
public function isStoreFirstOrderToday($user_id, $store_id, $current_order_id, $limit_amount = 3);
}
Loading…
Cancel
Save