Browse Source

订单退款处理--修改

master
liangyuyan 5 years ago
parent
commit
c3ed8900ec
  1. 5
      app/Constants/LogLabel.php
  2. 107
      app/Controller/NotifyPayRefundController.php
  3. 9
      app/Model/CouponRec.php
  4. 18
      app/Model/CouponUserRec.php
  5. 3
      app/Model/FinancialRecord.php
  6. 48
      app/Service/CouponService.php
  7. 1
      app/Service/CouponServiceInterface.php
  8. 106
      app/Service/OrderService.php
  9. 21
      app/Service/WxRefundService.php
  10. 2
      app/Service/WxRefundServiceInterface.php

5
app/Constants/LogLabel.php

@ -54,4 +54,9 @@ class LogLabel extends AbstractConstants
*/ */
const OFFLINE_PAID_LOG = 'offline_paid_log'; const OFFLINE_PAID_LOG = 'offline_paid_log';
/**
* @Message("Pay refund Log Label")
*/
const PAY_NOTIFY_REFUND = 'notify_refund';
} }

107
app/Controller/NotifyPayRefundController.php

@ -0,0 +1,107 @@
<?php
namespace App\Controller;
use App\Constants\LogLabel;
use App\Model\OrderMain;
use App\Model\Users;
use App\Service\CouponRebateServiceInterface;
use App\Service\DeviceServiceInterface;
use App\Service\FeiePrintServiceInterface;
use App\Service\MiniprogramServiceInterface;
use App\Service\MqttServiceInterface;
use App\Service\OrderServiceInterface;
use App\Service\SeparateAccountsServiceInterface;
use App\Service\UserServiceInterface;
use EasyWeChat\Factory;
use Hyperf\DbConnection\Db;
use Hyperf\Guzzle\CoroutineHandler;
use Exception;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Symfony\Component\HttpFoundation\Request;
class NotifyPayRefundController extends BaseController
{
const AWARD_LIMIT_AMOUNT = 3;
/**
* @Inject
* @var UserServiceInterface
*/
protected $userService;
/**
* @Inject
* @var CouponRebateServiceInterface
*/
protected $couponRebateService;
/**
* @Inject
* @var OrderServiceInterface
*/
protected $orderService;
/**
* 微信退款回调
*/
public function wxPayRefund()
{
$config = config('wxpay');
$app = Factory::payment($config);
$app['guzzle_handler'] = CoroutineHandler::class;
$get = $this->request->getQueryParams();
$post = $this->request->getParsedBody();
$cookie = $this->request->getCookieParams();
$files = $this->request->getUploadedFiles();
$server = $this->request->getServerParams();
$xml = $this->request->getBody()->getContents();
$app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
/* 通知回调,进行业务处理 */
$response = $app->handleRefundedNotify(function ($message, $fail) use ($app) {
try {
/* --- 退款失败 --- */
if (
empty($message)
|| !isset($message['result_code'])
|| $message['result_code'] != 'SUCCESS'
) {
// 错误日志
$this->log->event(
LogLabel::PAY_NOTIFY_REFUND,
$message
);
$fail('Unknown error but FAIL');
}
/* --- 退款成功 --- */
// 退款返还优惠券
$this->couponService->orderRefundCoupon($message['out_trade_no']);
// 添加用户的流水
$orderMain = OrderMain::select('id','global_order_id')->where('code',$message['out_trade_no'])->first();
} catch (Exception $e) {
$this->log->event(
LogLabel::PAY_NOTIFY_REFUND,
['exception_fail' => $e->getMessage()]
);
$fail('Exception');
}
});
return $this->response
->withHeader('Content-Type', 'text/xml')
->withStatus(200)
->withBody(new SwooleStream($response->getContent()));
}
}

9
app/Model/CouponRec.php

@ -6,8 +6,15 @@ use App\Model\Model;
class CouponRec extends Model class CouponRec extends Model
{ {
protected $table = 'ims_system_coupon_user_receive';
/* 状态 */
// 未使用
const STATE_UNUSED = 0;
// 使用部分
const STATE_SOME = 1;
// 已用完
const STATE_FINISH = 2;
protected $table = 'ims_system_coupon_user_receive';
public function coupon() public function coupon()
{ {

18
app/Model/CouponUserRec.php

@ -1,18 +0,0 @@
<?php
namespace App\Model;
class CouponUserRec extends Model
{
/* 状态 */
// 未使用
const STATE_UNUSED = 0;
// 使用部分
const STATE_SOME = 1;
// 已用完
const STATE_FINISH = 2;
protected $table = 'ims_system_coupon_user_receive';
}

3
app/Model/FinancialRecord.php

@ -51,6 +51,9 @@ class FinancialRecord extends Model
const MONEY_TYPE_STORE_FIRST_ORDER = 5; // 商户当日首单奖励 const MONEY_TYPE_STORE_FIRST_ORDER = 5; // 商户当日首单奖励
const MONEY_TYPE_STORE_OL_ORDER_COMP = 6; // 商户线上订单完成收入 const MONEY_TYPE_STORE_OL_ORDER_COMP = 6; // 商户线上订单完成收入
const MONEY_TYPE_STORE_OFL_ORDER_COMP = 7; // 商户线下订单完成收入 const MONEY_TYPE_STORE_OFL_ORDER_COMP = 7; // 商户线下订单完成收入
const MONEY_TYPE_USER_OL_ORDER_REFUND = 8; // 商户线下订单完成收入
const MONEY_TYPE_USER_OFL_ORDER = 100; // 用户线下支付订单 const MONEY_TYPE_USER_OFL_ORDER = 100; // 用户线下支付订单
const MONEY_TYPE_USER_OL_ORDER = 101; // 用户线上支付订单 const MONEY_TYPE_USER_OL_ORDER = 101; // 用户线上支付订单

48
app/Service/CouponService.php

@ -260,7 +260,6 @@ class CouponService implements CouponServiceInterface
/* 删除-优惠券今日使用的缓存 /* 删除-优惠券今日使用的缓存
* @param $userId * @param $userId
* @param $couponId * @param $couponId
* @param $couponRecId
* @return bool * @return bool
*/ */
function clearTodayCouponUsed($userId, $couponId) function clearTodayCouponUsed($userId, $couponId)
@ -272,5 +271,52 @@ class CouponService implements CouponServiceInterface
'coupon_'.date('Ymd').'_used_'.$userId, 'coupon_'.date('Ymd').'_used_'.$userId,
$couponId $couponId
); );
return $res;
}
/**
* 退款返还优惠券
* 先查询是否正常使用优惠券
* 修改状态,退还领取记录库存,删除ssdb缓存
*/
public function orderRefundCoupon($global_order_id)
{
$time = time();
Db::beginTransaction();
try {
$couponUses = CouponUserUse::query()
->select('id','system_coupon_id','user_id','number','user_receive_id')
->where('global_order_id',$global_order_id)
->where('status',CouponUserUse::COUPON_USE_STATE_USED)
->select();
if(!empty($couponUse)){
foreach($couponUses as $use){
$use->status = CouponUserUse::COUPON_USE_STATE_USED;
$use->return_time = $time;
$use->update_time = $time;
$res = $use->save();
$couponReceive = CouponRec::query()
->where('id',$use->user_receive_id)
->whereRaw('number >= number_remain+'.$use->number)
->update([
'number_remain' => Db::raw('number_remain+'.$use->number),
'status' => Db::raw('IF(number=number_remain,' . CouponRec::STATE_UNUSED . ',' . CouponRec::STATE_SOME . ')'),
'update_time' => $time
]);
$clearUseRedis = $this->clearTodayCouponUsed($use->user_id,$use->system_coupon_id);
}
}
Db::commit();
return true;
} catch (Exception $e) {
$this->log->event(LogLabel::ORDER_LOG, ['msg'=> '订单退款','exception' => $e->getMessage()]);
Db::rollBack();
return false;
}
return true;
} }
} }

1
app/Service/CouponServiceInterface.php

@ -29,4 +29,5 @@ interface CouponServiceInterface
public function refundOrderCoupons($order_id,$user_id); public function refundOrderCoupons($order_id,$user_id);
public function clearTodayCouponUsed($userId, $couponId); public function clearTodayCouponUsed($userId, $couponId);
public function orderRefundCoupon($global_order_id);
} }

106
app/Service/OrderService.php

@ -5,7 +5,7 @@ namespace App\Service;
use App\Commons\Log; use App\Commons\Log;
use App\Constants\LogLabel; use App\Constants\LogLabel;
use App\Model\Coupon; use App\Model\Coupon;
use App\Model\CouponUserRec;
use App\Model\CouponRec;
use App\Model\CouponUserUse; use App\Model\CouponUserUse;
use App\Model\Goods; use App\Model\Goods;
use App\Model\Order; use App\Model\Order;
@ -19,6 +19,7 @@ use Hyperf\DbConnection\Db;
use Hyperf\Snowflake\IdGeneratorInterface; use Hyperf\Snowflake\IdGeneratorInterface;
use Hyperf\Utils\ApplicationContext; use Hyperf\Utils\ApplicationContext;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use App\Service\WxRefundServiceInterface;
class OrderService implements OrderServiceInterface class OrderService implements OrderServiceInterface
{ {
@ -34,6 +35,12 @@ class OrderService implements OrderServiceInterface
*/ */
protected $couponService; protected $couponService;
/**
* @Inject
* @var WxRefundServiceInterface
*/
protected $wxRefundService;
/** /**
* @inheritDoc * @inheritDoc
*/ */
@ -280,7 +287,7 @@ class OrderService implements OrderServiceInterface
} }
// 处理红包的使用 // 处理红包的使用
$canUseCoupons = CouponUserRec::select(['id', 'user_id', 'number', 'number_remain', 'system_coupon_user_id'])
$canUseCoupons = CouponRec::select(['id', 'user_id', 'number', 'number_remain', 'system_coupon_user_id'])
->whereIn('id', $receiveCouponIds) ->whereIn('id', $receiveCouponIds)
->get()->toArray(); ->get()->toArray();
if (is_array($canUseCoupons)&&!empty($canUseCoupons)) { if (is_array($canUseCoupons)&&!empty($canUseCoupons)) {
@ -312,7 +319,7 @@ class OrderService implements OrderServiceInterface
$status = 0; $status = 0;
} }
$upRes = CouponUserRec::query()->where(['id' => $coupon['id']])->update(['number_remain' => $numberRemain, 'status' => $status]);
$upRes = CouponRec::query()->where(['id' => $coupon['id']])->update(['number_remain' => $numberRemain, 'status' => $status]);
if (!$upRes) { if (!$upRes) {
Db::rollBack(); Db::rollBack();
@ -716,14 +723,16 @@ class OrderService implements OrderServiceInterface
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function onlineRefund($global_order_id){
public function onlineRefund($global_order_id)
{
Db::beginTransaction(); Db::beginTransaction();
try { try {
$time = time(); $time = time();
// 主订单状态更新 // 主订单状态更新
$orderMain = OrderMain::query() $orderMain = OrderMain::query()
->where(['global_order_id' => $global_order_id, 'state' => OrderMain::ORDER_STATE_DELIVERY])
->select('id','global_order_id','state','pay_type')
->where(['global_order_id' => $global_order_id, 'state' => OrderMain::ORDER_STATE_REFUNDING])
->first(); ->first();
if (empty($orderMain)) { if (empty($orderMain)) {
@ -736,40 +745,26 @@ class OrderService implements OrderServiceInterface
// 子订单状态更新 // 子订单状态更新
$upChild = Order::query() $upChild = Order::query()
->where(['order_main_id' => $orderMain->id])
->where('order_main_id' , $orderMain->id)
->where('state',OrderMain::ORDER_STATE_REFUNDING)
->update(['state' => OrderMain::ORDER_STATE_REFUNDED]); ->update(['state' => OrderMain::ORDER_STATE_REFUNDED]);
/* 退还优惠券 */
// 先查询是否正常使用优惠券
// 修改状态,退还领取记录库存,删除ssdb缓存
$couponUses = CouponUserUse::query()
->select('id','system_coupon_id','user_id','number','user_receive_id')
->where('order_main_id',$orderMain->id)
->where('status',CouponUserUse::COUPON_USE_STATE_USED)
->select();
if(!empty($couponUse)){
foreach($couponUses as $use){
$use->status = CouponUserUse::COUPON_USE_STATE_USED;
$use->return_time = $time;
$use->update_time = $time;
$use->save();
$couponReceive = CouponUserRec::query()
->where('id',$use->user_receive_id)
->whereRaw('number >= number_remain+'.$use->number)
->update([
'number_remain' => Db::raw('number_remain+'.$use->number),
'status' => Db::raw('IF(number=number_remain,' . CouponUserRec::STATE_UNUSED . ',' . CouponUserRec::STATE_SOME . ')'),
'update_time' => $time
]);
$clearUseRedis = $this->couponService->clearTodayCouponUsed($use->user_id,$use->system_coupon_id);
}
if(empty($upChild)){
Db::rollBack();
return false;
} }
// 退还订单金额到用户微信余额
if($orderMain->pay_type == OrderMain::ORDER_PAY_WX){
// 微信支付 微信退款
$refundRes = $this->wxRefundService->wxPayRefund($global_order_id);
}else if($orderMain->pay_type == OrderMain::ORDER_PAY_BALANCE){
// 余额支付 退款到用户余额
// 返还优惠券
$this->couponService->orderRefundCoupon($global_order_id);
// 添加用户流水
}
Db::commit(); Db::commit();
return true; return true;
} catch (Exception $e) { } catch (Exception $e) {
@ -780,4 +775,47 @@ class OrderService implements OrderServiceInterface
} }
} }
/**
* 订单退款失败
* 回退订单状态
*/
public function onlineRefundFail($global_order_id)
{
Db::beginTransaction();
try {
$time = time();
// 主订单状态更新
$orderMain = OrderMain::query()
->select('id','global_order_id','state','pay_type')
->where(['global_order_id' => $global_order_id, 'state' => OrderMain::ORDER_STATE_REFUNDED])
->first();
if (empty($orderMain)) {
Db::rollBack();
return false;
}
$orderMain->state = OrderMain::ORDER_STATE_REFUNDING;
$upOrderMain = $orderMain->save();
// 子订单状态更新
$upChild = Order::query()
->where('order_main_id' , $orderMain->id)
->where('state',OrderMain::ORDER_STATE_REFUNDED)
->update(['state' => OrderMain::ORDER_STATE_REFUNDING]);
if(empty($upChild)){
Db::rollBack();
return false;
}
Db::commit();
return true;
} catch (Exception $e) {
$this->log->event(LogLabel::ORDER_LOG, ['msg'=> '订单退款失败时处理状态9->8','exception' => $e->getMessage()]);
Db::rollBack();
return false;
}
}
} }

21
app/Service/PayRefundService.php → app/Service/WxRefundService.php

@ -7,7 +7,7 @@ use EasyWeChat\Factory;
use Hyperf\DbConnection\Db; use Hyperf\DbConnection\Db;
use App\Constants\ErrorCode; use App\Constants\ErrorCode;
class PayRefundService implements PayRefundServiceInterface
class WxRefundService implements WxRefundServiceInterface
{ {
/** /**
* 微信支付退款 * 微信支付退款
@ -18,29 +18,24 @@ class PayRefundService implements PayRefundServiceInterface
$app = Factory::payment($config); $app = Factory::payment($config);
$app['guzzle_handler'] = CoroutineHandler::class; $app['guzzle_handler'] = CoroutineHandler::class;
$result = [
'status' => 0,
'msg' => '退款成功'
];
// 查询订单 // 查询订单
$orderMain = OrderMain::query() $orderMain = OrderMain::query()
->select('id','code','order_num','money','state')
->select('id','global_order_id','order_num','money','state')
->where('global_order_id',$global_order_id) ->where('global_order_id',$global_order_id)
->where('pay_type',OrderMain::ORDER_PAY_WX) ->where('pay_type',OrderMain::ORDER_PAY_WX)
->where(Db::raw('refund_time is null')) ->where(Db::raw('refund_time is null'))
->first(); ->first();
if(empty($orderMain)){ if(empty($orderMain)){
return ['status'=>1, 'msg'=>'订单不存在或已退款'];
return false;
} }
$optional = [];
;
$result = $app->refund->byOutTradeNumber( $result = $app->refund->byOutTradeNumber(
$orderMain->code,
$orderMain->code,
$orderMain->money * 100,
$orderMain->global_order_id,
$orderMain->global_order_id,
$orderMain->money * 100, $orderMain->money * 100,
$optional
$orderMain->money * 100
); );
return $result; return $result;
} }

2
app/Service/PayRefundServiceInterface.php → app/Service/WxRefundServiceInterface.php

@ -2,7 +2,7 @@
namespace App\Service; namespace App\Service;
interface PayRefundServiceInterface
interface WxRefundServiceInterface
{ {
public function wxPayRefund($global_order_id); public function wxPayRefund($global_order_id);
} }
Loading…
Cancel
Save