作者 何书鹏
1 个管道 的构建 通过 耗费 2 秒

测试退款

... ... @@ -164,22 +164,24 @@ class Dispute extends Backend
$grab->status = '6';
$grab->save();
// 退定金到发单人余额
\app\api\model\User::money($order['deposit'],$order['user_id'],'售后已完成',['order_id'=>$row['order_id']]);
// 退款成功通知
$send_data = [
"first" => '亲,您的订单已成功退款,请稍候查收。',
"keyword1" => $order['order_sn'],
"keyword2" => $order['license_plate'],
"keyword3" => $order['deposit'],
"keyword4" => '退款成功',
"remark" => ['请点击查看详情','#FF0000'],
];
$openid = Third::where('user_id',$order['user_id'])->value('openid');
$templateid = config('tmplmsg.template')['refund_success'];
$url = config('tmplmsg.vue_url').'/wallet';
(new Wechat)->tmplmsg($openid,$send_data,$templateid,$url);
// // 退定金到发单人余额
// \app\api\model\User::money($order['deposit'],$order['user_id'],'售后已完成',['order_id'=>$row['order_id']]);
// 退款
(new Wechat)->refund($order,'售后已完成');
// // 退款成功通知
// $send_data = [
// "first" => '亲,您的订单已成功退款,请稍候查收。',
// "keyword1" => $order['order_sn'],
// "keyword2" => $order['license_plate'],
// "keyword3" => $order['deposit'],
// "keyword4" => '退款成功',
// "remark" => ['请点击查看详情','#FF0000'],
// ];
// $openid = Third::where('user_id',$order['user_id'])->value('openid');
// $templateid = config('tmplmsg.template')['refund_success'];
// $url = config('tmplmsg.vue_url').'/wallet';
// (new Wechat)->tmplmsg($openid,$send_data,$templateid,$url);
// 解绑隐私通话
\app\api\controller\Order::unbindPrivateNumber($row['order_id']);
... ...
... ... @@ -18,7 +18,7 @@ use think\Db;
*/
class Order extends Api
{
protected $noNeedLogin = ['dealAction','grabCountdown','payCountdown','cancelAction','unbindPrivateNumber'];
protected $noNeedLogin = ['dealAction','grabCountdown','payCountdown','cancelAction','payCountdownAction','unbindPrivateNumber'];
protected $noNeedRight = ['*'];
public function _initialize()
... ... @@ -412,8 +412,12 @@ class Order extends Api
if($order->grab_success){
$order->grab_success->save(['status'=>'7']);
}
// 变更会员余额
User::money($order['deposit'],$order['user_id'],'取消订单',['order_id' => $order['id']]);
// // 变更会员余额
// User::money($order['deposit'],$order['user_id'],'取消订单',['order_id' => $order['id']]);
// 退款
(new Wechat)->refund($order,'取消订单');
// 取消订单推送
$send_data = [
"first" => '你好,你的订单已经取消。',
... ... @@ -427,6 +431,7 @@ class Order extends Api
$templateid = config('tmplmsg.template')['order_cancel'];
$url = config('tmplmsg.vue_url').'/indentc?id='.$order['id'];
(new Wechat)->tmplmsg($openid,$send_data,$templateid,$url);
// 给发单用户发送"取消订单"通知
(new Message)->save([
'user_id' => $order['user_id'],
... ... @@ -435,20 +440,23 @@ class Order extends Api
'type' => '2',
'order_status' => '4',
]);
// 退款成功通知
$send_data = [
"first" => '亲,您的订单已成功退款,请稍候查收。',
"keyword1" => $order['order_sn'],
"keyword2" => $order['license_plate'],
"keyword3" => $order['deposit'],
"keyword4" => '退款成功',
"remark" => ['请点击查看详情','#FF0000'],
];
$templateid = config('tmplmsg.template')['refund_success'];
$url = config('tmplmsg.vue_url').'/wallet';
(new Wechat)->tmplmsg($openid,$send_data,$templateid,$url);
// // 退款成功通知
// $send_data = [
// "first" => '亲,您的订单已成功退款,请稍候查收。',
// "keyword1" => $order['order_sn'],
// "keyword2" => $order['license_plate'],
// "keyword3" => $order['deposit'],
// "keyword4" => '退款成功',
// "remark" => ['请点击查看详情','#FF0000'],
// ];
// $templateid = config('tmplmsg.template')['refund_success'];
// $url = config('tmplmsg.vue_url').'/wallet';
// (new Wechat)->tmplmsg($openid,$send_data,$templateid,$url);
// 解绑隐私通话
self::unbindPrivateNumber($order['id']);
return true;
}
... ... @@ -763,41 +771,59 @@ class Order extends Api
"data": null
})
*/
public function payCountdown()
{
$order_id = $this->request->param('order_id');
empty($order_id) && $this->error('缺少必需参数');
$order = $this->model->get($order_id,['grab_success']);
empty($order) && $this->error('订单信息不存在');
$order['status'] != '2' && $this->error('订单不合法');
Db::startTrans();
try{
$grab = $order['grab_success'];
$score = -10;
// 订单状态改为缴费超时
$grab->save(['status'=>'8','score'=>$score]);
$order->save(['status'=>'8']);
// 给抢单用户发送"缴费超时"通知
(new Message)->save([
'user_id' => $grab['user_id'],
'order_id' => $grab['order_id'],
'order_grab_id' => $grab['id'],
'type' => '1',
'grab_status' => '4',
]);
// 扣10积分
User::score($score,$grab['user_id'],'缴费超时',['order_id'=>$grab['order_id']]);
// 变更会员余额
User::money($order['deposit'],$order['user_id'],'接单人缴费超时',['order_id' => $order_id]);
// 解绑隐私通话
self::unbindPrivateNumber($order['id']);
Db::commit();
} catch (PDOException $e) {
Db::rollback();
} catch (Exception $e) {
Db::rollback();
}
$this->success('成功');
// public function payCountdown()
// {
// $order_id = $this->request->param('order_id');
// empty($order_id) && $this->error('缺少必需参数');
// $order = $this->model->get($order_id,['grab_success']);
// empty($order) && $this->error('订单信息不存在');
// $order['status'] != '2' && $this->error('订单不合法');
// Db::startTrans();
// try{
// self::payCountdownAction($order);
// Db::commit();
// } catch (PDOException $e) {
// Db::rollback();
// } catch (Exception $e) {
// Db::rollback();
// }
// $this->success('成功');
// }
/**
* @ApiInternal
* @ApiTitle (缴费倒计时结束-操作)
* @ApiSummary (缴费倒计时结束-操作)
*/
public static function payCountdownAction($order){
$grab = $order['grab_success'];
$score = -10;
// 订单状态改为缴费超时
$grab->save(['status'=>'8','score'=>$score]);
$order->save(['status'=>'8']);
// 给抢单用户发送"缴费超时"通知
(new Message)->save([
'user_id' => $grab['user_id'],
'order_id' => $grab['order_id'],
'order_grab_id' => $grab['id'],
'type' => '1',
'grab_status' => '4',
]);
// 扣10积分
User::score($score,$grab['user_id'],'缴费超时',['order_id'=>$grab['order_id']]);
// // 变更会员余额
// User::money($order['deposit'],$order['user_id'],'接单人缴费超时',['order_id' => $order_id]);
// 退款
(new Wechat)->refund($order,'接单人缴费超时');
// 解绑隐私通话
self::unbindPrivateNumber($order['id']);
return true;
}
/**
... ...
... ... @@ -181,6 +181,7 @@ class OrderGrab extends Api
// 只要有人抢单直接给他
$new_order = Order::get($order_id);
(new \app\api\controller\Order)->dealAction($new_order);
\think\Queue::later(config('countdown.pay'), '\app\api\job\OrderAutoOper@autoPayCancel', ['order_id'=>$order['id']], 'parking');
Db::commit();
} catch (PDOException $e) {
Db::rollback();
... ...
... ... @@ -30,7 +30,7 @@ class OrderAutoOper extends BaseJob
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
\think\Log::write('queue-' . get_class() . '-autoCancel' . ':执行失败,错误信息:' . $e->getMessage());
}
}
... ... @@ -54,4 +54,25 @@ class OrderAutoOper extends BaseJob
\think\Log::write('queue-' . get_class() . '-autoComplete' . ':执行失败,错误信息:' . $e->getMessage());
}
}
/**
* 订单缴费超时
*/
public function autoPayCancel(Job $job, $data){
try {
$order = Order::get($data['order_id']);
if ($order['status'] == '2') {
\think\Db::transaction(function () use ($order) {
\app\api\controller\Order::payCountdownAction($order);
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoPayCancel' . ':执行失败,错误信息:' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace app\api\model;
use think\Model;
/**
* 退款记录模型
*/
class RefundLog extends Model
{
// 表名
protected $name = 'refund_log';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
// 追加属性
protected $append = [];
// 获取退款单号
public static function getSn($user_id)
{
$rand = $user_id < 9999 ? mt_rand(100000, 99999999) : mt_rand(100, 99999);
$order_sn = date('Yhis') . $rand;
$id = str_pad($user_id, (24 - strlen($order_sn)), '0', STR_PAD_BOTH);
return 'R' . $order_sn . $id;
}
}
... ...
... ... @@ -2,6 +2,7 @@
namespace app\common\controller;
use app\api\model\RefundLog;
use think\Controller;
use think\Request;
use EasyWeChat\Factory;
... ... @@ -39,7 +40,7 @@ class Wechat extends Controller
'total_fee' => $order_price * 100,
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
'openid' => $openid,
'notify_url' => (self::isHttps() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . url('/index/notify/notify'),
'notify_url' => request()->domain() . url('/index/notify/notify'),
]);
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
... ... @@ -82,6 +83,42 @@ class Wechat extends Controller
}
/**
* 退款
*/
public function refund($order,$refund_desc = '退款')
{
// 生成退款单
$refundLog = new RefundLog();
$refundLog->order_sn = $order->order_sn;
$refundLog->refund_sn = RefundLog::getSn($order->user_id);
$refundLog->pay_fee = $order->pay_fee;
$refundLog->refund_fee = $order->pay_fee;
$refundLog->refund_desc = $refund_desc;
$refundLog->save();
$payment = self::payment();
$result = $payment->refund->byOutTradeNumber($refundLog['order_sn'], $refundLog['refund_sn'], $refundLog['pay_fee'], $refundLog['refund_fee'], [
// 可在此处传入其他参数,详细参数见微信支付文档
'refund_desc' => $refund_desc,
'notify_url' => request()->domain() . url('/index/notify/notifyr')
]);
\think\Log::write('refund-result' . json_encode($result));
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
return $result; // 返回数组
}
if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) {
// $this->setError($result['return_msg']);
// return false;
throw new \Exception($result['return_msg']);
}
// $this->setError($result['err_code_des']);
// return false;
throw new \Exception($result['err_code_des']);
}
/**
* 发送模板消息
* @param string $open_id 用户openid
* @param array $data 模板消息内容
... ... @@ -104,20 +141,6 @@ class Wechat extends Controller
}
/**
* 判断是否是https
*/
public static function isHttps() {
if ( !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
return true;
} elseif ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
return true;
} elseif ( !empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
return true;
}
return false;
}
/**
* 设置错误信息
*/
public function setError($error)
... ...
... ... @@ -2,9 +2,11 @@
namespace app\index\controller;
use app\admin\model\Third;
use app\common\controller\Frontend;
use app\common\controller\Wechat;
use think\Db;
use think\Log;
/**
* 支付回调
... ... @@ -115,4 +117,58 @@ class Notify extends Frontend
return true;
}
/**
* @ApiInternal
* 退款成功回调
*/
public function notifyr()
{
Log::write('notifyreturn-comein:');
$payment = Wechat::payment();
$response = $payment->handleRefundedNotify(function ($message, $reqInfo, $fail) {
// 其中 $message['req_info'] 获取到的是加密信息
// $reqInfo 为 message['req_info'] 解密后的信息
// 你的业务逻辑...
Log::write('notifyr-result:' . json_encode($reqInfo));
try {
$out_refund_no = $reqInfo['out_refund_no'];
$out_trade_no = $reqInfo['out_trade_no'];
// 退款
$order = \app\api\model\Order::where('order_sn', $out_trade_no)->find();
$refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();
if (!$order || !$refundLog || $refundLog->status != 0) {
// 订单不存在,或者订单已退款
return true; // 返回 true 告诉微信“我已处理完成”
}
// 退款完成
$refundLog->status = 1;
$refundLog->save();
// 退款成功通知
$openid = Third::where('user_id',$order['user_id'])->value('openid');
$send_data = [
"first" => '亲,您的订单已成功退款,请稍候查收。',
"keyword1" => $order['order_sn'],
"keyword2" => $order['license_plate'],
"keyword3" => $order['deposit'],
"keyword4" => '退款成功',
"remark" => ['请点击查看详情','#FF0000'],
];
$templateid = config('tmplmsg.template')['refund_success'];
$url = config('tmplmsg.vue_url').'/wallet';
(new Wechat)->tmplmsg($openid,$send_data,$templateid,$url);
} catch (\Exception $e) {
Log::write('notifyreturn-error:' . json_encode($e->getMessage()));
}
return true; // 返回 true 告诉微信“我已处理完成”
// 或返回错误原因 $fail('参数格式校验错误');
});
$response->send();
}
}
... ...