357 lines
13 KiB
PHP
357 lines
13 KiB
PHP
<?php
|
||
namespace addon\aliapp\model;
|
||
|
||
use app\model\BaseModel;
|
||
use think\Exception;
|
||
use think\facade\Db;
|
||
|
||
/**
|
||
* Common: 支付宝消息相关
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 14:52
|
||
* Class AliPayMessage
|
||
* @package addon\aliapp\model
|
||
*/
|
||
class AliPayMessage extends BaseModel{
|
||
|
||
protected $site_id;
|
||
|
||
public function __construct($siteId){
|
||
$this->site_id = $siteId;
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 订单中心 —— 订单同步
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 17:40
|
||
* @param int $zmOrderId zm_order表id
|
||
* @param string $orderStatus 订单状态
|
||
* @param string $refundPath 退款路径 例:花呗
|
||
* @return array
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
public function orderSynchronization(int $zmOrderId,string $orderStatus,string $refundPath = ''){
|
||
// $orderStatus 订单状态:下单成功=CREATE;已退款=REFUNDED;核销成功=FINISHED
|
||
$siteName = Db::name('site')->where('site_id',$this->site_id)->value('site_name');
|
||
if($siteName) return $this->error('','未设置店铺(站点)名称!');
|
||
// 参数获取
|
||
$appid = $this->getAppid();// 获取小程序id
|
||
$info = $this->getOrderInfo($zmOrderId);// 获取订单信息
|
||
$cardInfo = $this->getCardInfo($info['order_id']); // 获取用户会员卡id
|
||
$backUrl = $cardInfo['card_id'] > 0 ? 'pages/card/my_detail?card_id='.$cardInfo['card_id'] : 'pages/card/my_card';
|
||
$params = [
|
||
'out_biz_no' => $info['out_trade_no'],// 外部订单号
|
||
'buyer_id' => $info['userid'],// 买家userId
|
||
'amount' => $info['amount'],// 订单金额,单位为【元】
|
||
'pay_amount' => $info['amount'],// 支付金额,单位为【元】
|
||
'order_type' => 'SERVICE_ORDER',// 订单类型,新接入商户统一传入SERVICE_ORDER(服务订单)
|
||
//'discount_amount' => '',// 优惠金额,单位为【元】
|
||
//'trade_no' => $info['trade_no'],// 订单所对应的支付宝交易号
|
||
'order_create_time' => date('Y-m-d H:i:s',$info['create_time']),// 订单创建时间 当order_type为SERVICE_ORDER时必传 日期
|
||
'order_pay_time' => $info['pay_time'] > 0 ? date('Y-m-d H:i:s',$info['pay_time']) : '',// 订单支付时间 当pay_channel为非ALIPAY时 且订单状态已流转到“支付”或支付后时,需要将支付时间传入
|
||
//'send_msg' => 'Y',// 是否需要小程序订单代理发送模版消息,Y代表需要发送,N代表不需要发送,不传默认不发送
|
||
'ext_info' => [
|
||
['ext_key' => 'merchant_biz_type','ext_value' => 'MERCHANT_SECURITIES'],
|
||
['ext_key' => 'merchant_order_status','ext_value' => $orderStatus],
|
||
['ext_key' => 'tiny_app_id','ext_value' => $appid],
|
||
['ext_key' => 'merchant_order_link_page','ext_value' => $backUrl],
|
||
[
|
||
'ext_key' => 'business_info',
|
||
'ext_value' => json_encode([
|
||
//'note' => $note,
|
||
'refund_path' => $refundPath,
|
||
'expiration_time' => date('Y-m-d H:i:s',$cardInfo['end_time']),
|
||
'charge_off_time' => date('Y-m-d H:i:s',time()),
|
||
])
|
||
]
|
||
],
|
||
'order_modified_time' => date('Y-m-d H:i:s',time()),// 订单修改时间
|
||
'item_order_list' => $this->getGoodsInfo($info['order_id']), // 商品信息
|
||
'ticket_info' => [
|
||
'resv_type' => 'RESERVATION',
|
||
],
|
||
'shop_info' => [
|
||
'name' => $siteName,
|
||
],
|
||
];
|
||
// 发起请求
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.merchant.order.sync', $params,[]);
|
||
$result = $result['alipay_merchant_order_sync_response'];
|
||
if($result['code'] == 10000) {
|
||
|
||
return $this->success($result);
|
||
}else{
|
||
return $this->error('',$result['sub_msg']);
|
||
}
|
||
}
|
||
/**
|
||
* Common: 订单中心 —— 获取小程序id
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 16:15
|
||
* @return mixed
|
||
*/
|
||
public function getAppid(){
|
||
return Db::name('uni_account')
|
||
->where('site_id',$this->site_id)
|
||
->where('app_type','=','aliapp')
|
||
->value('appid');
|
||
}
|
||
/**
|
||
* Common: 订单中心 —— 订单信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 16:16
|
||
* @param $zmOrderId
|
||
* @return array|mixed|Db|\think\Model|null
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
public function getOrderInfo($zmOrderId){
|
||
$field = [
|
||
'zo.order_id',
|
||
'zo.userid',
|
||
'zo.amount',
|
||
'zo.trade_no',
|
||
'zo.create_time',
|
||
'zo.pay_time',
|
||
'zo.out_trade_no',
|
||
'order.order_no',
|
||
];
|
||
return Db::name('zm_order')
|
||
->alias('zo')
|
||
->field($field)
|
||
->join('order','zo.order_id = order.order_id','left')
|
||
->where('zo.id',$zmOrderId)
|
||
->find();
|
||
}
|
||
/**
|
||
* Common: 订单中心 —— 获取会员卡信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 16:44
|
||
* @param $orderId
|
||
* @return array|mixed|Db|\think\Model|null
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
public function getCardInfo($orderId){
|
||
return Db::name('member_goods_card')
|
||
->field('card_id,end_time')
|
||
->where('order_id',$orderId)
|
||
->find();
|
||
}
|
||
/**
|
||
* Common: 获取商品信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 16:28
|
||
* @param $orderId
|
||
* @return array
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
public function getGoodsInfo($orderId){
|
||
// 获取商品列表
|
||
$list = Db::name('order_goods')
|
||
->field('sku_name')
|
||
->where('order_id',$orderId)
|
||
->select();
|
||
if($list){
|
||
$list = $list->toArray();
|
||
$data = [];
|
||
// 循环处理
|
||
foreach($list as $item){
|
||
$data[] = [
|
||
'item_name' => $item['sku_name']
|
||
];
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
return [
|
||
['item_name' => '商品名称']
|
||
];
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 订阅消息发送 —— 开始
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 16:12
|
||
* @param $uid
|
||
* @param $keywords
|
||
* @param array $params
|
||
* @param string $page
|
||
* @return array
|
||
*/
|
||
public function sendMessage($uid,$keywords,$params = [],$page = 'pages/index/index'){
|
||
try{
|
||
// 通过用户user_id
|
||
$userId = Db::name('member')->where('member_id',$uid)->value('ali_openid');
|
||
if(!$userId) return $this->error('','用户不存在支付宝小程序user_id!');
|
||
// 判断:用户是否订阅当前消息
|
||
$subscribeInfo = $this->userIsSubscribeMessage($uid,$keywords);
|
||
// 消息发送
|
||
$sendData = $this->getSendData($keywords,$params);
|
||
$params = [
|
||
'to_user_id' => $userId,
|
||
'user_template_id' => $subscribeInfo['template_id'],
|
||
'page' => $page,
|
||
'data' => json_encode($sendData,JSON_UNESCAPED_UNICODE),
|
||
];
|
||
// 发起请求
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.open.app.mini.templatemessage.send', $params,[]);
|
||
$result = $result['alipay_open_app_mini_templatemessage_send_response'];
|
||
|
||
if($result['code'] == 10000) {
|
||
// 发送成功后的处理
|
||
Db::name('message_form_id')->where($subscribeInfo)->delete();// 删除记录
|
||
// 发送记录
|
||
$this->sendLog($keywords,$params,$result,1);
|
||
|
||
return $this->success($result);
|
||
}else{
|
||
// 发送记录
|
||
$this->sendLog($keywords,$params,$result,0);
|
||
|
||
return $this->error('',$result['sub_msg']);
|
||
}
|
||
}catch(Exception $e){
|
||
// 发送记录
|
||
$this->sendLog($keywords,$params,['error_msg'=>$e->getMessage()],0);
|
||
|
||
return $this->error('',$e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* Common: 订阅消息发送 —— 判断:用户是否订阅当前消息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 15:13
|
||
* @param $uid
|
||
* @param $keywords
|
||
* @return array|mixed|Db|\think\Model
|
||
* @throws Exception
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
private function userIsSubscribeMessage($uid,$keywords){
|
||
// 获取模板id
|
||
$templateId = Db::name('message')
|
||
->where('site_id',$this->site_id)
|
||
->where('keywords',$keywords)
|
||
->where('aliapp_is_open',1)
|
||
->value('aliapp_template_id');
|
||
if(!$templateId) throw new Exception('当前模板消息未开启或未设置!');
|
||
// 获取用户订阅消息
|
||
$subscribeInfo = Db::name('message_form_id')
|
||
->where('template_id',$templateId)
|
||
->where('uid',$uid)
|
||
->where('type','aliapp')
|
||
->order('create_time','ASC')
|
||
->find();
|
||
if(!$subscribeInfo) throw new Exception('当前用户未订阅该信息!');
|
||
|
||
return $subscribeInfo;
|
||
}
|
||
/**
|
||
* Common: 订阅消息发送 —— 获取发送信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 15:40
|
||
* @param $keywords
|
||
* @param $params
|
||
* @return mixed
|
||
* @throws Exception
|
||
*/
|
||
private function getSendData($keywords,$params){
|
||
// 键名转驼峰 方法名称
|
||
$nameArr = array_map(function($item){
|
||
return ucwords(strtolower($item));
|
||
},explode('_',$keywords));
|
||
$classList = get_class_methods(self::class);
|
||
$className = 'message'.implode($nameArr);
|
||
|
||
if(in_array($className,$classList)) return $this->$className($params);
|
||
else throw new Exception('未获取发送信息!');
|
||
}
|
||
/**
|
||
* Common: 订阅消息发送 —— 发送记录
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 16:10
|
||
* @param $keywords
|
||
* @param $params
|
||
* @param $sendResult
|
||
* @param $isSuccess
|
||
* @return int|string
|
||
*/
|
||
private function sendLog($keywords,$params,$sendResult,$isSuccess){
|
||
$sendLog = [
|
||
'site_id' => $this->site_id,
|
||
'keywords' => $keywords,
|
||
'message_type' => 'aliapp',
|
||
'addon' => '',
|
||
'title' => '',
|
||
'message_json' => json_encode($params,JSON_UNESCAPED_UNICODE),
|
||
'create_time' => time(),
|
||
'send_time' => time(),
|
||
'send_log' => json_encode($sendResult,JSON_UNESCAPED_UNICODE),
|
||
'is_success' => $isSuccess,
|
||
];
|
||
|
||
return Db::name('message_send_log')->insert($sendLog);
|
||
}
|
||
/**
|
||
* Common: 订阅消息发送信息 —— 权益即将过期通知
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 15:40
|
||
* @param $params
|
||
* @return array[]
|
||
*/
|
||
private function messageInterestExpirationNotice($params){
|
||
return [
|
||
'keyword1' => ['value' => $params['store_name']], // 商家名称
|
||
'keyword2' => ['value' => $params['surplus']],// 剩余次数
|
||
'keyword3' => ['value' => $params['content']],// 优惠内容
|
||
];
|
||
}
|
||
/**
|
||
* Common: 订阅消息发送信息 —— 服务开通成功提醒
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 15:40
|
||
* @param $params
|
||
* @return array[]
|
||
*/
|
||
private function messageServiceOpenedSuccess($params){
|
||
return [
|
||
'keyword1' => ['value' => $params['end_time']], // 到期时间 日期:2022年1月18日
|
||
'keyword2' => ['value' => $params['nickname']],// 姓名
|
||
'keyword3' => ['value' => $params['start_time']],// 开通时间 日期:2022年1月18日
|
||
'keyword4' => ['value' => $params['content']],// 服务项目
|
||
];
|
||
}
|
||
/**
|
||
* Common: 订阅消息发送信息 —— 核销提醒
|
||
* Author: wu-hui
|
||
* Time: 2023/01/10 15:40
|
||
* @param $params
|
||
* @return array[]
|
||
*/
|
||
private function messageVerify($params){
|
||
return [
|
||
'keyword1' => ['value' => $params['goods_name']], // 核销产品
|
||
'keyword2' => ['value' => $params['store_name']],// 核销商户
|
||
'keyword3' => ['value' => $params['start_time']],// 核销时间 日期:2022年1月18日
|
||
];
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
} |