PaySuccess.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 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\api\service\order;
  13. use app\api\model\card\UserRiceCard as UserRiceCardModel;
  14. use app\api\model\card\UserRiceCardConsume as UserRiceCardConsumeModel;
  15. use app\api\model\member\GoldRice as GoldRiceModel;
  16. use app\common\enum\user\AccumulatePointsScene;
  17. use app\common\service\BaseService;
  18. use app\api\model\User as UserModel;
  19. use app\api\model\Order as OrderModel;
  20. use app\api\model\user\BalanceLog as BalanceLogModel;
  21. use app\common\service\commission\RecordWaitCommission;
  22. use app\common\service\goods\source\Factory as StockFactory;
  23. use app\common\enum\OrderType as OrderTypeEnum;
  24. use app\common\enum\order\PayType as OrderPayTypeEnum;
  25. use app\common\enum\user\balanceLog\Scene as SceneEnum;
  26. use app\common\enum\order\OrderSource as OrderSourceEnum;
  27. use think\facade\Event;
  28. /**
  29. * 订单支付成功服务类
  30. * Class PaySuccess
  31. * @package app\api\service\order
  32. */
  33. class PaySuccess extends BaseService
  34. {
  35. // 订单模型
  36. public $model;
  37. // 当前用户信息
  38. private $user;
  39. /**
  40. * 构造函数
  41. * PaySuccess constructor.
  42. * @param $orderNo
  43. */
  44. public function __construct($orderNo)
  45. {
  46. parent::__construct();
  47. // 实例化订单模型
  48. $this->model = OrderModel::getPayDetail($orderNo);
  49. // 获取用户信息
  50. $this->user = UserModel::detail($this->model['user_id']);
  51. }
  52. /**
  53. * 获取订单详情
  54. * @return OrderModel|null
  55. */
  56. public function getOrderInfo()
  57. {
  58. return $this->model;
  59. }
  60. /**
  61. * 订单支付成功业务处理
  62. * @param $payType
  63. * @param array $payData
  64. * @return bool
  65. */
  66. public function onPaySuccess($payType, $payData = [])
  67. {
  68. if (empty($this->model)) {
  69. $this->error = '未找到该订单信息';
  70. return false;
  71. }
  72. // 更新付款状态
  73. $status = $this->updatePayStatus($payType, $payData);
  74. // 订单支付成功事件
  75. if ($status == true) {
  76. Event::trigger('OrderPaySuccess', ['order' => $this->model, 'orderType' => OrderTypeEnum::ORDER]);
  77. }
  78. return $status;
  79. }
  80. /**
  81. * 更新付款状态
  82. * @param $payType
  83. * @param array $payData
  84. * @return bool
  85. */
  86. private function updatePayStatus($payType, $payData = [])
  87. {
  88. // 验证余额支付时用户余额是否满足
  89. if ($payType == OrderPayTypeEnum::BALANCE) {
  90. if ($this->user['balance'] < $this->model['pay_price']) {
  91. $this->error = '用户余额不足,无法使用余额支付';
  92. return false;
  93. }
  94. }
  95. //积分不足 todo 补充积分兑换商品比例
  96. if ($payType == OrderPayTypeEnum::EXCHANGE) {
  97. if ($this->user['accumulate_points'] < $this->model['total_price']) {
  98. $this->error = '用户积分不足,无法兑换成功';
  99. return false;
  100. }
  101. $this->model->transaction(function () use ($payType, $payData) {
  102. // 更新订单状态
  103. $this->updateOrderInfo($payType, $payData);
  104. //扣除用户积分 todo 确定积分兑换商品金额比例
  105. $points = bcmul($this->model['total_price'],"100",0);
  106. UserModel::setDecAccumulatePoints($this->user['user_id'], $points,AccumulatePointsScene::CONSUME,'兑换商品');
  107. // 记录订单支付信息
  108. $this->updatePayInfo($payType);
  109. });
  110. return true;
  111. }
  112. // 事务处理
  113. $this->model->transaction(function () use ($payType, $payData) {
  114. // 更新订单状态
  115. $this->updateOrderInfo($payType, $payData);
  116. // 累积用户总消费金额
  117. UserModel::setIncPayMoney($this->user['user_id'], (float)$this->model['pay_price']);
  118. //累积VIP用户积分
  119. UserModel::setIncGrowthValue($this->user,$this->model['rice_card_money']+$this->model['pay_price']);
  120. //累计用户积分
  121. UserModel::setIncAccumulatePoints($this->user['user_id'], $this->model['pay_price']);
  122. // 记录订单支付信息
  123. $this->updatePayInfo($payType);
  124. // 如果是普通订单,写入分销记录(积分兑换商品订单无分佣)
  125. if($this->model['order_source']!=OrderSourceEnum::BARGAIN || $this->model['or'] != OrderSourceEnum::EXCHANGE){
  126. $this->writeCommission($payType);
  127. }
  128. //写入金米粒记录
  129. $this->writeUserGoldRice();
  130. //写入米卡记录
  131. $this->writeUserRiceCard($payType, $payData);
  132. });
  133. return true;
  134. }
  135. /**
  136. * 更新订单记录
  137. * @param int $payType
  138. * @param array $payData
  139. * @return false|int
  140. * @throws \Exception
  141. */
  142. private function updateOrderInfo(int $payType, array $payData)
  143. {
  144. log_record($this->model['order_id']);
  145. log_record($payData);
  146. log_record($payType);
  147. // 更新商品库存、销量
  148. StockFactory::getFactory($this->model['order_source'])->updateStockSales($this->model);
  149. //秒杀订单还要处理正常订单的销量
  150. if($this->model['order_source']==OrderSourceEnum::MIAOSHA){
  151. StockFactory::getFactory(OrderSourceEnum::MASTER)->updateStockSales($this->model);
  152. }
  153. // 整理订单信息
  154. $order = [
  155. 'pay_type' => $payType,
  156. 'pay_status' => 20,
  157. 'pay_time' => time(),
  158. 'invoice_deadline' => time() + OrderModel::getInvoiceDeadline() * 60 // 申请开票截止时间:订单付款后的40天内可以申请开票
  159. ];
  160. if ($payType == OrderPayTypeEnum::WECHAT) {
  161. $order['transaction_id'] = $payData['transaction_id'];
  162. }
  163. // 更新订单状态
  164. return $this->model->save($order);
  165. }
  166. /**
  167. * 记录订单支付信息
  168. * @param int $payType
  169. */
  170. private function updatePayInfo(int $payType)
  171. {
  172. // 余额支付
  173. if ($payType == OrderPayTypeEnum::BALANCE) {
  174. // 更新用户余额
  175. UserModel::setDecBalance((int)$this->user['user_id'], (float)$this->model['pay_price']);
  176. // 新增余额变动记录
  177. BalanceLogModel::add(SceneEnum::CONSUME, [
  178. 'user_id' => (int)$this->user['user_id'],
  179. 'money' => -$this->model['pay_price'],
  180. ], ['order_no' => $this->model['order_no']]);
  181. }
  182. // 微信支付
  183. if ($payType == OrderPayTypeEnum::WECHAT) {
  184. }
  185. }
  186. /**
  187. * 写入分销记录
  188. * @param int $payType
  189. * @return false|int
  190. * @throws \Exception
  191. */
  192. private function writeCommission(int $payType)
  193. {
  194. // 余额支付 或 微信支付
  195. if ($payType == OrderPayTypeEnum::BALANCE || $payType == OrderPayTypeEnum::WECHAT) {
  196. //待结算佣金计算
  197. $RecordWaitCommission = new RecordWaitCommission;
  198. //分销记录放入队列
  199. $RecordWaitCommission->recordWaitCommission($this->model['order_id']);
  200. }
  201. // 米卡兑换
  202. if ($payType == OrderPayTypeEnum::MICAH_EXCHANGE) {
  203. }
  204. }
  205. /**
  206. * 写入金米粒记录
  207. * @param int $payType
  208. * @return false|int
  209. * @throws \Exception
  210. */
  211. private function writeUserGoldRice()
  212. {
  213. if($this->model['gold_rice_amount']>0){
  214. //写金米粒出账记录
  215. GoldRiceModel::add($this->model['user_id'],$this->model['order_no'],'下单抵扣',$this->model['gold_rice_amount'],0);
  216. //扣除冻结中的金米粒
  217. UserModel::setDecByField($this->user['user_id'],'gold_rice_frozen',(float)$this->model['gold_rice_amount']);
  218. }
  219. if($this->model['gold_rice_amount_input']>0){
  220. //写金米粒入账记录
  221. GoldRiceModel::add($this->model['user_id'],$this->model['order_no'],'会员购物返金米粒',$this->model['gold_rice_amount_input'],1);
  222. //用户直接添加在途金米粒
  223. UserModel::setIncByField($this->user['user_id'],'gold_rice_road',(float)$this->model['gold_rice_amount_input']);
  224. }
  225. }
  226. /**
  227. * 写入米卡记录
  228. * @param int $payType
  229. * @return false|int
  230. * @throws \Exception
  231. */
  232. private function writeUserRiceCard(int $payType,array $payData)
  233. {
  234. // 余额支付 或 微信支付
  235. // if ($payType == OrderPayTypeEnum::BALANCE || $payType == OrderPayTypeEnum::WECHAT) {
  236. //现金卡的操作
  237. if($this->model['rice_card_id']>0){
  238. //写现金卡出账记录
  239. $userRiceCard = UserRiceCardModel::find($this->model['rice_card_id']);
  240. UserRiceCardConsumeModel::add($userRiceCard,$this->model['order_no'],$this->model['pay_price'],$this->model['rice_card_money']);
  241. //如果可用余额为0并且冻结余额等于要抵扣的金额
  242. if($this->model['userRiceCard']['balance']==0 && $this->model['rice_card_money']==$this->model['userRiceCard']['frozen_amount']){
  243. //现金卡直接减冻结余额,并且状态改为已失效
  244. UserRiceCardModel::setIncDecByField($this->model['rice_card_id'],[],['frozen_amount'=>(float)$this->model['rice_card_money']],['effect_state'=>2]);
  245. }else{
  246. //现金卡直接减冻结余额
  247. UserRiceCardModel::setDecByField($this->model['rice_card_id'],'frozen_amount',(float)$this->model['rice_card_money']);
  248. }
  249. }
  250. // }
  251. // // 米卡兑换
  252. // if ($payType == OrderPayTypeEnum::MICAH_EXCHANGE) {
  253. //
  254. // }
  255. }
  256. }