find(); // $user = User::where("id",$user_id)->find(); // if($user['user_money'] < $result['order_amount']){ // throw new \Exception('余额不足'); // } // $user->dec('user_money', $result['order_amount']); // $user->save(); // $order_data['order_status'] = 1; // $order_data['pay_status'] = 1; // $order_data['update_dtime'] = date("Y-m-d H:i:s"); // Order::where("id",$result['order_id'])->update($order_data); // $d['order_sn'] = createSn('pay','order_sn'); // $d['create_time'] = date("Y-m-d H:i:s"); // $d['pay_time'] = date("Y-m-d H:i:s"); // $result = Pay::where("id",$data['id'])->update($d); // return $result; // } public static function yuePay($data, $user_id) { Db::startTrans(); try { $payId = $data['id']; $currentTime = date("Y-m-d H:i:s"); // 1. 查询支付记录(悲观锁) $pay = Pay::where("id", $payId)->lock(true)->find(); if (!$pay) { throw new \Exception('支付记录不存在'); } // 支付记录状态检查 if ($pay['pay_status'] == 1) { throw new \Exception('该支付记录已完成支付'); } // 2. 查询关联订单 if($pay['order_type'] == 1){ $order = OrderStore::where("id", $pay['order_id'])->find(); }elseif($pay['order_type'] == 2){ $order = OrderGroup::where("id", $pay['order_id'])->find(); }elseif($pay['order_type'] == 7){ $order = OrderStoreRenew::where("id", $pay['order_id'])->find(); } if (!$order) { throw new \Exception('关联订单不存在'); } // 3. 查询用户并检查余额(悲观锁) $user = User::where("id", $user_id)->lock(true)->find(); if (!$user) { throw new \Exception('用户不存在'); } // 金额处理:保持数值类型用于计算,字符串类型用于显示 $amount = (float)$pay['order_amount']; // 区分门店余额支付还是平台余额 if($data['pay_way'] == 3){ $user_store_money = UserStoreMoney::where("user_id",$user_id)->where("store_id",$data['store_id'])->find(); $userMoney = (float)$user_store_money['money']; }else{ $userMoney = (float)$user['user_money']; } // 用于显示的格式化金额 $displayAmount = number_format($amount, 2); $displayUserMoney = number_format($userMoney, 2); if ($userMoney < $amount) { throw new \Exception("余额不足,当前余额: {$displayUserMoney},需支付: {$displayAmount}"); } // 4. 扣减用户余额(使用数值类型的 $amount) // $userSave = User::where("id", $user_id)->setDec('user_money', $amount); $newBalance = round($userMoney - $amount, 2); if($data['pay_way'] == 3){ $userSave = UserStoreMoney::where("user_id", $user_id)->where("store_id",$data['store_id'])->update(['money' => $newBalance,"update_dtime"=>date("Y-m-d H:i:s")]); }else{ $userSave = User::where("id", $user_id)->update(['user_money' => $newBalance,"update_time"=>time()]); } if (!$userSave) { throw new \Exception('用户余额扣减失败'); } $change_type = 0; $sub_sn = 0; // 5. 更新订单状态 if($pay['order_type'] == 1) { $change_type = 1; $type = 3; // 修改优惠券使用状态 if($order['group_coupon_id']>=0){ UserGroup::where("id", $order['group_coupon_id'])->update(["status"=>1]); } if($order['user_coupon_id']>=0){ UserCoupon::where('id',$order['user_coupon_id'])->update(["status"=>1]); } $amount = $order['order_amount']; $orderUpdate = OrderStore::where("id", $pay['order_id'])->update([ 'order_status' => 1, 'pay_status' => 1, 'update_dtime' => $currentTime ]); if(isset($order['room_id'])){ if($order['room_id']!=0&&$order['room_id']!=""&&$order['room_id']!=null){ TeaStoreRoom::where('id', $order['room_id'])->inc('sold', 1)->update(); } } if (!$orderUpdate) { throw new \Exception('订单状态更新失败'); } }elseif($pay['order_type'] == 2){ $change_type = 4; $type = 6; $orderUpdate = OrderGroup::where("id", $pay['order_id'])->update([ 'order_status' => 1, 'pay_status' => 1, 'update_dtime' => $currentTime ]); if (!$orderUpdate) { throw new \Exception('订单状态更新失败'); } $qr_sn = createSn("user_group","qr_sn"); $qr_url = CommonLogic::qrcode($qr_sn); $group = TeaStoreGroup::where('id', $order['group_id'])->find(); UserGroup::create([ "user_id"=>$user_id, "group_id"=>$order['group_id'], "qr_sn"=>$qr_sn, "qr_url"=>$qr_url['file_url'], "type"=>$group['type'], "order_id"=>$order['id'], "store_id"=>$order['store_id'], "dtime"=>date("Y-m-d H:i:s") ]); if(isset($order['group_id'])){ if($order['group_id']!=0&&$order['group_id']!=""&&$order['group_id']!=null){ TeaStoreGroup::where('id', $order['group_id'])->inc('sold', 1)->update(); } } }elseif($pay['order_type'] == 7){ $renew_order = OrderStoreRenew::where('id',$pay['order_id'])->find(); if(!$renew_order){ throw new \Exception('付款失败,订单不存在'); } $source_id = $renew_order->source_id; $store_order = OrderStore::where('id',$source_id)->find(); if(!$store_order){ throw new \Exception('包间订单错误,订单不存在'); } $renew_timeslot = explode(',', $renew_order->timeslot); $store_timeslot = explode(',', $store_order->timeslot); $timeList = array_merge($store_timeslot, $renew_timeslot); $end = end($timeList); $renew_price = $renew_order->price; $renew_order->pay_status = 1; $renew_order->pay_dtime = 1; $renew_order->save(); $transfer_order = OrderStore::where('transfer_order_id',$store_order['id'])->select(); $ids = explode(',',$store_order->id); if($transfer_order->count() > 0){ $orderIds = $transfer_order->column('id'); $ids = array_merge($ids,$orderIds); } OrderStore::whereIn("id",$ids)->update([ "end_time"=>$end, 'timeslot'=>implode(',', $timeList), 'renew_dtime'=>implode(',', $timeList), 'is_renewal'=>1, 'renew_price'=>$renew_order->price+$store_order->renew_price, 'renew_hour'=>$renew_order->hour + $store_order->renew_hour, 'store_income_price'=>$store_order->store_income_price+$renew_price ]); $change_type = 2; $type = 7; $sub_sn =$renew_order->order_sn; $order['order_sn'] =$store_order->order_sn; $order['store_id'] =$store_order->store_id; $order['room_id'] =$store_order->room_id; $amount = $renew_order->price; } OrderAll::where("source_sn", $order['order_sn'])->where("type", $type)->update([ 'order_status' => 1, 'pay_status' => 1, 'pay_way'=>$order['pay_way'], 'update_time' => time() ]); // 6. 更新支付记录 $payUpdate = Pay::where("id", $payId)->update([ 'order_sn' => createSn('pay', 'order_sn'), 'pay_status' => 1, 'pay_time' => $currentTime ]); if (!$payUpdate) { throw new \Exception('支付记录更新失败'); } // 7. 记录资金流水(使用数值类型的金额) $moneyLog = self::addUserAccountLog( $user_id, $change_type, $amount, $userMoney, $newBalance, $order ); $change_object = 1; if($data['pay_way'] == 3){ $amount = 0; $change_object = 3; } if($pay['order_type'] != 2){ // 记录店家资金流水(使用数值类型的金额) self::addStoreUserAccountLog( $data['pay_way'], $pay['order_type'], $user_id, $change_object, $change_type, $amount, $order, $sub_sn ); } // 8. 记录支付日志 self::addPayLog($payId, $user_id, $amount, 'success'); Db::commit(); // 9. 支付成功后的后续操作(可异步处理) self::afterPaySuccess($pay['order_id'], $user_id); return [ 'success' => true, 'pay_id' => $payId, 'order_id' => $pay['order_id'], 'order_sn' => $order['order_sn'], 'amount' => $displayAmount, // 返回格式化后的金额用于显示 'balance' => number_format($userMoney - $amount, 2) // 格式化余额 ]; } catch (\Exception $e) { Db::rollback(); // 记录支付失败日志 if (isset($payId)) { self::addPayLog($payId, $user_id, $amount ?? 0, 'fail', $e->getMessage()); } self::$error = $e->getMessage(); return false; } } private static function addUserAccountLog($user_id,$change_type, $amount,$userMoney, $newBalance,$order) { return Db::name('user_account_log')->insert([ 'sn'=>createSn("user_account_log","sn"), 'user_id' => $user_id, 'change_object'=>1, 'change_type'=>$change_type, 'action'=>2, 'amount' => $amount, 'before_amount'=>$userMoney, 'after_amount' => $newBalance, 'source_sn' => $order['order_sn'], 'store_id'=>$order['store_id'], 'create_time' => time() ]); } private static function addStoreUserAccountLog($pay_way,$order_type,$user_id,$change_object,$change_type, $amount,$order,$sub_sn) { $tea_store = TeaStore::where("id",$order['store_id'])->find(); // if($amount != 0){ StoreUserAccountLog::create([ 'sn'=>createSn("store_user_account_log","sn"), 'change_object'=>$change_object, 'change_type'=>$change_type, 'user_id'=>$user_id, 'action'=>1, 'amount' => $amount, 'before_amount'=>$tea_store['balance'], 'after_amount' => round($amount+$tea_store['balance'],2), 'source_sn' => $order['order_sn'], 'store_id'=>$order['store_id'], 'sub_sn'=>$sub_sn, 'room_id'=>$order['room_id'], 'create_time' => time() ]); // if($order_type == 7 ){ // TeaStore::where('id', $order['store_id'])->inc('total_amount', $amount)->update(); // TeaStore::where('id', $order['store_id'])->inc('balance', $amount)->update(); // } if($pay_way != 3){ TeaStore::where('id', $order['store_id'])->inc('total_amount',$amount)->update(); TeaStore::where('id', $order['store_id'])->inc('balance', $amount)->update(); } // } if($order['group_coupon_id'] != 0&&$order_type == 1){ $group = UserGroup::where("id",$order['group_coupon_id'])->find(); $store_group = TeaStoreGroup::where("id",$group['group_id'])->find(); $change_object = 4; if($group['type'] == 2){ $store_group['discount_price'] = 0; $change_object = 5; $amount = 0; } StoreUserAccountLog::create([ 'sn'=>createSn("store_user_account_log","sn"), 'change_object'=>$change_object, 'change_type'=>1, 'user_id'=>$user_id, 'action'=>1, 'amount' => $store_group['discount_price'], 'before_amount'=>round($tea_store['balance']+$amount,2), 'after_amount' => round($tea_store['balance']+$amount+$store_group['discount_price'],2), 'source_sn' => $order['order_sn'], 'store_id'=>$order['store_id'], 'room_id'=>$order['room_id'], 'remark'=>"团购套餐", 'create_time' => time() ]); TeaStore::where('id', $order['store_id'])->inc('total_amount', $store_group['discount_price'])->update(); TeaStore::where('id', $order['store_id'])->inc('balance', $store_group['discount_price'])->update(); } return true; } /** * 记录支付日志 */ private static function addPayLog($pay_id, $user_id, $amount, $status, $message = '') { return Db::name('pay_log')->insert([ 'pay_id' => $pay_id, 'user_id' => $user_id, 'amount' => $amount, 'status' => $status, 'message' => $message, 'create_time' => time() ]); } // 退款 public static function refund($data, $user_id){ $refund_msg = RefundRecord::where("id",$data['id'])->find(); $remark = ""; $change_type = 0; // 判断是否为微信支付 // 0为茶艺师 1为茶室支付 2购买套餐 3购买会员 4充值 5团购退款 6茶室退款 if($refund_msg['order_type'] == 5){ $order = OrderGroup::where("order_sn",$refund_msg['source_sn'])->find(); $remark = "团购套餐退款"; $order_amount = $order['order_amount']; }elseif($refund_msg['order_type'] == 1){ $order = OrderStore::where("order_sn",$refund_msg['source_sn'])->find(); $remark = "包间预定退款"; $order_amount = $order['store_income_price']; $change_type = 1; } if(isset($order)){ // 微信支付 if($order['pay_way'] == 2){ if($order['order_amount'] <= 0){ //查询是否使用优惠券 if($order['user_coupon_id'] != 0){ $r = UserCoupon::where("id",$order['user_coupon_id'])->update(['status'=>0]); } //查询是否使用团购券 if($order['group_coupon_id'] != 0){ $r = UserGroup::where("id",$order['user_coupon_id'])->update(['status'=>0]); } if(!isset($r)){ throw new \Exception('退款失败100001'); } }else{ if($refund_msg['order_type'] == 5){ UserGroup::where('order_id',$order['id'])->update(['status'=>4]); } $refundData = [ 'transaction_id'=>$order->transaction_id, 'refund_sn'=>$refund_msg->order_sn, 'total_amount'=>$order->order_amount, 'notify_url'=>FileService::getFileUrl('api/pay/notifyMnp'), ]; $payService = (new WeChatPayService(1, $user_id ?? null)); $result = $payService->refund($refundData); if($result['status'] !=='PROCESSING'){ throw new \Exception('押金退款失败请联系客服'); } return true; } }else{ // 余额退款 RefundRecord::where("id",$data['id'])->update(['refund_way'=>3,'refund_status'=>1]); // 更新总表状态 OrderAll::where("source_sn",$refund_msg['order_sn'])->where("type",$refund_msg['order_type'])->update([ "pay_way"=>$order['pay_way'], "order_status"=>5, "pay_status"=>1, "pay_time"=>time(), "update_time"=>time() ]); $user = User::where("id",$user_id)->find(); $money = 0; $user_money = 0; if($order['pay_way'] == 1){ // 平台余额 $money = $user['user_money']; $user_money = round($user['user_money']+$refund_msg['refund_amount'],2); User::where("id",$user_id)->update(['user_money'=>$user_money]); }else{ // 门店余额 $user_store_money = UserStoreMoney::where("user_id",$user_id)->where("store_id",$order['store_id'])->find(); $money = $user_store_money['money']; $user_money = round($user_store_money['money']+$refund_msg['refund_amount'],2); UserStoreMoney::where("user_id",$user_id)->where("store_id",$order['store_id'])->update(['money'=>$user_money]); } // 更新用户流水 UserAccountLog::create([ "sn"=>createSn("user_account_log","sn"), "user_id"=>$user_id, "change_object"=>1, "change_type"=>5, "action"=>1, "amount"=>$refund_msg['refund_amount'], "before_amount"=>$money, "after_amount"=>$user_money, "source_sn"=>$refund_msg['order_sn'], "store_id"=>$refund_msg['store_id'], "remark"=>$remark, "create_time"=>time() ]); } // 修改订单状态 if($refund_msg['order_type'] == 5){ $rs = OrderGroup::where("order_sn",$refund_msg['source_sn'])->update(['order_status'=>5]); UserGroup::where("id",$refund_msg['content_id'])->update(['status'=>3]); }elseif($refund_msg['order_type'] == 1){ $rs = OrderStore::where("order_sn",$refund_msg['source_sn'])->update(['order_status'=>5]); } if(isset($rs)){ if(!$rs){ throw new \Exception('退款失败100002'); } }else{ throw new \Exception('退款失败100003'); } // if($refund_msg['order_type'] == 5){ // // 扣除店家余额 // $tes_store = TeaStore::where('id', $order['store_id'])->find(); // $total_amount = round($tes_store['total_amount'] - $order_amount,2); // $balance = round($tes_store['balance'] - $order_amount,2); // TeaStore::where('id', $order['store_id'])->update(['total_amount'=>$total_amount,'balance'=>$balance]); // // 添加店家流水 // StoreUserAccountLog::create([ // 'order_sn'=>createSn("store_user_account_log","order_sn"), // 'change_object'=>1, // 'change_type'=>$change_type, // 'action'=>2, // 'amount' => $order_amount, // 'before_amount'=>$tes_store['balance'], // 'after_amount' => $balance, // 'source_sn' => $order['order_sn'], // 'store_id'=>$order['store_id'], // 'room_id'=>$order['room_id'], // 'remark'=>$remark, // 'create_time' => time() // ]); // } return true; }else{ throw new \Exception('暂无订单信息'); } } /** * 支付成功后置操作 */ private static function afterPaySuccess($order_id, $user_id) { // 可以在这里处理: // 1. 发送通知 // 2. 更新库存 // 3. 记录日志 // 4. 触发其他业务逻辑 // 示例:发送支付成功通知 // NoticeService::sendPaySuccessNotice($user_id, $order_id); } }