MixedPayService.php 6.7 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. $userBalance = $user['user_money']; // 用户余额
  64. $orderAmount = $order['order_amount']; // 订单金额
  65. // 如果余额足够支付全部订单,直接使用余额支付
  66. if ($userBalance >= $orderAmount) {
  67. $result = $this->balancePayService->pay($from, $order);
  68. if ($result === false) {
  69. throw new \Exception('余额支付失败');
  70. }
  71. Db::commit();
  72. return $result;
  73. }
  74. // 余额不足,使用混合支付
  75. $balanceAmount = $userBalance; // 使用全部余额
  76. $wechatAmount = $orderAmount - $balanceAmount; // 剩余金额用微信支付
  77. // 先扣除用户余额
  78. if ($balanceAmount > 0) {
  79. User::update([
  80. 'user_money' => ['dec', $balanceAmount]
  81. ], ['id' => $order['user_id']]);
  82. // 记录余额流水
  83. AccountLogLogic::add(
  84. $order['user_id'],
  85. AccountLogEnum::BNW_DEC_ORDER,
  86. AccountLogEnum::DEC,
  87. $balanceAmount,
  88. $order['sn'],
  89. '混合支付-余额部分'
  90. );
  91. }
  92. // 创建微信支付订单(金额为剩余需要支付的金额)
  93. $wechatOrder = $order;
  94. $wechatOrder['order_amount'] = $wechatAmount;
  95. $wechatOrder['balance_amount'] = $balanceAmount; // 记录已使用的余额金额
  96. $result = $this->wechatPayService->pay($from, $wechatOrder);
  97. if ($result === false) {
  98. throw new \Exception('微信支付创建失败');
  99. }
  100. // 在返回结果中添加混合支付信息
  101. $result['pay_way'] = PayEnum::MIXED_PAY;
  102. $result['balance_amount'] = $balanceAmount;
  103. $result['wechat_amount'] = $wechatAmount;
  104. $result['total_amount'] = $orderAmount;
  105. Db::commit();
  106. return $result;
  107. } catch (\Exception $e) {
  108. Db::rollback();
  109. $this->setStatus(false, $e->getMessage());
  110. return false;
  111. }
  112. }
  113. /**
  114. * @notes 混合支付退款
  115. * @param $order 订单信息
  116. * @param $refundAmount 退款金额
  117. * @param $afterSaleId 售后ID
  118. * @return bool
  119. */
  120. public function refund($order, $refundAmount, $afterSaleId)
  121. {
  122. try {
  123. // 获取订单的余额支付金额和微信支付金额
  124. $balanceAmount = $order['balance_amount'] ?? 0;
  125. $wechatAmount = $order['order_amount'] - $balanceAmount;
  126. // 按比例退款
  127. if ($refundAmount >= $order['order_amount']) {
  128. // 全额退款
  129. $refundBalanceAmount = $balanceAmount;
  130. $refundWechatAmount = $wechatAmount;
  131. } else {
  132. // 部分退款,按比例分配
  133. $refundRatio = $refundAmount / $order['order_amount'];
  134. $refundBalanceAmount = $balanceAmount * $refundRatio;
  135. $refundWechatAmount = $wechatAmount * $refundRatio;
  136. }
  137. // 退回余额
  138. if ($refundBalanceAmount > 0) {
  139. $this->balancePayService->refund($order, $refundBalanceAmount, $afterSaleId);
  140. }
  141. // 微信退款
  142. if ($refundWechatAmount > 0) {
  143. // 这里需要调用微信退款接口
  144. // $this->wechatPayService->refund($order['sn'], $refundWechatAmount, $afterSaleId);
  145. }
  146. return true;
  147. } catch (\Exception $e) {
  148. $this->setStatus(false, $e->getMessage());
  149. return false;
  150. }
  151. }
  152. // 实现抽象方法
  153. public function payMnp() { return $this->wechatPayService->payMnp(); }
  154. public function payOa() { return $this->wechatPayService->payOa(); }
  155. public function payIos() { return $this->wechatPayService->payIos(); }
  156. public function payAndroid() { return $this->wechatPayService->payAndroid(); }
  157. public function payH5() { return $this->wechatPayService->payH5(); }
  158. public function payPc() { return $this->wechatPayService->payPc(); }
  159. public function payNotify() { return $this->wechatPayService->payNotify(); }
  160. public function queryPay() { return $this->wechatPayService->queryPay(); }
  161. public function queryRefund() { return $this->wechatPayService->queryRefund(); }
  162. }