|
|
|
@ -8,10 +8,14 @@ use App\Constants\v3\LogLabel; |
|
|
|
use App\Constants\v3\OrderState; |
|
|
|
use App\Exception\ErrorCodeException; |
|
|
|
use App\Model\v3\Order; |
|
|
|
use App\Model\v3\OrderGoods; |
|
|
|
use App\Model\v3\OrderMain; |
|
|
|
use App\Service\v3\Interfaces\OrderOnlineServiceInterface; |
|
|
|
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface; |
|
|
|
use EasyWeChat\Factory; |
|
|
|
use EasyWeChat\Kernel\Exceptions\InvalidConfigException; |
|
|
|
use Hyperf\DbConnection\Db; |
|
|
|
use Hyperf\Guzzle\CoroutineHandler; |
|
|
|
use Hyperf\RpcServer\Annotation\RpcService; |
|
|
|
use Hyperf\Di\Annotation\Inject; |
|
|
|
use function AlibabaCloud\Client\json; |
|
|
|
@ -107,53 +111,142 @@ class OrderService implements OrderServiceInterface |
|
|
|
* 退2元商品时,退款金额为 |
|
|
|
* 红包 :(2/(98+2))*10 = 0.2 |
|
|
|
* 退款:2-0.2=1.8元 |
|
|
|
* @param $user_id *用户ID |
|
|
|
* @param $user_id *用户ID |
|
|
|
* @param $global_order_id *全局总订单ID |
|
|
|
* @param $child_order_id *主订单ID, |
|
|
|
* @param $order_child_id *主订单ID, |
|
|
|
* @param $order_goods_id *订单商品ID |
|
|
|
* @param $note |
|
|
|
* @throws InvalidConfigException |
|
|
|
*/ |
|
|
|
public function onlineSingleRefund($user_id, $note, $global_order_id, $child_order_id=null, $order_goods_id=null) |
|
|
|
public function onlineSingleRefund($user_id, $note, $global_order_id, $order_child_id=null, $order_goods_id=null) |
|
|
|
{ |
|
|
|
|
|
|
|
$params = [ |
|
|
|
'user_id' => $user_id, |
|
|
|
'note' => $note, |
|
|
|
'global_order_id' => $global_order_id, |
|
|
|
'order_child_id' => $order_child_id, |
|
|
|
'order_goods_id' => $order_goods_id, |
|
|
|
]; |
|
|
|
|
|
|
|
if (!$user_id || !$global_order_id || !$note) { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '参数不对', |
|
|
|
'params' => json([$global_order_id, $user_id, $note]) |
|
|
|
'params' => json_encode($params) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
// 主订单
|
|
|
|
$orderMain = OrderMain::query() |
|
|
|
->where(['global_order_id' => $global_order_id]) |
|
|
|
->where(['global_order_id' => $global_order_id, 'user_id' => $user_id]) |
|
|
|
->whereIn('state', OrderState::CAN_REFUND_DIRECT) |
|
|
|
->first(); |
|
|
|
|
|
|
|
if (empty($orderMain)) { |
|
|
|
if (is_null($orderMain)) { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '订单不存在', |
|
|
|
'params' => json([$global_order_id, $user_id, $note]) |
|
|
|
'params' => json_encode($params) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
// 子订单
|
|
|
|
if ($child_order_id) { |
|
|
|
$orderChild = Order::query()->where(['order_main_id' => $orderMain->global_order_id])->first(); |
|
|
|
$orderChild = null; |
|
|
|
if ($order_child_id) { |
|
|
|
$orderChild = Order::query()->where(['order_main_id' => $orderMain->global_order_id, 'id' => $order_child_id])->first(); |
|
|
|
} |
|
|
|
|
|
|
|
// 单商品退
|
|
|
|
// 订单商品
|
|
|
|
$orderGoods = null; |
|
|
|
if ($order_goods_id) { |
|
|
|
if (!$child_order_id) { |
|
|
|
if (!$order_child_id || is_null($orderChild)) { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '参数不对[单品]', |
|
|
|
'params' => json([$global_order_id, $user_id, $note, $child_order_id]) |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '子订单参数异常[单品]', |
|
|
|
'params' => json_encode($params) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
$orderGoods = OrderGoods::query()->where(['order_id' => $orderChild->id, 'id' => $order_goods_id])->first(); |
|
|
|
|
|
|
|
if (is_null($orderGoods)) { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '订单商品参数异常[单品]', |
|
|
|
'params' => json_encode($params) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$totalAmount = $orderMain->total_money; // 订单可退款金额,总订单金额不含配送费和服务费
|
|
|
|
$preRefundAmount = 0; // 预退款金额
|
|
|
|
$refundAmount = 0; // 实际退款金额
|
|
|
|
$refundType = 'Main'; // 退款类型, Main整单 Sub子单 Goods单品
|
|
|
|
if ($orderGoods) { // 1. 如果订单商品存在则说明要退单品
|
|
|
|
$preRefundAmount = bcmul($orderGoods->price, $orderGoods->number, 2); |
|
|
|
$refundType = 'Goods'; |
|
|
|
} elseif ($orderChild) { // 2. 否则如果存在子订单说明退子订单
|
|
|
|
$preRefundAmount = $orderChild->money; |
|
|
|
$refundType = 'Sub'; |
|
|
|
} else { // 3. 再则如果存在主订单说明退主订单
|
|
|
|
$preRefundAmount = $orderMain->total_money; |
|
|
|
$refundType = 'Main'; |
|
|
|
} |
|
|
|
|
|
|
|
// 占订单金额的比例
|
|
|
|
$rate = bcdiv($preRefundAmount, $totalAmount, 6); |
|
|
|
// 计算优惠券所占金额
|
|
|
|
$couponMoney = bcmul($orderMain->coupon_money, $rate, 6); |
|
|
|
// 计算本次退款实际退款金额
|
|
|
|
$refundAmount = bcsub($preRefundAmount, $couponMoney, 2); |
|
|
|
|
|
|
|
if ($refundAmount <= 0) { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '没有可退款金额[实际退款金额]', |
|
|
|
'params' => json_encode($params) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
// 开始退款
|
|
|
|
$config = config('wxpay'); |
|
|
|
$app = Factory::payment($config); |
|
|
|
$app['guzzle_handler'] = CoroutineHandler::class; |
|
|
|
$result = $app->refund->byOutTradeNumber( |
|
|
|
$orderMain->global_order_id, |
|
|
|
$orderMain->global_order_id, |
|
|
|
bcmul($orderMain->money, 100, 0), |
|
|
|
bcmul($refundAmount, 100, 0), |
|
|
|
[ |
|
|
|
'refund_desc' => '订单协商退款['.$refundType.']', |
|
|
|
'notify_url' => config('wechat.notify_url.refund_single'), |
|
|
|
] |
|
|
|
); |
|
|
|
|
|
|
|
if ($result['return_code'] == 'FAIL') { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => $result['return_msg'].'[微信退款失败]', |
|
|
|
'params' => json_encode($result) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
if ($result['result_code'] == 'FAIL') { |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => $result['err_code_des'].'[微信退款失败]'.$result['err_code'], |
|
|
|
'params' => json_encode($result) |
|
|
|
]); |
|
|
|
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
// 退款申请成功,查询退款状态
|
|
|
|
$refundResult = $app->refund->queryByRefundId($result['refund_id']); |
|
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|
|
|
'jsonrpc_order_service_exception_onlineSingleRefund' => '[微信退款查询]', |
|
|
|
'params' => json_encode($refundResult) |
|
|
|
]); |
|
|
|
|
|
|
|
} |
|
|
|
} |