validationFactory->make( $this->request->all(), [ 'user_id' => 'required|nonempty|integer', 'store_id' => 'required|nonempty|integer', ], ['*.*' => ':attribute 参数不正确'] ); if ($validator->fails()) { throw new ValidationException($validator); } $userId = $this->request->input('user_id'); $storeId = $this->request->input('store_id'); $store = Store::query()->where(['user_id' => $userId, 'id' => $storeId])->first(); if (empty($store)) { throw new ErrorCodeException(ErrorCode::STORE_NOT_AVAILABLE); } $data['balance'] = UserBalance::query() ->where(['source_id' => $store->user_id, 'user_type' => UserType::STORE]) ->value('balance'); $data['award'] = $this->financialService->sumAmount( $store->user_id, UserType::STORE, [FinancialRecord::MONEY_TYPE_STORE_PLAT_NEW_USER, FinancialRecord::MONEY_TYPE_STORE_FIRST_ORDER] ); $data['notice'] = [ [ 'title' => '用户须知', 'content' => '
请仔细填写相关信息,如果由于您填写的信息有误导致资金流失,平台概不负责。
注意:因微信限制当前用户账户余额满1元后才可提现
' ], [ 'title' => '提现须知', 'content' => '一次提现金额最低为1元
' .'一次提现金额最高为5000元
' .'每天可提现10次
' ], ]; return $this->success($data); } /** * 商户提现申请 * 1、商户提现参数校验 * 2、商户提现是否超过可提现金额 * 3、提现是否秒到账,秒到账则打款并且做流水,否则就打到后台审核 */ public function applyByStore() { $isDirect = config('wechat.withdrawal.is_direct'); $min = config('wechat.withdrawal.min_amount'); $max = config('wechat.withdrawal.max_amount'); $validator = $this->validationFactory->make( $this->request->all(), [ 'user_id' => 'required|nonempty|integer', 'store_id' => 'required|nonempty|integer', 'money' => "required|nonempty|numeric|between:{$min}, {$max}", ] ); if ($validator->fails()) { throw new ValidationException($validator); } $money = $this->request->input('money'); $userId = $this->request->input('user_id'); $storeId = $this->request->input('store_id'); $store = Store::query()->where(['user_id' => $userId, 'id' => $storeId])->first(); if (empty($store)) { throw new ErrorCodeException(ErrorCode::STORE_NOT_AVAILABLE); } // 校验余额 $balance = UserBalance::query() ->where(['source_id' => $store->user_id, 'user_type' => UserType::STORE]) ->first(); if ($money > $balance->balance) { throw new ErrorCodeException(ErrorCode::STORE_WITHDRAW_INSUFFICIENT_BALANCE); } Db::beginTransaction(); try { $storeUser = User::query()->find($store->user_id); $currentTime = time(); // 获取分布式全局ID $generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class); $globalOrderId = $generator->generate(); // 记录提现申请记录 $withdraw = new StoreWithdrawal(); $withdraw->trade_no = $globalOrderId; $withdraw->store_id = $store->id; $withdraw->name = $storeUser->real_name ?? $storeUser->nick_name; $withdraw->tel = $storeUser->tel; $withdraw->apply_cash = $money; $withdraw->save(); // 先扣除余额 $balance->balance = bcsub($balance->balance, $money, 2); $balance->save(); // 如果秒到账无需审核的话 if ($isDirect) { // 打款 $res = $this->paymentService->payToWx( bcmul($withdraw->apply_cash, 100 , 0), $withdraw->trade_no, $storeUser->openid, $withdraw->name, '商户提现打款' ); // 更新打款金额,审核时间等 $withdraw->check_time = time(); $withdraw->real_cash = $money; $withdraw->state = 2; $withdraw->save(); // 打款成功,写流水 if ($res === true) { $this->financialService->storeWithdrawByWx($store->user_id, 0, $withdraw->real_cash); } } Db::commit(); return $this->success([]); } catch (\Exception $e) { Db::rollBack(); $this->log->event(LogLabel::STORE_WITHDRAW_FAIL_LOG, [ 'exception' => $e->getMessage(), 'withdraw' => json_encode($withdraw), 'params' => json_encode(['balance' => $balance->balance, 'user_id' => $userId, 'store_id' => $storeId]), ]); throw new ErrorCodeException(ErrorCode::STORE_WITHDRAW_FAIL, $e->getMessage()); } } }