food_server/FlyCube/MpApi/Controller/PayController.class.php
air 4cf7eecf07 【类 型】:fix
【原  因】:发送mqtt主题需要openid 并未取到此字段
【过  程】:从order列表里面取出openid
【影  响】:
2025-01-15 19:38:19 +08:00

157 lines
6.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace MpApi\Controller;
use Yansongda\Pay\Pay;
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\Exceptions\MqttClientException;
use PhpMqtt\Client\ConnectionSettings;
class PayController extends PublicController
{
/**
* @description: 初始化 pay类的参数
*/
public function _initialize()
{
// 初始化 pay类的参数
$this->config = [
'wechat' => [
'default' => [
'mch_id' => C('weixin')['mch_id'], // 必填-商户号
'mch_secret_key' => C('weixin')['mch_secret_key'], // 必填-v3商户秘钥
'mch_secret_cert' => C('weixin')['mch_secret_cert'], // 必填-商户私钥路径
'mch_public_cert_path' => C('weixin')['mch_public_cert_path'], // 必填-商户公钥证书路径
'notify_url' => C('host') . 'flycube.php/MpApi/Pay/notifyCallback', // 必填-回调通知地址
'mini_app_id' => C('weixin')['appid'], // 选填-小程序 的 app_id
'wechat_public_cert_path' => [ // 必填-微信平台公钥证书路径
'5878026B07BD819CCC25AC95FA31AE45BB6BC0D9' => C('weixin')['wechat_public_cert_path'],
],
],
],
'logger' => [ // 可选
'enable' => true,
'file' => C('weixin')['payLogger_path'],
'level' => 'info', // 建议生产环境等级调整为 info开发环境为 debug
'type' => 'single', // 可选, 可选 daily
'max_file' => 30, // 当 type 为 daily 时有效,默认 30 天
],
'http' => [ // 可选
'timeout' => 5.0,
'connect_timeout' => 5.0,
],
];
}
/**
* @description: Yansongda pay类的参数
*/
protected $config;
/**
* @description: 发起退款
*/
public function refund()
{
//父级构造函数
parent::_initialize();
// 总管理员 可接收任何shop_id 非总管理员 只可以调用自身shop_id 否则会中断
$this->isPower();
// post参数检查
if (!($_REQUEST['refund_price'] && $_REQUEST['order_sn'] && $_REQUEST['shop_id'] && ($_REQUEST['refund_type'] == 'buyer' || $_REQUEST['refund_type'] == 'seller'))) {
echo json_encode(array('status' => 0, 'msg' => '退款参数有误'));
exit();
}
// 获取订单信息
$where['shop_id'] = $_REQUEST['shop_id'];
$where['order_sn'] = $_REQUEST['order_sn'];
$field = array('order_sn,openid,total_price, transport_price, pack_price, pay_sn,main_status,shop_id');
$orderDb = D('order');
if (!$order = $orderDb->where($where)->field($field)->find()) {
echo json_encode(array('status' => 0, 'msg' => '订单不存在'));
exit();
}
if (($order['total_price'] + $order['transport_price'] + $order['pack_price']) < $_REQUEST['refund_price']) {
echo json_encode(array('status' => 0, 'msg' => '退款申请超额'));
exit();
}
if ($order['main_status'] == "已退款") {
// 构建发布主题 并向地面终端提示刷新信息
$topic = 'refreshQuestList/' . $order['shop_id'];
$this->publish($topic, 1);
echo json_encode(array('status' => 1, 'msg' => '此订单已完成退款'));
exit();
}
if ($order['main_status'] == "已完成") {
echo json_encode(array('status' => 0, 'msg' => '已完成订单不可申请退款'));
exit();
}
// 设置退款参数
$refundParameter = [
'out_trade_no' => $order['order_sn'], // 商户订单号
'out_refund_no' => $order['order_sn'] . '_' . $_REQUEST['refund_type'], // 商户退款单号
'amount' => [
'refund' => $_REQUEST['refund_price'] * 100, // 退款金额,单位:分
'total' => ($order['total_price'] + $order['transport_price'] + $order['pack_price']) * 100, // 订单金额 包括运费 打包费,单位:分
'currency' => 'CNY',
],
];
try {
// 调用退款接口
$result = Pay::wechat($this->config)->refund($refundParameter);
// 处理退款结果
echo json_encode(array('status' => 1, 'msg' => $result));
$topicPrefix = makeTopicPrefix($order['openid']); //小程序端用户订阅主题的前缀 ps:订单对应的用户的openid算出来的
// 提醒小程序端 刷新订单列表(mqtt)
$this->publish('refreshOrderList/' . $topicPrefix, 1);
} catch (\Exception $e) {
echo json_encode(array('status' => 0, 'msg' => $e->getMessage()));
}
}
/**
* @description: 退款成功后 腾讯服务器的回调
*/
public function notifyCallback()
{
try {
// 实例化 Yansongda Pay 并处理回调
$result = Pay::wechat($this->config)->callback();
// 验证成功,处理业务逻辑
if ($result['resource']['ciphertext']['refund_status'] == 'SUCCESS') {
$where['order_sn'] = $result['resource']['ciphertext']['out_trade_no']; // 获取订单号
$orderDb = D('order'); // 实例化订单模型
$data['main_status'] = "已退款"; // 更新订单状态为已退款
$data['refunded_time'] = time(); // 标记退款时间
$data['refund_sn'] = $result['resource']['ciphertext']['refund_id']; // 退款单号
$data['refund_price'] = $result['resource']['ciphertext']['amount']['refund'] / 100; // 退款金额,单位:元
$outRefundNo = $result['resource']['ciphertext']['out_refund_no'];
$refundType = substr($outRefundNo, strrpos($outRefundNo, '_') + 1); //截取退款类型
if ($refundType == "buyer") { //买家申请
$data['refund_status'] = "已同意";
} elseif ($refundType == "seller") { //卖家主动退
$data['refund_status'] = "主动退";
}
// 更新订单
$orderDb->where($where)->data($data)->save();
}
// 构建发布主题 并向地面终端提示刷新信息
$field = array('shop_id');
$order = $orderDb->where($where)->field($field)->find();
$topic = 'refreshQuestList/' . $order['shop_id'];
$this->publish($topic, 1);
} catch (\Exception $e) {
// 捕获并记录可能的异常
error_log('退款回调处理错误:' . $e->getMessage());
}
// 返回成功响应给腾讯服务器,告知通知已处理
return Pay::wechat()->success();
}
}