IntegralOrderRefundLogic.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeshop开源商城系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | gitee下载:https://gitee.com/likeshop_gitee
  7. // | github下载:https://github.com/likeshop-github
  8. // | 访问官网:https://www.likeshop.cn
  9. // | 访问社区:https://home.likeshop.cn
  10. // | 访问手册:http://doc.likeshop.cn
  11. // | 微信公众号:likeshop技术社区
  12. // | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
  13. // | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
  14. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  15. // | likeshop团队版权所有并拥有最终解释权
  16. // +----------------------------------------------------------------------
  17. // | author: likeshop.cn.team
  18. // +----------------------------------------------------------------------
  19. namespace app\common\logic;
  20. use app\common\service\WeChatConfigService;
  21. use app\common\service\pay\{AliPayService, BalancePayService, WeChatPayService};
  22. use app\common\model\{IntegralGoods, IntegralOrder, IntegralOrderRefund, User};
  23. use app\common\enum\{AccountLogEnum, IntegralGoodsEnum, IntegralOrderEnum, IntegralOrderRefundEnum, PayEnum};
  24. use think\Exception;
  25. /**
  26. * 积分订单退款逻辑
  27. * Class OrderRefundLogic
  28. * @package app\common\logic
  29. */
  30. class IntegralOrderRefundLogic extends BaseLogic
  31. {
  32. /**
  33. * @notes 取消订单(标记订单状态,退回库存,扣减销量)
  34. * @param int $orderId
  35. * @author 段誉
  36. * @date 2022/4/1 10:09
  37. */
  38. public static function cancelOrder(int $orderId)
  39. {
  40. // 订单信息
  41. $order = IntegralOrder::findOrEmpty($orderId);
  42. $order->cancel_time = time();
  43. $order->order_status = IntegralOrderEnum::ORDER_STATUS_DOWN;
  44. $order->save();
  45. // 订单商品信息
  46. $goodsSnap = $order['goods_snap'];
  47. // 退回库存, 扣减销量
  48. IntegralGoods::where([['id', '=', $goodsSnap['id']], ['sales', '>=', $order['total_num']]])
  49. ->inc('stock', $order['total_num'])
  50. ->dec('sales', $order['total_num'])
  51. ->update();
  52. }
  53. /**
  54. * @notes 退回已支付积分
  55. * @param int $id
  56. * @return bool
  57. * @author 段誉
  58. * @date 2022/4/1 10:09
  59. */
  60. public static function refundOrderIntegral(int $id)
  61. {
  62. $order = IntegralOrder::findOrEmpty($id);
  63. if ($order['order_integral'] > 0) {
  64. // 退回积分
  65. User::where(['id' => $order['user_id']])
  66. ->inc('user_integral', $order['order_integral'])
  67. ->update();
  68. // 流水日志
  69. AccountLogLogic::add(
  70. $order['user_id'],
  71. AccountLogEnum::INTEGRAL_INC_CANCEL_INTEGRAL,
  72. AccountLogEnum::INC,
  73. $order['order_integral'],
  74. $order['sn']
  75. );
  76. // 更新积分订单表 已退积分
  77. IntegralOrder::where(['id' => $id])->update([
  78. 'refund_integral' => $order['order_integral']
  79. ]);
  80. }
  81. return true;
  82. }
  83. /**
  84. * @notes 退回已支付金额
  85. * @param int $orderId
  86. * @return bool
  87. * @throws Exception
  88. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  89. * @throws \think\db\exception\DataNotFoundException
  90. * @throws \think\db\exception\DbException
  91. * @throws \think\db\exception\ModelNotFoundException
  92. * @author 段誉
  93. * @date 2022/3/3 16:00
  94. */
  95. public static function refundOrderAmount(int $orderId)
  96. {
  97. // 订单信息
  98. $order = IntegralOrder::findOrEmpty($orderId);
  99. // 订单商品信息
  100. $goodsSnap = $order['goods_snap'];
  101. //已支付的商品订单,取消,退款
  102. if ($goodsSnap['type'] != IntegralGoodsEnum::TYPE_GOODS
  103. || $order['refund_status'] != IntegralOrderEnum::NO_REFUND
  104. || $order['order_amount'] <= 0
  105. ) {
  106. return true;
  107. }
  108. // 退款记录
  109. $refund = self::addRefundLog($order, $order['order_amount'], IntegralOrderRefundEnum::STATUS_ING);
  110. switch ($order['pay_way']) {
  111. //余额退款
  112. case PayEnum::BALANCE_PAY:
  113. self::balancePayRefund($order, $refund);
  114. break;
  115. //微信退款
  116. case PayEnum::WECHAT_PAY:
  117. self::wechatPayRefund($order, $refund);
  118. break;
  119. //支付宝退款
  120. case PayEnum::ALI_PAY:
  121. self::aliPayRefund($order, $refund);
  122. break;
  123. default:
  124. throw new \Exception('支付方式异常');
  125. }
  126. // 更新订单退款状态为已退款
  127. IntegralOrder::update([
  128. 'id' => $order['id'],
  129. 'refund_status' => IntegralOrderEnum::IS_REFUND,//订单退款状态; 0-未退款;1-已退款
  130. 'refund_amount' => $order['order_amount'],
  131. ]);
  132. // 更新退款记录状态为退款成功
  133. IntegralOrderRefund::update([
  134. 'id' => $refund['id'],
  135. 'status' => IntegralOrderRefundEnum::STATUS_SUCCESS
  136. ]);
  137. return true;
  138. }
  139. /**
  140. * @notes 增加退款记录
  141. * @param $order
  142. * @param $refundAmount
  143. * @param $status // 退款状态,0退款中,1完成退款,2退款失败
  144. * @param string $msg
  145. * @return IntegralOrderRefund|\think\Model
  146. * @throws \think\db\exception\DataNotFoundException
  147. * @throws \think\db\exception\DbException
  148. * @throws \think\db\exception\ModelNotFoundException
  149. * @author 段誉
  150. * @date 2022/3/3 14:51
  151. */
  152. public static function addRefundLog($order, $refundAmount, $status, $msg = '')
  153. {
  154. return IntegralOrderRefund::create([
  155. 'sn' => generate_sn(new IntegralOrderRefund(), 'sn'),
  156. 'order_id' => $order['id'],
  157. 'user_id' => $order['user_id'],
  158. 'order_amount' => $order['order_amount'],
  159. 'refund_amount' => $refundAmount,
  160. 'transaction_id' => $order['transaction_id'],
  161. 'create_time' => time(),
  162. 'refund_status' => $status,
  163. 'refund_time' => time(),
  164. 'refund_msg' => json_encode($msg, JSON_UNESCAPED_UNICODE),
  165. ]);
  166. }
  167. /**
  168. * @notes 微信支付退款
  169. * @param $order
  170. * @param $refund_id
  171. * @throws Exception
  172. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  173. * @author 段誉
  174. * @date 2022/3/3 14:52
  175. */
  176. public static function wechatPayRefund($order, $refund)
  177. {
  178. $pay = new WeChatPayService($order['order_source']);
  179. $result = $pay->refund([
  180. 'transaction_id' => $order['transaction_id'],
  181. 'refund_sn' => $refund['sn'],
  182. 'total_fee' => $refund['order_amount'],
  183. 'refund_fee' => $refund['refund_amount'],
  184. ]);
  185. if ($result !== true) {
  186. throw new \Exception($pay->realPay()->getMessage());
  187. }
  188. //更新退款日志记录
  189. IntegralOrderRefund::where(['id' => $refund['id']])->update([
  190. 'wechat_refund_id' => 0,
  191. 'refund_msg' => json_encode([], JSON_UNESCAPED_UNICODE),
  192. ]);
  193. }
  194. /**
  195. * @notes 支付宝退款
  196. * @param $order
  197. * @param $refund
  198. * @throws Exception
  199. * @author 段誉
  200. * @date 2022/4/1 11:00
  201. */
  202. public static function aliPayRefund($order, $refund)
  203. {
  204. $result = (new AliPayService())->refund($order['sn'], $refund['refund_amount'], $refund['sn']);
  205. $result = (array)$result;
  206. if ($result['code'] == '10000' && $result['msg'] == 'Success' && $result['fundChange'] == 'Y') {
  207. //更新退款日志记录
  208. IntegralOrderRefund::where(['id' => $refund])->update([
  209. 'refund_msg' => json_encode($result['httpBody'], JSON_UNESCAPED_UNICODE),
  210. ]);
  211. } else {
  212. throw new Exception('支付宝退款失败');
  213. }
  214. }
  215. /**
  216. * @notes 余额退款
  217. * @param $order
  218. * @author 段誉
  219. * @date 2022/4/1 11:01
  220. */
  221. public static function balancePayRefund($order, $refund)
  222. {
  223. BalancePayService::integralOrderRefund($order, $refund['refund_amount']);
  224. }
  225. }