作者 郭文星

123

@@ -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 ]