123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <?php
- namespace app\common\service\order;
- use app\common\model\fullsend\FullSendActivity as FullSendActivityModel;
- use app\common\enum\order\OrderStatus as OrderStatusEnum;
- use app\common\enum\order\ReceiptStatus;
- use app\common\exception\BaseException;
- use app\common\model\mj\MjSendActivity;
- use app\common\model\Order as OrderModel;
- use app\common\model\qc\QcMjSendActivity;
- use app\common\model\User as UserModel;
- use app\common\model\Wxapp as WxappModel;
- use app\common\model\user\BalanceLog as BalanceLogModel;
- use app\common\enum\order\PayType as PayTypeEnum;
- use app\common\enum\order\refund\RefundStatus as RefundStatusEnum;
- use app\common\enum\user\balanceLog\Scene as SceneEnum;
- use app\common\library\wechat\WxPay;
- use app\common\model\OrderGoods as OrderGoodsModel;
- use think\Log;
- /**
- * 订单退款服务类
- * Class Refund
- * @package app\common\service\order
- */
- class Refund
- {
- /**
- * 执行订单退款
- * @param \app\common\model\BaseModel $order 订单信息
- * @param double|null $money 指定退款金额
- * @return bool
- * @throws \think\Exception
- * @throws \think\exception\DbException
- * @throws \app\common\exception\BaseException
- */
- public function execute($order, $out_refund_no, $money = null)
- {
- // 退款金额,如不指定则默认为订单实付款金额
- is_null($money) && $money = $order['pay_price'];
- if(isset($order['parent_order_id'])&&$order['parent_order_id']>0){ //说明是子订单
- $order = OrderModel::find($order['parent_order_id']);
- }
- // 1.微信支付退款
- if ($order['pay_type'] == PayTypeEnum::WECHAT) {
- return $this->wechatRefund($order, $money,$out_refund_no);
- }
- // // 2.余额支付退款
- // if ($order['pay_type'] == PayTypeEnum::BALANCE) {
- // return $this->balance($order, $money,$out_refund_no);
- // }
- // // 2.支付宝退款
- // if ($order['pay_type'] == PayTypeEnum::ALIPAY) {
- // return $this->alipayRefund($order, $money,$out_refund_no);
- // }
- return false;
- }
- /**
- * 余额支付退款
- * @param $order
- * @param $money
- * @return bool
- * @throws \think\Exception
- * @throws \think\exception\DbException
- */
- private function balance(&$order, $money)
- {
- // 回退用户余额
- $user = UserModel::detail($order['user_id']);
- $user->setInc('balance', $money);
- // 记录余额明细
- BalanceLogModel::add(SceneEnum::REFUND, [
- 'user_id' => $user['user_id'],
- 'money' => $money,
- ], ['order_no' => $order['order_no']]);
- return true;
- }
- /**
- * 微信支付退款
- * @param $order
- * @param double $money
- * @return bool
- * @throws \app\common\exception\BaseException
- * @throws \think\exception\DbException
- */
- private function wxpay(&$order, $money)
- {
- $wxConfig = WxappModel::getWxappCache($order['wxapp_id']);
- $WxPay = new WxPay($wxConfig);
- return $WxPay->refund($order['transaction_id'], $order['pay_price'], $money);
- }
- //微信支付退款
- private function wechatRefund($order,$money,$out_refund_no){
- $wxConfig = WxappModel::find(10001);
- $WxPay = new WxPay($wxConfig);
- // $out_refund_no = OrderService::createOrderNo('TK');
- $payment = $WxPay->refundNew($order['order_no'], $out_refund_no, $order['pay_price'], $money);
- return $payment;
- }
- //支付宝退款
- private function alipayRefund($order,$money,$out_request_no){
- $refund_amount = $money;//退款金额
- $out_trade_no = $order['order_no']; //原支付订单号
- // $out_request_no = OrderService::createOrderNo('TK'); //退款订单号
- $refund_reason = '售后单退款'; //退款的原因说明
- $aliConfig = config('alipay');
- $aop = new \AopClient();
- $aop->gatewayUrl = $aliConfig['gateway_url'];
- $aop->appId = $aliConfig['app_id'];
- $aop->rsaPrivateKey = $aliConfig['private_key'];
- $aop->alipayrsaPublicKey=$aliConfig['public_key'];
- $aop->apiVersion = '1.0';
- $aop->postCharset='UTF-8';
- $aop->format='json';
- $aop->signType='RSA2';
- $request = new \AlipayTradeRefundRequest ();
- $bizContent = "{" .
- " \"refund_reason\":\"$refund_reason\"," .
- " \"out_trade_no\":\"$out_trade_no\"," .
- " \"out_request_no\":\"$out_request_no\"," .
- " \"refund_amount\":$refund_amount" .
- " }";
- $request->setBizContent($bizContent);
- $result = $aop->execute ( $request);
- $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
- $resultCode = $result->$responseNode->code;
- if(!empty($resultCode)&&$resultCode == 10000){
- // return ['code'=>0,'msg'=>'退款成功'];
- return true;
- } else {
- Log::error($result);
- throw new BaseException(['msg' => 'err_code_des: ' . $result->$responseNode->sub_msg]);
- }
- }
- //判断退货退款订单商品是否需要提示退回赠品
- public static function checkRefund($order_id,$order_goods_id,$refund_money){
- $order = OrderModel::get(['order_id'=>$order_id]);
- if(!$order){
- return false;
- }
- $goodFullPrice = 0;
- $isCheck = false;
- foreach ($order['goods'] as $good){
- if($good['full_send_activity_id']>0){
- $goodFullPrice += $good['total_price'];
- if($good['refund']['status'] == RefundStatusEnum::COMPLETED){
- $goodFullPrice -= $good['refund']['refund_money'];
- }
- }
- if($good['order_goods_id'] == $order_goods_id){
- $isCheck = true;
- }
- }
- if($isCheck){//
- $FullSendActivity = FullSendActivityModel::detail($order['full_send_activity_id']);
- if($goodFullPrice-$refund_money<$FullSendActivity['full_money']){//退款的商品不足满减条件了,就需要退回赠品
- return true;
- }
- }
- return false;
- }
- //判断满件送商品退款后的剩余的商品件数是否满足赠品活动条件,如不满足,弹窗提示将赠品一起寄回。-V1.3.7添加于2022年3月29日
- //$goods_num退回的商品数量
- public static function checkMjRefund($order_id,$order_goods_id,$goods_num){
- $order = OrderModel::get(['order_id'=>$order_id]);
- if(!$order){
- return 0;
- }
- $isCheck = 0;//需要退还的赠品套数
- foreach ($order['goods'] as $good){
- if($good['order_goods_id'] == $order_goods_id && $good['is_mj_send']==1){//是满件送活动
- $MjSendActivity = MjSendActivity::find($good['mj_send_activity_id']);
- $mj_props = array_values(array_sort($MjSendActivity['mj_props'], 'value', true));
- $c = $good['total_num']-$good['mj_send_use_count'];
- if($c>0){
- $c2 = $goods_num-$c;
- if($c2<=0){
- continue;
- }
- }
- $residue_num = $good['total_num']-$goods_num;//剩余商品数量
- $count = 0;
- foreach ($mj_props as $arr){
- if($residue_num>=$arr['value']){//商品数量大于当前活动满件送的最小数量
- $count = $arr['count'];
- break;
- }else{
- continue;
- }
- }
- $isCheck = $good['mj_send_count'] - $count;
- }
- }
- if($isCheck){//
- return $isCheck;
- }
- return 0;
- }
- //判断全场满件送商品退款后的剩余的商品件数是否满足赠品活动条件,如不满足,弹窗提示将赠品一起寄回。-V1.4.2添加于2022年7月12日
- //$goods_num退回的商品数量
- public static function checkQcMjRefund($order_id,$order_goods_id,$goods_num){
- $order = OrderModel::get(['order_id'=>$order_id]);
- if(!$order){
- return 0;
- }
- $act_count = 0;//全场满件送活动的剩余数量
- foreach ($order['goods'] as $good){
- if($good['qc_send_activity_id']>0){
- $act_count += $good['qc_send_use_count'];
- if($good['refund']['status'] == RefundStatusEnum::COMPLETED){
- $count = $good['total_num']-$good['qc_send_use_count'];
- if($count>0){
- if($good['refund']['goods_num']-$count>0){
- $act_count -= $good['refund']['goods_num']-$count;
- }
- }else{
- $act_count -= $good['refund']['goods_num'];
- }
- }
- }
- }
- $isCheck = 0;//需要退还的赠品套数
- foreach ($order['goods'] as $good){
- if($good['order_goods_id'] == $order_goods_id && $good['is_qc_send_send']==1){//是全场满件送活动
- $QcMjSendActivity = QcMjSendActivity::find($good['qc_send_activity_id']);
- $mj_props = array_values(array_sort($QcMjSendActivity['mj_props'], 'value', true));
- $c = $good['total_num']-$good['qc_send_use_count'];
- if($c>0){
- $c2 = $goods_num-$c;
- if($c2<=0){
- continue;
- }else{
- $residue_num = $act_count-$c2;//剩余商品数量
- }
- }else{
- $residue_num = $act_count-$goods_num;//剩余商品数量
- }
- $count = 0;
- foreach ($mj_props as $arr){
- if($residue_num>=$arr['value']){//商品数量大于当前活动满件送的最小数量
- $count = $arr['count'];
- break;
- }else{
- continue;
- }
- }
- $isCheck = $good['qc_send_count'] - $count;
- }
- }
- if($isCheck){//
- return $isCheck;
- }
- return 0;
- }
- }
|