mall_id; $params['user_id'] = $this->user_id; try { $res = UserWithdrawLog::withdrawCheck($params); if (!empty($res) && $res['state'] == true) { return $res['data']; } $res = $this->saveRecord($params); return $res; } catch (\Exception $e) { throw new \Exception($e->getMessage()); } } public function saveRecord($params, $extra = []) { $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic'); if (empty($configs['payment_withdraw'])) { throw new \Exception('暂未开启货款提现功能'); } if ($params['price'] <= 0) { throw new \Exception('提现金额必须大于0'); } $exists = UserWithdrawLog::find()->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::DISABLED, 'user_id' => $params['user_id'], 'from' => UserWithdrawLog::FROM_PAYMENT_FOR_GOODS ])->asArray()->one(); if ($exists) { throw new \Exception('尚有未审核的提现申请'); } $cloud_stock_agent = CloudStockAgent::getOne([['user_id' => $this->user_id, 'status' => 1]], true, [], false, 'cloud_warehouse_price'); if ($cloud_stock_agent['cloud_warehouse_price'] < $params['price']) { throw new \Exception('提现金额超出可提现金额'); } $withdraw_cash_type = json_decode($configs['withdraw_cash_type'], true); if (!in_array($params['type'], $withdraw_cash_type)) { throw new \Exception('不支持该提现方式'); } $poundage_ratio = isset($configs['payment_withdraw_poundage']) && $configs['payment_withdraw_poundage'] > 0 ? $configs['payment_withdraw_poundage'] : 0; $cash = new UserWithdrawLog(); $cash->mall_id = $params['mall_id']; $cash->user_id = $params['user_id']; $cash->num = $params['price']; $cash->source = 'CloudStock'; $cash->actual_num = $params['price']; $cash->content = Json::encode(['user_content' => $params['content']]); $cash->from = UserWithdrawLog::FROM_PAYMENT_FOR_GOODS; $cash->type = $params['type']; $cash->extra = Json::encode([ 'name' => !empty($params['name']) ? $params['name'] : '', 'mobile' => !empty($params['mobile']) ? $params['mobile'] : '', 'bank_name' => $params['bank_name'], 'bank_account' => (string)$params['bank_account'], 'bank_account_type' => $params['bank_account_type'], 'wechat_qrcode' => $params['wechat_qrcode'], 'id_card' => $params['id_card'] ?? '', 'receive_bank_chanel_no' => $params['receive_bank_chanel_no'] ?? '', 'x-app-platform' => $params['x-app-platform'] ?? '', 'bank_address' => !empty($params['bank_address']) ? $params['bank_address'] : '', 'idcard' => !empty($params['idcard']) ? $params['idcard'] : '', ], JSON_UNESCAPED_UNICODE); if ($poundage_ratio < 0 || $poundage_ratio > 100) { throw new \Exception('手续费设置不正确'); } //手续费 $poundage = 0; if ($poundage_ratio > 0 && $poundage_ratio < 100) { //手续费:取小数点2位,截断 $poundage = bcmul($poundage_ratio / 100, $params['price'], 4); // 四舍五入,保留2位 $poundage = number_format($poundage, 2, '.', ''); $cash->actual_num = bcsub($params['price'], $poundage, 2); $cash->poundage_num = $poundage; $cash->poundage_ratio = $poundage_ratio; } if (intval(bcmul($cash->actual_num, 100)) < 1) { throw new \Exception('提现金额扣除费用后金额不足'); } $t = \Yii::$app->db->beginTransaction(); try { $cash->order_no = $cash->getCashOrder($params['mall_id']); if (!$cash->save()) { throw new \Exception($cash->getErrorMessage()); } $res_data = [ 'state' => true, 'data' => ['cash_id' => $cash->id], 'msg' => '' ]; $data = [ 'mall_id' => $params['mall_id'], 'user_id' => $params['user_id'], 'money' => -abs($cash->num), ]; self::handle($data); $t->commit(); } catch (Exception $e) { $t->rollBack(); \Yii::error($e->getMessage()); throw new \Exception('提现失败!' . $e->getMessage() . $e->getFile() . $e->getLine()); } return $res_data; } public static function handle($data) { $user_id = $data['user_id']; $lock_key = RedisKeyEnum::suffix(self::LOCK_CLOUD_STOCK_AGENT, $user_id); $identification = uniqid(); if (LockHelper::lock($lock_key, $identification, 100, 100)) { $t = \Yii::$app->db->beginTransaction(); try { $cloud_stock_agent = CloudStockAgent::getOne([['user_id' => $user_id, 'status' => 1]], false, [], false); if(isset($data['is_frozen']) && $data['is_frozen']){ $cloud_stock_agent->cloud_warehouse_frozen_price += $data['money']; }else{ $cloud_stock_agent->cloud_warehouse_price += $data['money']; } if ($cloud_stock_agent->cloud_warehouse_price < 0) { throw new \Exception('云仓货款不足'); } $cloud_stock_agent->save(); $t->commit(); LockHelper::uLock($lock_key, $identification); return true; } catch (Exception $e) { $t->rollBack(); LockHelper::uLock($lock_key, $identification); self::$static_error = $e->getMessage(); return false; } } else { LockHelper::uLock($lock_key, $identification); //抢不到锁 Yii::error(__CLASS__ . ' handle error : 抢不到锁'); self::$static_error = '操作太频繁'; return false; } } /** * 获取提现信息 * @return array * @throws \Exception */ public function cashSetting() { $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic'); if (empty($configs['payment_withdraw'])) { throw new \Exception('暂未开启货款提现功能'); } $cloud_stock_agent = CloudStockAgent::getOne([['user_id' => $this->user_id, 'status' => 1]], true, [], false, 'cloud_warehouse_price'); $is_need_redirect = 0; $repurchase_redirect_url = ''; $repurchase_prompt = ''; $is_hidden_money_unit = 0; $userMoney = $cloud_stock_agent['cloud_warehouse_price']; $pay_password_status = 0; $cash__type_name = []; $withdraw_cash_type = $configs['withdraw_cash_type']; $get_system_setting = PlatformSetting::getConfByGroup('system', true); if (!empty($withdraw_cash_type)) { $cash_type = Json::decode($withdraw_cash_type); $default_withdraw_way = WithdrawWayEnum::getDefaultWithDrawWayMap(WithdrawWayEnum::WITHDRAW_TYPE_2); $extension_withdraw_way = GlobalInvoke::exec(GlobalInvoke::INVOKE_GET_WITHDRAW_EXTENSION_WAY, $this->mall_id, ['mall_id' => $this->mall_id]); $all_withdraw = array_merge($default_withdraw_way, $extension_withdraw_way); $cash_type_keys = array_keys($all_withdraw); if (in_array('bank', $cash_type_keys) || in_array('joinpay', $cash_type_keys)) { $bank_card_list = UserBankCard::getUserCardList($this->user_id, $this->mall_id); } foreach ($cash_type as $i => $item) { if (isset($all_withdraw[$item])) { $taxFee = 0; $name = ''; if (isset($all_withdraw[$item])) { if (is_array($all_withdraw[$item])) { $name = $all_withdraw[$item]['name'] ?? ''; $taxFee = $all_withdraw[$item]['taxFee'] ?? 0; } else { $name = $all_withdraw[$item]; } } $cash__type_name[$i]['type'] = $item; $cash__type_name[$i]['taxFee'] = $taxFee; $cash__type_name[$i]['name'] = $name; $cash__type_name[$i]['img'] = $get_system_setting['api_url']['value'] . '/resources/img/payment/' . $item . '.png'; if ('bank' == $item || 'joinpay' == $item || 'yunfast_pay' == $item) { $cash__type_name[$i]['bank_card_list'] = $bank_card_list; } } } } //检测是否需要实名认证 $need_auth = GlobalInvoke::exec(GlobalInvoke::REAL_AUTH, $this->mall_id, ['user_id' => $this->user_id, 'mall_id' => $this->mall_id, 'type' => 'cash']); if ($need_auth === true) { //需要先进行实名认证 return $this->error('请先进行实名认证', [], ApiStatusEnum::CODE_ERROR_NEED_REAL_AUTH); } $userWithdrawLog = UserWithdrawLog::getOne([ ['user_id' => $this->user_id], ['type' => ['alipay_tax', 'alipay']] ], true, [], 'id desc'); $aliAccountInfo = []; if (!empty($userWithdrawLog)) { $extra = json_decode($userWithdrawLog['extra'], true); if (!empty($extra)) { $aliAccountInfo = [ 'name' => $extra['name'], 'mobile' => $extra['mobile'], 'id_card' => $extra['id_card'] ?? '', ]; } } return [ 'addons_auth' => [], 'notice' => [ 'content' => '', 'icon' => '' ], 'setting' => [ 'cash_type_name' => $cash__type_name, 'cash_service_fee' => $configs['payment_withdraw_poundage'] ?? 0, 'cash_income_service_fee' => $configs['payment_withdraw_poundage'] ?? 0, 'min_money' => 0, 'day_max_money' => 0, 'withdrawal_rule' => '', 'pay_password_status' => intval($pay_password_status), 'multiple' => 0, 'withdraws_limit_enable' => 0, 'withdraws_limit_money' => 0, 'is_hidden_money_unit' => $is_hidden_money_unit, ], 'user_info' => [ 'income' => $userMoney, 'is_transaction_password' => false ], 'ali_account_info' => $aliAccountInfo, 'repurchase_limit' => [ 'is_need_redirect' => $is_need_redirect, 'repurchase_redirect_url' => $repurchase_redirect_url, 'repurchase_prompt' => $repurchase_prompt ] ]; } public function transferBalance($params) { $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic'); if (empty($configs['payment_to_balance'])) { throw new \Exception('暂未开启货款转余额功能'); } $payment_to_balance_poundage = $configs['payment_to_balance_poundage'] ?? 0; $user_id = $this->user_id; $money = $params['money']; $res = self::handle(['user_id' => $user_id, 'money' => -$money]); if ($res) { $poundage = bcdiv($money * $payment_to_balance_poundage, 100, 2); $desc = '云仓货款转余额,手续费:' . $poundage; $insert_wallet [] = [ 'mall_id' => $this->mall_id, 'user_id' => $user_id, 'is_frozen' => false, 'wallet_type' => UserWalletService::WALLET_TYPE_BALANCE, 'money' => bcsub($money, $poundage, 2), 'desc' => $desc, 'source_table' => '', 'source_table_id' => 0, 'from_type' => 'CloudStock', 'capital_type' => 'cloud_stock_payment_transfer', ]; UserWalletService::batchHandleByQueue($insert_wallet); }else{ throw new \Exception(self::$static_error); } return true; } }