HandlesRefunds.php 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <?php
  2. namespace App\Services\Client\Traits;
  3. use App\Enums\OrderStatus;
  4. use App\Models\MemberUser;
  5. use App\Models\Order;
  6. use App\Models\WalletRefundRecord;
  7. use Illuminate\Support\Facades\Log;
  8. trait HandlesRefunds
  9. {
  10. /**
  11. * 处理订单取消退款
  12. */
  13. protected function handleCancelRefund(Order $order): void
  14. {
  15. $user = $order->user;
  16. $deductAmount = $this->calculateDeductAmount($order);
  17. $this->processRefund($user, $order, $deductAmount);
  18. }
  19. /**
  20. * 计算扣除金额
  21. */
  22. private function calculateDeductAmount(Order $order): float
  23. {
  24. $baseAmount = $order->payment_amount + $order->balance_amount - $order->traffic_amount;
  25. return match ($order->state) {
  26. OrderStatus::ACCEPTED->value => $baseAmount * 0.2, // 已接单扣除20%
  27. OrderStatus::DEPARTED->value => $baseAmount * 0.5, // 已出发扣除50%
  28. default => 0
  29. };
  30. }
  31. /**
  32. * 处理退款流程
  33. */
  34. private function processRefund(MemberUser $user, Order $order, float $deductAmount): void
  35. {
  36. try {
  37. $refundAmount = $this->calculateRefundAmount($order, $deductAmount);
  38. if ($refundAmount > 0) {
  39. // 退还余额
  40. $user->wallet->increment('total_balance', $refundAmount);
  41. $user->wallet->increment('available_balance', $refundAmount);
  42. // 创建退款记录
  43. $this->createRefundRecord($order, $refundAmount);
  44. }
  45. } catch (\Exception $e) {
  46. Log::error('处理退款失败', [
  47. 'order_id' => $order->id,
  48. 'user_id' => $user->id,
  49. 'error' => $e->getMessage(),
  50. ]);
  51. throw $e;
  52. }
  53. }
  54. /**
  55. * 创建退款记录
  56. */
  57. private function createRefundRecord(Order $order, float $refundAmount): void
  58. {
  59. WalletRefundRecord::create([
  60. 'order_id' => $order->id,
  61. 'user_id' => $order->user_id,
  62. 'amount' => $refundAmount,
  63. 'state' => 'success',
  64. ]);
  65. }
  66. }