6
0
Fork 0

微信支付退款

release
李静 2021-12-20 18:13:14 +08:00
parent 9e8db909fa
commit 1bc12ba559
6 changed files with 111 additions and 78 deletions

View File

@ -42,11 +42,6 @@ class OrderRefundCommand extends Command
}
$this->{$method}($task);
$task->update([
'status' => OrderRefundTask::STATUS_SUCCESS,
'failed_reason' => null,
]);
} catch (Throwable $e) {
report($e);
@ -62,7 +57,7 @@ class OrderRefundCommand extends Command
}
/**
* 微信退款
* 微信支付退款
*
* @param \App\Models\OrderRefundTask $orderRefundTask
* @return void
@ -78,7 +73,26 @@ class OrderRefundCommand extends Command
$orderRefundTask->amount,
[
'refund_desc' => $orderRefundTask->reason,
'notify_url' => url(route('wxpay.order_refund_notify', [], false), [], true),
]
);
$orderRefundTask->update([
'status' => OrderRefundTask::STATUS_SUCCESS,
'failed_reason' => null,
]);
}
/**
* 现金支付退款
*
* @param \App\Models\OrderRefundTask $orderRefundTask
* @return void
*/
protected function refundByOffline(OrderRefundTask $orderRefundTask)
{
$orderRefundTask->update([
'status' => OrderRefundTask::STATUS_SUCCESS,
]);
}
}

View File

@ -4,6 +4,7 @@ namespace App\Endpoint\Callback\Http\Controllers;
use App\Exceptions\BizException;
use App\Models\Order;
use App\Models\OrderRefundTask;
use App\Services\OrderService;
use App\Services\WeChatPayService;
use Illuminate\Database\Eloquent\ModelNotFoundException;
@ -14,12 +15,12 @@ use Throwable;
class WeChatPayController extends Controller
{
/**
* 支付结果通知
* 订单支付结果通知
*
* @param \App\Services\WeChatPayService $weChatPayService
* @return \Illuminate\Http\Response
*/
public function paidNotify(WeChatPayService $weChatPayService)
public function orderPaidNotify(WeChatPayService $weChatPayService)
{
return $weChatPayService->handlePaidNotify(function ($message, $fail) {
// 通信失败
@ -32,16 +33,17 @@ class WeChatPayController extends Controller
return true;
}
$attach = json_decode($message['attach'], true);
if (! isset($attach['pay_target'])) {
return true;
}
switch ($attach['pay_target']) {
case 'order':
$this->handlePaidNotifyForOrder($message);
break;
try {
DB::transaction(function () use ($message) {
(new OrderService())->paySuccess($message['out_trade_no'], [
'pay_sn' => $message['transaction_id'],
'pay_way' => Order::PAY_WAY_WXPAY,
'pay_at' => Carbon::parse($message['time_end']),
]);
});
} catch (ModelNotFoundException | BizException $e) {
} catch (Throwable $e) {
throw $e;
}
return true;
@ -49,24 +51,30 @@ class WeChatPayController extends Controller
}
/**
* 处理订单支付结果通知
* 订单退款结果通知
*
* @param array $message
* @return void
* @param \App\Services\WeChatPayService $weChatPayService
* @return \Illuminate\Http\Response
*/
protected function handlePaidNotifyForOrder(array $message): void
public function orderRefundedNotify(WeChatPayService $weChatPayService)
{
try {
DB::transaction(function () use ($message) {
(new OrderService())->paySuccess($message['out_trade_no'], [
'pay_sn' => $message['transaction_id'],
'pay_way' => Order::PAY_WAY_WXPAY,
'pay_at' => Carbon::parse($message['time_end']),
return $weChatPayService->handleRefundedNotify(function ($message, $reqInfo, $fail) {
// 通信失败
if (data_get($message, 'return_code') !== 'SUCCESS') {
return $fail('通信失败');
}
// 退款失败
if ($reqInfo['refund_status'] !== 'SUCCESS') {
$orderRefundTask = OrderRefundTask::where('sn', $reqInfo['out_refund_no'])->first();
$orderRefundTask?->update([
'status' => OrderRefundTask::STATUS_FAILED,
'failed_reason' => $reqInfo['refund_status'] === 'CHANGE' ? '退款异常' : '退款关闭',
]);
});
} catch (ModelNotFoundException|BizException $e) {
} catch (Throwable $e) {
throw $e;
}
}
return true;
});
}
}

View File

@ -7,4 +7,5 @@ use Illuminate\Support\Facades\Route;
//快递100物流推送
Route::post('kuaidi100', [Kuaidi100Controller::class, 'notify']);
// 微信支付通知
Route::post('wxpay/paid-notify', [WeChatPayController::class, 'paidNotify'])->name('wxpay.paid_notify');
Route::post('wxpay/order-paid-notify', [WeChatPayController::class, 'orderPaidNotify'])->name('wxpay.order_paid_notify');
Route::post('wxpay/order-refund-notify', [WeChatPayController::class, 'orderRefundedNotify'])->name('wxpay.order_refund_notify');

View File

@ -6,9 +6,9 @@ use Illuminate\Database\Eloquent\Model;
class OrderRefundTask extends Model
{
public const STATUS_PENDING = 0;
public const STATUS_SUCCESS = 5;
public const STATUS_FAILED = 6;
public const STATUS_PENDING = 0; // 待处理
public const STATUS_SUCCESS = 5; // 退款成功
public const STATUS_FAILED = 6; // 退款失败
/**
* @var array

View File

@ -90,45 +90,6 @@ class OrderService
return $order;
}
/**
* 确认快速下单
*
* @param \App\Models\User $user
* @param int $skuId
* @param int $quantity
* @param int|null $shippingAddressId
* @param int|null $couponId
* @return array
*/
public function verifyQuickOrder(User $user, int $skuId, int $quantity, ?int $shippingAddressId = null, ?int $couponId = null)
{
$sku = ProductSku::online()->findOrFail($skuId);
$product = [
'sku' => $sku,
'quantity' => $quantity,
];
return $this->verifyOrder($user, [$product], $shippingAddressId, $couponId);
}
/**
* 确认购物车订单
*
* @param \App\Models\User $user
* @param array $shoppingCartItemIds
* @param int|null $shippingAddressId
* @param int|null $couponId
* @return array
*/
public function verifyShoppingCartOrder(User $user, array $shoppingCartItemIds, ?int $shippingAddressId = null, ?int $couponId = null)
{
// 获取购买商品
$products = $this->getProductsByShoppingCart($user, $shoppingCartItemIds);
return $this->verifyOrder($user, $products, $shippingAddressId, $couponId);
}
/**
* 创建订单
*
@ -254,6 +215,45 @@ class OrderService
]);
}
/**
* 确认快速下单
*
* @param \App\Models\User $user
* @param int $skuId
* @param int $quantity
* @param int|null $shippingAddressId
* @param int|null $couponId
* @return array
*/
public function verifyQuickOrder(User $user, int $skuId, int $quantity, ?int $shippingAddressId = null, ?int $couponId = null)
{
$sku = ProductSku::online()->findOrFail($skuId);
$product = [
'sku' => $sku,
'quantity' => $quantity,
];
return $this->verifyOrder($user, [$product], $shippingAddressId, $couponId);
}
/**
* 确认购物车订单
*
* @param \App\Models\User $user
* @param array $shoppingCartItemIds
* @param int|null $shippingAddressId
* @param int|null $couponId
* @return array
*/
public function verifyShoppingCartOrder(User $user, array $shoppingCartItemIds, ?int $shippingAddressId = null, ?int $couponId = null)
{
// 获取购买商品
$products = $this->getProductsByShoppingCart($user, $shoppingCartItemIds);
return $this->verifyOrder($user, $products, $shippingAddressId, $couponId);
}
/**
* 确认订单
*
@ -599,13 +599,12 @@ class OrderService
if (in_array($payWay, $this->wxpayWays)) {
return (new WeChatPayService())->pay([
'attach' => json_encode([
'pay_target' => 'order',
'pay_way' => $payWay,
]),
'body' => config('settings.app_name').'-商城订单',
'out_trade_no' => $order->sn,
'total_fee' => $order->total_amount,
'notify_url' => url(route('wxpay.paid_notify', [], false), [], true),
'notify_url' => url(route('wxpay.order_paid_notify', [], false), [], true),
'trade_type' => PayWay::$wxpayTradeTypes[$payWay],
]);
}

View File

@ -167,4 +167,15 @@ class WeChatPayService
return $result;
}
/**
* 退款结果通知
*
* @param \Closure $closure
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handleRefundedNotify(Closure $closure)
{
return $this->app->handleRefundedNotify($closure);
}
}