MixedPayService.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeshop100%开源免费商用商城系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | 商业版本务必购买商业授权,以免引起法律纠纷
  8. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  9. // | gitee下载:https://gitee.com/likeshop_gitee
  10. // | github下载:https://github.com/likeshop-github
  11. // | 访问官网:https://www.likeshop.cn
  12. // | 访问社区:https://home.likeshop.cn
  13. // | 访问手册:http://doc.likeshop.cn
  14. // | 微信公众号:likeshop技术社区
  15. // | likeshop团队 版权所有 拥有最终解释权
  16. // +----------------------------------------------------------------------
  17. // | author: likeshopTeam
  18. // +----------------------------------------------------------------------
  19. namespace app\common\service\pay;
  20. use app\common\enum\AccountLogEnum;
  21. use app\common\enum\PayEnum;
  22. use app\common\logic\AccountLogLogic;
  23. use app\common\model\User;
  24. use app\common\service\pay\base\BasePayService;
  25. use app\common\service\pay\base\StatusTrait;
  26. use think\facade\Db;
  27. /**
  28. * 混合支付服务(余额+微信)
  29. * Class MixedPayService
  30. * @package app\common\service\pay
  31. */
  32. class MixedPayService extends BasePayService
  33. {
  34. use StatusTrait;
  35. protected $wechatPayService;
  36. protected $balancePayService;
  37. public function __construct($terminal, $userId = null)
  38. {
  39. parent::__construct(['terminal' => $terminal]);
  40. $this->wechatPayService = new WeChatPayService($terminal, $userId);
  41. $this->balancePayService = new BalancePayService();
  42. }
  43. function realPay()
  44. {
  45. return $this->wechatPayService->realPay();
  46. }
  47. /**
  48. * @notes 混合支付(余额+微信)
  49. * @param $from 订单类型
  50. * @param $order 订单信息
  51. * @return array|false
  52. * @author 系统
  53. * @date 2024/12/19
  54. */
  55. public function pay($from, $order)
  56. {
  57. Db::startTrans();
  58. try {
  59. $user = User::findOrEmpty($order['user_id']);
  60. if ($user->isEmpty()) {
  61. throw new \Exception('用户不存在');
  62. }
  63. outFileLog($user,'prepay','$user');
  64. $userBalance = $user['user_money']; // 用户余额
  65. $orderAmount = $order['order_amount']; // 订单金额
  66. // 如果余额足够支付全部订单,直接使用余额支付
  67. if ($userBalance >= $orderAmount) {
  68. $result = $this->balancePayService->pay($from, $order);
  69. if ($result === false) {
  70. throw new \Exception('余额支付失败');
  71. }
  72. Db::commit();
  73. return $result;
  74. }
  75. // 余额不足,使用混合支付
  76. $balanceAmount = $userBalance; // 使用全部余额
  77. $wechatAmount = $orderAmount - $balanceAmount; // 剩余金额用微信支付
  78. // 先扣除用户余额
  79. if ($balanceAmount > 0) {
  80. User::update([
  81. 'user_money' => ['dec', $balanceAmount]
  82. ], ['id' => $order['user_id']]);
  83. // 记录余额流水
  84. AccountLogLogic::add(
  85. $order['user_id'],
  86. AccountLogEnum::BNW_DEC_ORDER,
  87. AccountLogEnum::DEC,
  88. $balanceAmount,
  89. $order['sn'],
  90. '混合支付-余额部分'
  91. );
  92. }
  93. outFileLog(2,'prepay','2');
  94. // 创建微信支付订单(金额为剩余需要支付的金额)
  95. $wechatOrder = $order;
  96. $wechatOrder['order_amount'] = $wechatAmount;
  97. $wechatOrder['balance_amount'] = $balanceAmount; // 记录已使用的余额金额
  98. outFileLog($wechatOrder,'prepay','$wechatOrder');
  99. $result = $this->wechatPayService->pay($from, $wechatOrder);
  100. if ($result === false) {
  101. throw new \Exception('微信支付创建失败');
  102. }
  103. // 在返回结果中添加混合支付信息
  104. $result['pay_way'] = PayEnum::MIXED_PAY;
  105. $result['balance_amount'] = $balanceAmount;
  106. $result['wechat_amount'] = $wechatAmount;
  107. $result['total_amount'] = $orderAmount;
  108. Db::commit();
  109. return $result;
  110. } catch (\Exception $e) {
  111. Db::rollback();
  112. $this->setStatus(false, $e->getMessage());
  113. return false;
  114. }
  115. }
  116. /**
  117. * @notes 混合支付退款
  118. * @param $order 订单信息
  119. * @param $refundAmount 退款金额
  120. * @param $afterSaleId 售后ID
  121. * @return bool
  122. */
  123. public function refund($order, $refundAmount, $afterSaleId)
  124. {
  125. try {
  126. // 获取订单的余额支付金额和微信支付金额
  127. $balanceAmount = $order['balance_amount'] ?? 0;
  128. $wechatAmount = $order['order_amount'] - $balanceAmount;
  129. // 按比例退款
  130. if ($refundAmount >= $order['order_amount']) {
  131. // 全额退款
  132. $refundBalanceAmount = $balanceAmount;
  133. $refundWechatAmount = $wechatAmount;
  134. } else {
  135. // 部分退款,按比例分配
  136. $refundRatio = $refundAmount / $order['order_amount'];
  137. $refundBalanceAmount = $balanceAmount * $refundRatio;
  138. $refundWechatAmount = $wechatAmount * $refundRatio;
  139. }
  140. // 退回余额
  141. if ($refundBalanceAmount > 0) {
  142. $this->balancePayService->refund($order, $refundBalanceAmount, $afterSaleId);
  143. }
  144. // 微信退款
  145. if ($refundWechatAmount > 0) {
  146. // 这里需要调用微信退款接口
  147. // $this->wechatPayService->refund($order['sn'], $refundWechatAmount, $afterSaleId);
  148. }
  149. return true;
  150. } catch (\Exception $e) {
  151. $this->setStatus(false, $e->getMessage());
  152. return false;
  153. }
  154. }
  155. // 实现抽象方法
  156. public function payMnp() { return $this->wechatPayService->payMnp(); }
  157. public function payOa() { return $this->wechatPayService->payOa(); }
  158. public function payIos() { return $this->wechatPayService->payIos(); }
  159. public function payAndroid() { return $this->wechatPayService->payAndroid(); }
  160. public function payH5() { return $this->wechatPayService->payH5(); }
  161. public function payPc() { return $this->wechatPayService->payPc(); }
  162. public function payNotify() { return $this->wechatPayService->payNotify(); }
  163. public function queryPay() { return $this->wechatPayService->queryPay(); }
  164. public function queryRefund() { return $this->wechatPayService->queryRefund(); }
  165. }