Refund.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. // 回退用户余额
  65. UserModel::setIncBalance((int)$order['user_id'], (float)$money);
  66. // 记录余额明细
  67. BalanceLogModel::add(SceneEnum::REFUND, [
  68. 'user_id' => $order['user_id'],
  69. 'money' => $money,
  70. ], ['order_no' => $order['order_no']], $order['store_id']);
  71. return true;
  72. }
  73. /**
  74. * 第三方支付退款
  75. * @param mixed $order 订单信息
  76. * @param string $money 退款金额
  77. * @return bool
  78. * @throws BaseException
  79. * @throws \think\db\exception\DataNotFoundException
  80. * @throws \think\db\exception\DbException
  81. * @throws \think\db\exception\ModelNotFoundException
  82. */
  83. private function payment($order, string $money): bool
  84. {
  85. // 获取第三方交易记录
  86. $tradeInfo = $this->getTradeInfo($order['trade_id']);
  87. // 获取支付方式的配置信息
  88. $options = $this->getPaymentConfig($order);
  89. // 构建支付模块
  90. $Payment = PaymentFacade::store($order['pay_method'])->setOptions($options, $order['platform']);
  91. // 执行第三方支付下单API
  92. if (!$Payment->refund($tradeInfo['out_trade_no'], $money, ['totalFee' => (string)$order['pay_price']])) {
  93. throwError($Payment->getError() ?: '第三方支付退款API调用失败');
  94. }
  95. // 将第三方交易记录更新为已退款状态
  96. $this->updateTradeState($order['trade_id']);
  97. return true;
  98. }
  99. /**
  100. * 获取第三方交易记录
  101. * @param int $tradeId 交易记录ID
  102. * @return PaymentTradeModel|null
  103. * @throws BaseException
  104. */
  105. private function getTradeInfo(int $tradeId): ?PaymentTradeModel
  106. {
  107. $tradeInfo = PaymentTradeModel::detail($tradeId);
  108. empty($tradeInfo) && throwError('未找到第三方交易记录');
  109. return $tradeInfo;
  110. }
  111. /**
  112. * 将第三方交易记录更新为已退款状态
  113. * @param int $tradeId 交易记录ID
  114. */
  115. private function updateTradeState(int $tradeId)
  116. {
  117. PaymentTradeModel::updateToRefund($tradeId);
  118. }
  119. /**
  120. * 获取支付方式的配置信息
  121. * @param mixed $order 订单信息
  122. * @return mixed
  123. * @throws BaseException
  124. * @throws \think\db\exception\DataNotFoundException
  125. * @throws \think\db\exception\DbException
  126. * @throws \think\db\exception\ModelNotFoundException
  127. */
  128. private function getPaymentConfig($order)
  129. {
  130. $PaymentModel = new PaymentModel;
  131. $templateInfo = $PaymentModel->getPaymentInfo($order['pay_method'], $order['platform'], $order['store_id']);
  132. return $templateInfo['template']['config'][$order['pay_method']];
  133. }
  134. }