Refund.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\common\service\order;
  13. use app\common\model\Payment as PaymentModel;
  14. use app\common\model\PaymentTrade as PaymentTradeModel;
  15. use app\common\model\User as UserModel;
  16. use app\common\model\user\BalanceLog as BalanceLogModel;
  17. use app\common\service\BaseService;
  18. use app\common\enum\payment\Method as PaymentMethodEnum;
  19. use app\common\enum\user\balanceLog\Scene as SceneEnum;
  20. use app\common\library\payment\Facade as PaymentFacade;
  21. use cores\exception\BaseException;
  22. /**
  23. * 订单退款服务类
  24. * Class Refund
  25. * @package app\common\service\order
  26. */
  27. class Refund extends BaseService
  28. {
  29. /**
  30. * 执行订单退款
  31. * @param mixed $order 订单信息
  32. * @param string|null $money 退款金额
  33. * @return bool
  34. * @throws \cores\exception\BaseException
  35. * @throws \think\db\exception\DataNotFoundException
  36. * @throws \think\db\exception\DbException
  37. * @throws \think\db\exception\ModelNotFoundException
  38. */
  39. public function handle($order, ?string $money = null): bool
  40. {
  41. // 退款金额,如不指定则默认为订单实付款金额
  42. is_null($money) && $money = (string)$order['pay_price'];
  43. if ($money == 0) {
  44. return true;
  45. }
  46. // 余额支付退款
  47. if ($order['pay_method'] === PaymentMethodEnum::BALANCE) {
  48. return $this->balance($order, $money);
  49. }
  50. // 第三方支付退款
  51. if (in_array($order['pay_method'], [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) {
  52. return $this->payment($order, $money);
  53. }
  54. return false;
  55. }
  56. /**
  57. * 余额支付退款
  58. * @param mixed $order 订单信息
  59. * @param string $money 退款金额
  60. * @return bool
  61. */
  62. private function balance($order, string $money): bool
  63. {
  64. if ($money <= 0) {
  65. return false;
  66. }
  67. // 回退用户余额
  68. UserModel::setIncBalance((int)$order['user_id'], (float)$money);
  69. // 记录余额明细
  70. BalanceLogModel::add(SceneEnum::REFUND, [
  71. 'user_id' => $order['user_id'],
  72. 'money' => $money,
  73. ], ['order_no' => $order['order_no']], $order['store_id']);
  74. return true;
  75. }
  76. /**
  77. * 第三方支付退款
  78. * @param mixed $order 订单信息
  79. * @param string $money 退款金额
  80. * @return bool
  81. * @throws BaseException
  82. * @throws \think\db\exception\DataNotFoundException
  83. * @throws \think\db\exception\DbException
  84. * @throws \think\db\exception\ModelNotFoundException
  85. */
  86. private function payment($order, string $money): bool
  87. {
  88. // 获取第三方交易记录
  89. $tradeInfo = $this->getTradeInfo($order['trade_id']);
  90. // 获取支付方式的配置信息
  91. $options = $this->getPaymentConfig($order);
  92. // 构建支付模块
  93. $Payment = PaymentFacade::store($order['pay_method'])->setOptions($options, $order['platform']);
  94. // 执行第三方支付下单API
  95. if (!$Payment->refund($tradeInfo['out_trade_no'], $money, ['totalFee' => (string)$order['pay_price']])) {
  96. throwError($Payment->getError() ?: '第三方支付退款API调用失败');
  97. }
  98. // 将第三方交易记录更新为已退款状态
  99. $this->updateTradeState($order['trade_id']);
  100. return true;
  101. }
  102. /**
  103. * 获取第三方交易记录
  104. * @param int $tradeId 交易记录ID
  105. * @return PaymentTradeModel|null
  106. * @throws BaseException
  107. */
  108. private function getTradeInfo(int $tradeId): ?PaymentTradeModel
  109. {
  110. $tradeInfo = PaymentTradeModel::detail($tradeId);
  111. empty($tradeInfo) && throwError('未找到第三方交易记录');
  112. return $tradeInfo;
  113. }
  114. /**
  115. * 将第三方交易记录更新为已退款状态
  116. * @param int $tradeId 交易记录ID
  117. */
  118. private function updateTradeState(int $tradeId)
  119. {
  120. PaymentTradeModel::updateToRefund($tradeId);
  121. }
  122. /**
  123. * 获取支付方式的配置信息
  124. * @param mixed $order 订单信息
  125. * @return mixed
  126. * @throws BaseException
  127. * @throws \think\db\exception\DataNotFoundException
  128. * @throws \think\db\exception\DbException
  129. * @throws \think\db\exception\ModelNotFoundException
  130. */
  131. private function getPaymentConfig($order)
  132. {
  133. $PaymentModel = new PaymentModel;
  134. $templateInfo = $PaymentModel->getPaymentInfo($order['pay_method'], $order['platform'], $order['store_id']);
  135. return $templateInfo['template']['config'][$order['pay_method']];
  136. }
  137. }