正在显示
5 个修改的文件
包含
138 行增加
和
6 行删除
@@ -463,4 +463,76 @@ class Service | @@ -463,4 +463,76 @@ class Service | ||
463 | { | 463 | { |
464 | return self::getSdkVersion() === self::SDK_VERSION_V3; | 464 | return self::getSdkVersion() === self::SDK_VERSION_V3; |
465 | } | 465 | } |
466 | + /** | ||
467 | + * 提交退款订单 | ||
468 | + * @param array|float $amount 订单金额 | ||
469 | + * @param array|float $refund_money 退款金额 | ||
470 | + * @param string $orderid 订单号 | ||
471 | + * @param string $refund_sn 退款订单号 | ||
472 | + * @param string $type 支付类型,可选alipay或wechat | ||
473 | + * @param string $remark 退款原因 | ||
474 | + * @param string $notifyurl 通知回调URL | ||
475 | + * @param string $returnurl 跳转返回URL | ||
476 | + * @param string $method 支付方式 | ||
477 | + * @return Response|RedirectResponse|Collection | ||
478 | + * @throws Exception | ||
479 | + */ | ||
480 | + public static function submitRefund($amount = null, $refund_money, $orderid, $refund_sn, $type, $remark = null, $notifyurl = null, $returnurl = null, $method = 'miniapp') | ||
481 | + { | ||
482 | + if (!is_array($amount)) { | ||
483 | + $params = [ | ||
484 | + 'amount' => $amount, | ||
485 | + 'type' => $type, | ||
486 | + 'notifyurl' => $notifyurl, | ||
487 | + 'returnurl' => $returnurl, | ||
488 | + 'method' => $method, | ||
489 | + ]; | ||
490 | + } else { | ||
491 | + $params = $amount; | ||
492 | + } | ||
493 | + $type = isset($params['type']) && in_array($params['type'], ['alipay', 'wechat']) ? $params['type'] : 'wechat'; | ||
494 | + $request = request(); | ||
495 | + //$notifyurl = isset($params['notifyurl']) ? $params['notifyurl'] : $request->root(true) . '/addons/epay/index/' . $type . 'RfdNotify'; | ||
496 | + // $returnurl = isset($params['returnurl']) ? $params['returnurl'] : $request->root(true) . '/addons/epay/index/' . $type . 'return/out_trade_no/' . $orderid; | ||
497 | + //$notifyurl = $this->request->domain() . '/api/index/refundNotifyx'; | ||
498 | + $config = Service::getConfig($type); | ||
499 | + $config['notify_url'] = $notifyurl; | ||
500 | + $config['return_url'] = $returnurl; | ||
501 | + $result = null; | ||
502 | + //退款参数 | ||
503 | + $order_data = [ | ||
504 | + 'out_trade_no' => $orderid,//原订单号 | ||
505 | + ]; | ||
506 | + if ($type == 'wechat') { | ||
507 | + //创建支付对象 | ||
508 | + $pay = Pay::wechat($config); | ||
509 | + $total_fee = $amount * 100; | ||
510 | + $refund_fee = $refund_money * 100; | ||
511 | + $order_data = array_merge($order_data, [ | ||
512 | + 'out_refund_no' => $refund_sn,//退款订单号 | ||
513 | + 'total_fee' => $total_fee,//支付金额 | ||
514 | + 'refund_fee' => $refund_fee,//退款金额 | ||
515 | + 'refund_desc' => $remark,//退款原因 | ||
516 | + 'type' => $method //支付方式 | ||
517 | + ]); | ||
518 | + } else { | ||
519 | + $pay = Pay::alipay($config); | ||
520 | + $order_data = array_merge($order_data, [ | ||
521 | + 'out_request_no' => $refund_sn,//退款订单号 | ||
522 | + 'refund_amount' => $refund_money, | ||
523 | + ]); | ||
524 | + } | ||
525 | + | ||
526 | + $result = $pay->refund($order_data); | ||
527 | + | ||
528 | + //使用重写的Response类、RedirectResponse、Collection类 | ||
529 | + if ($result instanceof \Symfony\Component\HttpFoundation\RedirectResponse) { | ||
530 | + $result = RedirectResponse::create($result->getTargetUrl()); | ||
531 | + } elseif ($result instanceof \Symfony\Component\HttpFoundation\Response) { | ||
532 | + $result = Response::create($result->getContent()); | ||
533 | + } elseif ($result instanceof \Yansongda\Supports\Collection) { | ||
534 | + $result = Collection::make($result->all()); | ||
535 | + } | ||
536 | + return $result; | ||
537 | + } | ||
466 | } | 538 | } |
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | namespace app\admin\controller; | 3 | namespace app\admin\controller; |
4 | 4 | ||
5 | use app\common\controller\Backend; | 5 | use app\common\controller\Backend; |
6 | +use think\Db; | ||
6 | 7 | ||
7 | /** | 8 | /** |
8 | * 订单管理 | 9 | * 订单管理 |
@@ -73,4 +74,21 @@ class Order extends Backend | @@ -73,4 +74,21 @@ class Order extends Backend | ||
73 | return $this->view->fetch(); | 74 | return $this->view->fetch(); |
74 | } | 75 | } |
75 | 76 | ||
77 | + public function refund($id){ | ||
78 | + //查询订单 | ||
79 | + $order=Db::name("order")->where("id",$id)->find(); | ||
80 | + if($order['is_pay']!=1){ | ||
81 | + $this->error("该订单无法退款"); | ||
82 | + } | ||
83 | + //拼接退款参数 | ||
84 | + $pay_fee = $order['price']; | ||
85 | + $refund_fee = $pay_fee; | ||
86 | + $order_sn = $order['order_no']; | ||
87 | + $pay_type = 'wechat'; | ||
88 | + $reason = '订单退款'; | ||
89 | + $notifyurl = 'https://wyc.tenyes.cn/api/index/refundNotifyx';//退款回调地址 | ||
90 | + //直接调用退款方法传参即可 | ||
91 | + $response = \addons\epay\library\Service::submitRefund($pay_fee, $refund_fee, $order_sn, getRefundSn($order['user_id']), $pay_type, $reason, $notifyurl, '', 'miniapp'); | ||
92 | + print_r($response);return; | ||
93 | + } | ||
76 | } | 94 | } |
@@ -530,7 +530,20 @@ if (!function_exists('check_url_allowed')) { | @@ -530,7 +530,20 @@ if (!function_exists('check_url_allowed')) { | ||
530 | return false; | 530 | return false; |
531 | } | 531 | } |
532 | } | 532 | } |
533 | +/** | ||
534 | + * 工单退款 | ||
535 | + * 生成退款单号 | ||
536 | + */ | ||
537 | +if (!function_exists('getRefundSn')) { | ||
533 | 538 | ||
539 | + function getRefundSn($user_id) | ||
540 | + { | ||
541 | + $rand = $user_id < 99999 ? mt_rand(100000, 99999999) : mt_rand(100, 99999); | ||
542 | + $order_sn = date('Yhis') . $rand; | ||
543 | + $id = str_pad($user_id, (24 - strlen($order_sn)), '0', STR_PAD_BOTH); | ||
544 | + return 'R' . $order_sn . $id; | ||
545 | + } | ||
546 | +} | ||
534 | if (!function_exists('build_suffix_image')) { | 547 | if (!function_exists('build_suffix_image')) { |
535 | /** | 548 | /** |
536 | * 生成文件后缀图片 | 549 | * 生成文件后缀图片 |
@@ -33,14 +33,43 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin | @@ -33,14 +33,43 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin | ||
33 | {field: 'is_pay', title: __('Is_pay'), searchList: {"1":__('Is_pay 1'),"2":__('Is_pay 2'),"3":__('Is_pay 3')}, formatter: Table.api.formatter.normal}, | 33 | {field: 'is_pay', title: __('Is_pay'), searchList: {"1":__('Is_pay 1'),"2":__('Is_pay 2'),"3":__('Is_pay 3')}, formatter: Table.api.formatter.normal}, |
34 | {field: 'user_name', title: __('User_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 34 | {field: 'user_name', title: __('User_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, |
35 | {field: 'driver_name', title: __('Driver_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 35 | {field: 'driver_name', title: __('Driver_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, |
36 | - {field: 'pay_time', title: __('Pay_time'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | ||
37 | - {field: 'refund_time', title: __('Refund_time'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | ||
38 | - {field: 'create_time', title: __('Create_time'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 36 | + {field: 'pay_time', title: __('Pay_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime}, |
37 | + {field: 'refund_time', title: __('Refund_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime}, | ||
38 | + {field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime}, | ||
39 | {field: 'driver.name', title: __('Driver.name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 39 | {field: 'driver.name', title: __('Driver.name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, |
40 | {field: 'car.license_plate', title: __('Car.license_plate'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 40 | {field: 'car.license_plate', title: __('Car.license_plate'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, |
41 | {field: 'user.username', title: __('User.username'), operate: 'LIKE'}, | 41 | {field: 'user.username', title: __('User.username'), operate: 'LIKE'}, |
42 | - {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} | ||
43 | - ] | 42 | + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate, |
43 | + buttons:[ | ||
44 | + { | ||
45 | + name: 'ajax', | ||
46 | + title: "退款", | ||
47 | + text:"退款", | ||
48 | + classname: 'btn btn-xs btn-warning btn-magic btn-ajax', | ||
49 | + icon: 'fa fa-paper-plane', | ||
50 | + confirm: function (row) { | ||
51 | + return "确认退款" | ||
52 | + }, | ||
53 | + url: 'order/refund?id={id}', | ||
54 | + | ||
55 | + success: function (data, ret) { | ||
56 | + // Layer.alert(ret.msg + ",返回数据:" + JSON.stringify(data)); | ||
57 | + // 如果需要阻止成功提示,则必须使用return false; | ||
58 | + console.log(data, ret); | ||
59 | + Layer.alert(ret.msg); | ||
60 | + $("#myTabContent .btn-refresh").trigger("click"); | ||
61 | + return false; | ||
62 | + }, | ||
63 | + error: function (data, ret) { | ||
64 | + console.log(data, ret); | ||
65 | + Layer.alert(ret.msg); | ||
66 | + $("#myTabContent .btn-refresh").trigger("click"); | ||
67 | + return false; | ||
68 | + } | ||
69 | + }, | ||
70 | + | ||
71 | + ] | ||
72 | + }] | ||
44 | ] | 73 | ] |
45 | }); | 74 | }); |
46 | 75 |
@@ -30,7 +30,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin | @@ -30,7 +30,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin | ||
30 | {field: 'start_address', title: __('Start_address'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 30 | {field: 'start_address', title: __('Start_address'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, |
31 | {field: 'end_address', title: __('End_address'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 31 | {field: 'end_address', title: __('End_address'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, |
32 | {field: 'price', title: __('Price'), operate:'BETWEEN'}, | 32 | {field: 'price', title: __('Price'), operate:'BETWEEN'}, |
33 | - {field: 'create_time', title: __('Create_time'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, | 33 | + {field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime}, |
34 | {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} | 34 | {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} |
35 | ] | 35 | ] |
36 | ] | 36 | ] |
-
请 注册 或 登录 后发表评论