WithDrawInfoController.php 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. <?php
  2. namespace App\Http\Controllers\Game;
  3. use App\Facade\TableName;
  4. use App\Game\GlobalUserInfo;
  5. use App\Http\helper\NumConfig;
  6. use App\Models\AccountsInfo;
  7. use App\Models\Treasure\GameScoreLocker;
  8. use App\Notification\TelegramBot;
  9. use App\Util;
  10. use App\Utility\SetNXLock;
  11. use GuzzleHttp\Client;
  12. use GuzzleHttp\Exception\RequestException;
  13. use Illuminate\Http\Request;
  14. use Illuminate\Support\Facades\DB;
  15. use Illuminate\Support\Facades\Hash;
  16. use Illuminate\Support\Facades\Log;
  17. use Illuminate\Support\Facades\Validator;
  18. class WithDrawInfoController
  19. {
  20. public function FreeWithDrawInfo(Request $request)
  21. {
  22. $user = $request->user();
  23. $userScoreData = GlobalUserInfo::getScoreDataByUserID($user->UserID);
  24. if(!$userScoreData['Recharge']){
  25. $totalWithdraw = max($userScoreData['InsureScore'],40);
  26. if($userScoreData['InsureScore']<40){
  27. //第一种状态,我免费领了10块钱,但是金额不足40,点进去页面填信息后点击提现,提示我去玩游戏
  28. return apiReturnSuc(['state' => 1, 'total' => $totalWithdraw,'InsureScore' => $userScoreData['InsureScore']]);
  29. }else{
  30. //第二种状态,我免费金额足够40,提现按钮会点亮,告知用户点击进去
  31. return apiReturnSuc(['state' => 2, 'total' => $totalWithdraw,'InsureScore' => $userScoreData['InsureScore']]);
  32. }
  33. }else{
  34. //第四种状态,VIP状态下,金额不足了,进度条颜色红色,按钮灰色(不可点击),次日整个消失
  35. if($userScoreData['InsureScore']<10){
  36. return apiReturnSuc(['state' => 4, 'total' => max($userScoreData['InsureScore'],40),'InsureScore' => max($userScoreData['InsureScore'],40)]);
  37. }else{
  38. //第三种状态,进去完成了充值未提现,提现按钮会高光,引导用户完成提现
  39. return apiReturnSuc(['state' => 3, 'total' => max($userScoreData['InsureScore'],40),'InsureScore' => max($userScoreData['InsureScore'],40)]);
  40. }
  41. }
  42. }
  43. public function WithDrawRecord(Request $request)
  44. {
  45. $user = $request->user();
  46. $UserID=$user->UserID;
  47. // $paypass = $request->input('paypass');
  48. // if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
  49. // return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  50. // }
  51. $scoreType = intval($request->input('score_type', -1));
  52. if (!in_array($scoreType, [-1, 0, 1], true)) {
  53. return apiReturnFail(['web.withdraw.params_error', 'score_type must be -1, 0 or 1'], [], 422);
  54. }
  55. $sort = strtolower($request->input('sort', 'desc'));
  56. $sort = in_array($sort, ['asc', 'desc']) ? $sort : 'desc';
  57. $sortBy = strtolower($request->input('sort_by', 'createdate'));
  58. $pageSize = intval($request->input('page_size', 10));
  59. if ($pageSize <= 0) {
  60. $pageSize = 100;
  61. }
  62. $query = DB::table('QPAccountsDB.dbo.OrderWithDraw')
  63. ->where('UserID', $UserID);
  64. if ($scoreType !== -1) {
  65. $query->where('score_type', $scoreType);
  66. }
  67. $allowedSortColumns = [
  68. 'withdraw' => 'WithDraw',
  69. 'createdate' => 'CreateDate',
  70. ];
  71. $sortColumn = $allowedSortColumns[$sortBy] ?? 'CreateDate';
  72. $list = $query
  73. ->selectRaw("CreateDate,OrderId,[State],WithDraw,ServiceFee,PixType,score_type")
  74. ->where('CreateDate', '>=', date('Y-m-d', strtotime('-30 day')))
  75. ->orderBy($sortColumn, $sort)
  76. ->paginate($pageSize);
  77. return apiReturnSuc($list);
  78. }
  79. public function GetWithDrawBaseInfo(Request $request)
  80. {
  81. $user = $request->user();
  82. $UserID=$user->UserID;
  83. // $paypass = $request->input('paypass');
  84. //
  85. // if (empty($user->InsurePass)||!Hash::check($paypass,$user->InsurePass)) {
  86. // return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  87. // }
  88. $dbh = DB::connection()->getPdo();
  89. $sql="DECLARE @return_value int
  90. set nocount on use QPAccountsDB
  91. EXEC @return_value = GSP_GR_GetWithDrawBaseInfo '$UserID'
  92. SELECT 'ReturnValue' = @return_value";
  93. // echo $sql;die;
  94. $stmt = $dbh->prepare($sql);
  95. $stmt->execute();
  96. $retval = $stmt->fetch(\PDO::FETCH_ASSOC);
  97. $retval['srate']=env('CONFIG_24680_RATE',1);
  98. return apiReturnSuc($retval);
  99. }
  100. public function GoWithDraw(Request $request)
  101. {
  102. $user = $request->user();
  103. $UserID=$user->UserID;
  104. // $paypass = $request->input('paypass');
  105. //
  106. // if (empty($user->InsurePass)||!Hash::check($paypass,$user->InsurePass)) {
  107. // return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  108. // }
  109. $score=$request->input('score',0);
  110. if(!$score||is_float($score)||$score<=0){
  111. return apiReturnFail(['web.withdraw.score_fail', 'Amount must be an integer value.']);
  112. }
  113. $redisKey = 'withdraw_'.$UserID;
  114. if (!SetNXLock::getExclusiveLock($redisKey)) {
  115. return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']);
  116. }
  117. GameScoreLocker::where('UserID',$UserID)->delete();
  118. $dbh = DB::connection()->getPdo();
  119. // $score=$score*NumConfig::NUM_VALUE;
  120. $sql="DECLARE @return_value int
  121. set nocount on use QPAccountsDB
  122. EXEC @return_value = GSP_GR_GetWithDraw20260312 '$UserID','$score'
  123. SELECT 'ReturnValue' = @return_value";
  124. // echo $sql;die;
  125. $stmt = $dbh->prepare($sql);
  126. $stmt->execute();
  127. SetNXLock::release($redisKey);
  128. $retval = $stmt->fetch(\PDO::FETCH_ASSOC);
  129. try {
  130. // set @ret = 1 --可提额度不足
  131. // set @ret = 2 --低于最低可提现金额
  132. // set @ret = 3 --高于最高可提现金额
  133. // set @ret = 4 --超过每天提现次数上限
  134. // set @ret = 5 --身上钱不够
  135. // set @ret = 6 --开在游戏里面
  136. // set @ret = 7 --未充值的用户TX额度
  137. if (isset($retval['ReturnValue'])) {
  138. $ReturnValue = $retval['ReturnValue'];
  139. // set @ret = 1 -- Insufficient withdrawal amount
  140. // set @ret = 2 -- Lower than the minimum withdrawal amount
  141. // set @ret = 3 -- Higher than the maximum withdrawal amount
  142. // set @ret = 4 -- Exceeded the daily withdrawal limit
  143. // set @ret = 5 -- Not enough money on hand
  144. // set @ret = 6 -- Opened in the game
  145. // set @ret = 7 -- Undeposited user TX amount
  146. $errors = [
  147. [],
  148. ['web.withdraw.no_withdraw_value', "The withdrawable amount is not enough"],
  149. ['web.withdraw.too_low', 'Lower than the minimum withdrawal amount'],
  150. ['web.withdraw.too_high', 'Higher than the maximum withdrawal amount'],
  151. ['web.withdraw.day_max', 'Exceeded the daily withdrawal limit'],
  152. ['web.withdraw.no_enouth_score', 'Not enough money on hand'],
  153. ['web.withdraw.in_game', 'Sorry, You\'re in game for now'],
  154. ['web.withdraw.no_deposit', ' You need deposit first!'],
  155. ];
  156. return apiReturnFail($errors[$ReturnValue], [], $ReturnValue == 7 ? 777 : 301);
  157. }else{
  158. return apiReturnSuc($retval);
  159. }
  160. }catch (\Exception $e){
  161. TelegramBot::getDefault()->sendProgramNotify("WithDraw Error:", var_export($retval,true).':'.$e->getTraceAsString());
  162. return apiReturnSuc($retval);
  163. }
  164. }
  165. public function saveCpf(Request $request)
  166. {
  167. // $user = $request->user();
  168. // $UserID=$user->UserID;
  169. //
  170. // $account = $request->Account ?: '';
  171. // $phone = $request->Phone ?: '';
  172. // $email = $request->Email ?: '';
  173. // $PixNum = $request->PixNum ?: '';
  174. //
  175. // if(!Util::validateCpf($PixNum)){
  176. // return apiReturnFail(['withdraw.account.tip.cpf_error','Cpf error format']);
  177. // }
  178. //
  179. // $redisKey = 'Api_updateAccountsPayInfo_'.$UserID;
  180. // $lock = SetNXLock::getExclusiveLock($redisKey);
  181. // if (!$lock) {
  182. // return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']);
  183. // }
  184. // $exist = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')->where('UserID', $UserID)->first();
  185. //
  186. // if ($exist) {
  187. // DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')->where('UserID', $UserID)->update(['PixNum' => $PixNum]);
  188. // } else {
  189. //
  190. // $data = ['BankUserName' => $account, 'PhoneNumber' => $phone, 'EmailAddress' => $email, 'UserID' => $UserID, 'PixNum' => $PixNum, 'Achieves' => '', 'HistoryWithDraw' => 0];
  191. // DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  192. // ->insert($data);
  193. // }
  194. // SetNXLock::release($redisKey);
  195. return apiReturnSuc();
  196. }
  197. public function MexWithDrawInfo(Request $request)
  198. {
  199. $user = $request->user();
  200. $UserID=$user->UserID;
  201. $paypass = $request->input('paypass');
  202. $PixType = $request->input('cbPixType');;
  203. $BankNO = $request->input('account');
  204. $AccountsBank = $request->input('account');
  205. $BankUserName = $request->input('userName');
  206. $PhoneNumber = $request->input('phone');
  207. $EmailAddress = $request->input('email');
  208. $IFSCNumber = $request->input('IFSCNumber');
  209. // $PANNumber = $request->input('PAN');
  210. // $AdhaarNumber = $request->input('adhaar');
  211. // $BranchBank = $request->input('branceBank');
  212. $BranchBank = $request->input('bank');//银行编号
  213. $PixNum = $request->input('account');
  214. Util::WriteLog("mexwithdraw",$request->all());
  215. if(isset($EmailAddress)&&!empty($EmailAddress)){
  216. $validator = Validator::make(
  217. ['email' => $EmailAddress],
  218. ['email' => 'required|email']
  219. );
  220. if ($validator->fails()) {
  221. return apiReturnFail(['web.user.email_fail','Wrong email format']);
  222. }
  223. }
  224. if (!$AccountsBank || $AccountsBank == 'undefined') {
  225. return apiReturnFail(['web.bank.account_empty', 'The bank account cannot be empty']);
  226. }
  227. if (!(strlen($AccountsBank) == 16 || strlen($AccountsBank) == 18)) {
  228. return apiReturnFail(['web.bank.account_invalid_length', 'The bank number must have 16 or 18 digits']);
  229. }
  230. if (!(strlen($IFSCNumber) == 18 && $IFSCNumber)) {
  231. return apiReturnFail(['web.bank.clabe_invalid_length', 'The Clabe number must have 18 digits']);
  232. }
  233. if (!$BankUserName || $BankUserName == 'undefined') {
  234. return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
  235. }
  236. if (!$BranchBank || $BranchBank == 'undefined') {
  237. return apiReturnFail(['web.bank.branch_empty', 'The branch code cannot be empty']);
  238. }
  239. if (strlen($AccountsBank) == 16) {
  240. $PixType = 2;
  241. }
  242. if (strlen($AccountsBank) == 18) {
  243. $PixType = 1;
  244. }
  245. $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
  246. if (!SetNXLock::getExclusiveLock($redisKey)) {
  247. return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
  248. }
  249. if (!$UserID) {
  250. Log::info('miss UserID', $request->all());
  251. SetNXLock::release($redisKey);
  252. return apiReturnFail(['web.bank.missing_userid', 'params error']);
  253. }
  254. if (empty($PixType)) {
  255. SetNXLock::release($redisKey);
  256. return apiReturnFail(['web.bank.pix_type_missing', 'The PIX type is missing']);
  257. }
  258. // 验证PixNum绑定次数
  259. if (!empty($PixNum)) {
  260. $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  261. ->where('BankCard', $PixNum)
  262. ->lock('WITH(NOLOCK)')
  263. ->count();
  264. if ($BindCount >= 3) {
  265. SetNXLock::release($redisKey);
  266. return apiReturnFail(['web.bank.cpf_used_multiple_times', 'The CPF number has been used multiple times and cannot be saved'], [], 302);
  267. }
  268. }
  269. // 验证玩家信息
  270. if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
  271. return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  272. }
  273. if ($PixType < 10 && false) {
  274. $data = compact('PixType', 'BankUserName', 'PhoneNumber', 'EmailAddress', 'PixNum');
  275. } else {
  276. $data = compact('PixType', 'BankUserName','IFSCNumber', 'PhoneNumber', 'EmailAddress','BankNO', 'AccountsBank','BranchBank','PixNum');
  277. $PixNum = $BankNO;
  278. }
  279. foreach ($data as $key => &$val) {
  280. $data[$key] = trim($val);
  281. }
  282. unset($val);
  283. $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  284. ->lock('WITH(NOLOCK)')
  285. ->where('UserID', $UserID)
  286. ->first();
  287. if (!$AccountWithDrawInfo) {
  288. $data['UserID'] = $UserID;
  289. $data['Achieves'] = 0;
  290. $data['HistoryWithDraw'] = 0;
  291. try {
  292. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  293. ->where('UserID', $UserID)
  294. ->insert($data);
  295. } catch (\Exception $e) {
  296. Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
  297. }
  298. } else {
  299. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  300. ->where('UserID', $UserID)
  301. ->update($data);
  302. }
  303. // 添加绑定记录
  304. if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
  305. try {
  306. DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  307. ->insert([
  308. 'UserID' => $UserID,
  309. 'BankCard' => $PixNum ?: '',
  310. 'BindDate' => now()
  311. ]);
  312. } catch (\Exception $e) {
  313. Log::error('insert RecordBankCardBind failed', ['data' => $data]);
  314. }
  315. }
  316. SetNXLock::release($redisKey);
  317. return apiReturnSuc();
  318. }
  319. public function RuWithDrawInfo(Request $request)
  320. {
  321. $user = $request->user();
  322. $UserID=$user->UserID;
  323. $paypass = $request->input('paypass');
  324. $PixType = $request->input('PixType');;
  325. $BankNO = $request->input('account');
  326. $BankUserName = $request->input('userName');
  327. $PhoneNumber = $request->input('phone');
  328. // $EmailAddress = $request->input('email');
  329. // $IFSCNumber = $request->input('IFSCNumber');
  330. // $PANNumber = $request->input('PAN');
  331. // $AdhaarNumber = $request->input('adhaar');
  332. // $BranchBank = $request->input('branceBank');
  333. $BranchBank = $request->input('bank');//银行编号
  334. $PixNum = $BankNO;
  335. $AccountsBank = $BankNO;
  336. Util::WriteLog("ruwithdraw",$request->all());
  337. if (!$BankUserName || $BankUserName == 'undefined') {
  338. return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
  339. }
  340. if($PixType==1) {
  341. if (!$AccountsBank || $AccountsBank == 'undefined') {
  342. return apiReturnFail(['web.bank.account_empty', 'The bank account cannot be empty']);
  343. }
  344. if (!(strlen($AccountsBank) == 16 )) {
  345. return apiReturnFail(['web.bank.account_invalid_length', 'The bank number must have 16 digits']);
  346. }
  347. // if (!(strlen($IFSCNumber) == 11 && $IFSCNumber)) {
  348. // return apiReturnFail(['web.bank.clabe_invalid_length', 'The Clabe number must have 18 digits']);
  349. // }
  350. }else{
  351. if(!$PhoneNumber||strlen($PhoneNumber)!=11){
  352. return apiReturnFail(['withdraw.account.tip.phone_error', 'The phone number is error']);
  353. }
  354. if (!$BranchBank || $BranchBank == 'undefined') {
  355. return apiReturnFail(['web.bank.branch_empty', 'The branch code cannot be empty']);
  356. }
  357. }
  358. $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
  359. if (!SetNXLock::getExclusiveLock($redisKey)) {
  360. return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
  361. }
  362. if (!$UserID) {
  363. Log::info('miss UserID', $request->all());
  364. SetNXLock::release($redisKey);
  365. return apiReturnFail(['web.bank.missing_userid', 'params error']);
  366. }
  367. if (empty($PixType)) {
  368. SetNXLock::release($redisKey);
  369. return apiReturnFail(['web.bank.pix_type_missing', 'The PIX type is missing']);
  370. }
  371. // 验证PixNum绑定次数
  372. if (!empty($PixNum)) {
  373. $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  374. ->where('BankCard', $PixNum)
  375. ->lock('WITH(NOLOCK)')
  376. ->count();
  377. if ($BindCount >= 3) {
  378. SetNXLock::release($redisKey);
  379. return apiReturnFail(['web.bank.cpf_used_multiple_times', 'The CPF number has been used multiple times and cannot be saved'], [], 302);
  380. }
  381. }
  382. // 验证玩家信息
  383. if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
  384. return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  385. }
  386. $data = compact('PixType', 'BankUserName', 'PhoneNumber','BankNO', 'AccountsBank','BranchBank','PixNum');
  387. $PixNum = $BankNO;
  388. foreach ($data as $key => &$val) {
  389. $data[$key] = trim($val);
  390. }
  391. unset($val);
  392. $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  393. ->lock('WITH(NOLOCK)')
  394. ->where('UserID', $UserID)
  395. ->first();
  396. if (!$AccountWithDrawInfo) {
  397. $data['UserID'] = $UserID;
  398. $data['Achieves'] = 0;
  399. $data['HistoryWithDraw'] = 0;
  400. try {
  401. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  402. ->where('UserID', $UserID)
  403. ->insert($data);
  404. } catch (\Exception $e) {
  405. Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
  406. }
  407. } else {
  408. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  409. ->where('UserID', $UserID)
  410. ->update($data);
  411. }
  412. // 添加绑定记录
  413. if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
  414. try {
  415. DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  416. ->insert([
  417. 'UserID' => $UserID,
  418. 'BankCard' => $PixNum ?: '',
  419. 'BindDate' => now()
  420. ]);
  421. } catch (\Exception $e) {
  422. Log::error('insert RecordBankCardBind failed', ['data' => $data]);
  423. }
  424. }
  425. SetNXLock::release($redisKey);
  426. return apiReturnSuc();
  427. }
  428. public function withDrawInfo(Request $request)
  429. {
  430. // return apiReturnFail('params error');
  431. $user = $request->user();
  432. $UserID=$user->UserID;
  433. // $UserID = (int)$request->globalUser->UserID;//$request->input('UserID');
  434. // $RequestDynamicPass = $request->input('DynamicPass');
  435. $PixType = $request->input('cbPixType');
  436. $BankUserName = urldecode($request->input('userName'));
  437. $EmailAddress = $request->input('email');
  438. $PixNum = $request->input('PixNum');
  439. if(!empty($EmailAddress))$EmailAddress=Util::cleanEmptyString($EmailAddress);
  440. if(!empty($PixNum))$PixNum=Util::cleanEmptyString($PixNum);
  441. if (!empty($EmailAddress)&&!Util::validateEmail($EmailAddress)) {
  442. return apiReturnFail(['web.user.email_fail','Wrong email format']);
  443. }
  444. $redisKey = 'withDrawInfo_withDrawInfo_'.$UserID;
  445. if (!SetNXLock::getExclusiveLock($redisKey)) {
  446. Util::WriteLog("withdrawInfo",[1, $request->all()]);
  447. return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']);
  448. }
  449. if (!$UserID) {
  450. Util::WriteLog("withdrawInfo",[2, $request->all()]);
  451. Log::info('miss UserID', $request->all());
  452. SetNXLock::release($redisKey);
  453. return apiReturnFail(['web.withdraw.params_error','params error']);
  454. }
  455. if (empty($PixType)) {
  456. Util::WriteLog("withdrawInfo",[3, $request->all()]);
  457. SetNXLock::release($redisKey);
  458. return apiReturnFail(["web.withdraw.pix_type_missing",'O tipo PIX está ausente']);
  459. }
  460. // 验证PixNum绑定次数
  461. // if (!empty($PixNum)) {
  462. // $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  463. // ->where('BankCard', $PixNum)
  464. // ->lock('WITH(NOLOCK)')
  465. // ->count();
  466. // if ($BindCount >= 6) {
  467. // Util::WriteLog("withdrawInfo",[4, $request->all()]);
  468. // SetNXLock::release($redisKey);
  469. // return apiReturnFail(['web.withdraw.cpf_number_used','O número do CPF foi usado várias vezes e não pode ser salvo'], [], 302);
  470. // }
  471. // }
  472. if ($PixType==1) {
  473. // 验证 cashapp
  474. if (!empty($PixNum)) {
  475. // 如果 PixNum 第一个字符不是 "$",则在前面添加 "$"
  476. if (substr($PixNum, 0, 1) !== '$') {
  477. $PixNum = '$' . $PixNum;
  478. }
  479. // 构建 cash.app URL
  480. $cashAppUrl = 'https://cash.app/' . $PixNum;
  481. try {
  482. // 使用 stream context 来获取 HTTP 响应头
  483. $context = stream_context_create([
  484. 'http' => [
  485. 'method' => 'GET',
  486. 'header' => "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n",
  487. 'ignore_errors' => true
  488. ]
  489. ]);
  490. $htmlContent = @file_get_contents($cashAppUrl, false, $context);
  491. // 检查 HTTP 响应头中的状态码
  492. if ($htmlContent === false || (isset($http_response_header) && preg_match('/HTTP\/\d\.\d\s+404/', implode("\n", $http_response_header)))) {
  493. Util::WriteLog("withdrawInfo", [5, $request->all(), 'Invalid cashapp: ' . $PixNum]);
  494. SetNXLock::release($redisKey);
  495. return apiReturnFail(['web.withdraw.invalid_cashapp', 'Invalid CashApp account']);
  496. }
  497. if ($htmlContent !== false) {
  498. // 去除空格换行,转换成一行字符串
  499. $htmlContent = preg_replace('/\s+/', '', $htmlContent);
  500. Util::WriteLog("withdrawInfo", [5, $request->all(), 'CashApp verification response: ' . $htmlContent]);
  501. // 检查响应内容中是否包含 "404 Not Found"
  502. if (stripos($htmlContent, '404NotFound') !== false) {
  503. Util::WriteLog("withdrawInfo", [5, $request->all(), 'Invalid cashapp: ' . $PixNum]);
  504. SetNXLock::release($redisKey);
  505. return apiReturnFail(['web.withdraw.invalid_cashapp', 'Invalid CashApp account']);
  506. }
  507. }
  508. } catch (\Exception $e) {
  509. // 其他异常也记录日志但不阻止流程
  510. Util::WriteLog("withdrawInfo", [5, $request->all(), 'CashApp verification error: ' . $e->getMessage()]);
  511. }
  512. }
  513. $data = compact('PixType', 'BankUserName', 'PixNum');
  514. } else {
  515. $data = compact('PixType', 'EmailAddress');
  516. }
  517. foreach ($data as $key => &$val) {
  518. $data[$key] = trim($val);
  519. }
  520. unset($val);
  521. $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  522. ->lock('WITH(NOLOCK)')
  523. ->where('UserID', $UserID)
  524. ->first();
  525. if (!$AccountWithDrawInfo) {
  526. $data['UserID'] = $UserID;
  527. $data['Achieves'] = 0;
  528. $data['HistoryWithDraw'] = 0;
  529. try {
  530. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  531. ->where('UserID', $UserID)
  532. ->insert($data);
  533. } catch (\Exception $e) {
  534. Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
  535. Util::WriteLog("withdrawInfo",[6, $request->all(),$data]);
  536. }
  537. } else {
  538. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  539. ->where('UserID', $UserID)
  540. ->update($data);
  541. }
  542. SetNXLock::release($redisKey);
  543. return apiReturnSuc();
  544. }
  545. public function withDrawInfoSA(Request $request)
  546. {
  547. // return apiReturnFail('params error');
  548. $UserID = $request->input('UserID');
  549. $RequestDynamicPass = $request->input('DynamicPass');
  550. $PixType = $request->input('cbPixType');
  551. $BankNO = $request->input('bank');
  552. $AccountsBank = urldecode($request->input('account'));
  553. $BankUserName = urldecode($request->input('userName'));
  554. // 原始代码
  555. $BankUserName = Util::filterNickName($BankUserName);
  556. // 新增处理:在大写字母前加空格
  557. $BankUserName = preg_replace('/(?<!^)([A-Z])/', ' $1', $BankUserName);
  558. $PhoneNumber = $request->input('phone');
  559. $EmailAddress = $request->input('email');
  560. $IFSCNumber = $request->input('IFSC');
  561. $PANNumber = $request->input('PAN');
  562. $AdhaarNumber = $request->input('adhaar');
  563. $BranchBank = $request->input('branceBank');
  564. $PixNum = $request->input('PixNum');
  565. $redisKey = 'withDrawInfo_withDrawInfo_'.$UserID;
  566. if (!SetNXLock::getExclusiveLock($redisKey)) {
  567. Util::WriteLog("withdrawInfo",[1, $request->all()]);
  568. return apiReturnFail('Tente novamente mais tarde');
  569. }
  570. if (!$UserID) {
  571. Util::WriteLog("withdrawInfo",[2, $request->all()]);
  572. Log::info('miss UserID', $request->all());
  573. SetNXLock::release($redisKey);
  574. return apiReturnFail('params error');
  575. }
  576. if (empty($PixType)) {
  577. Util::WriteLog("withdrawInfo",[3, $request->all()]);
  578. SetNXLock::release($redisKey);
  579. return apiReturnFail('O tipo PIX está ausente');
  580. }
  581. // Util::validateSouthAmericanPhone('',)
  582. // 验证PixNum绑定次数
  583. if (!empty($PixNum)) {
  584. $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  585. ->where('BankCard', $PixNum)
  586. ->lock('WITH(NOLOCK)')
  587. ->count();
  588. if ($BindCount >= 8) {
  589. Util::WriteLog("withdrawInfo",[4, $request->all()]);
  590. SetNXLock::release($redisKey);
  591. return apiReturnFail(['web.withdraw.cpf_number_used','The CPF number has been used several times and cannot be saved'], [], 302);
  592. }
  593. }
  594. // if(!is_numeric($PixNum)){
  595. // return apiReturnFail(['web.withdraw.pix_failed','The CPF number has been used several times and cannot be saved'], [], 302);
  596. // }
  597. // 验证玩家信息
  598. $DynamicPass = DB::table(TableName::QPAccountsDB() . 'AccountsInfo')
  599. ->where('UserID', $UserID)
  600. ->lock('WITH(NOLOCK)')
  601. ->value('DynamicPass');
  602. if ($DynamicPass != $RequestDynamicPass || empty($DynamicPass)) {
  603. SetNXLock::release($redisKey);
  604. Util::WriteLog("withdrawInfo",[5, $request->all()]);
  605. return apiReturnFail('As informações do jogador são inconsistentes');
  606. }
  607. $data = compact('PixType', 'BankUserName', 'PhoneNumber', 'EmailAddress', 'PixNum','BankNO', 'AccountsBank', 'IFSCNumber', 'PANNumber', 'AdhaarNumber', 'BranchBank');
  608. foreach ($data as $key => &$val) {
  609. $data[$key] = trim($val);
  610. }
  611. unset($val);
  612. $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  613. ->lock('WITH(NOLOCK)')
  614. ->where('UserID', $UserID)
  615. ->first();
  616. if (!$AccountWithDrawInfo) {
  617. $data['UserID'] = $UserID;
  618. $data['Achieves'] = 0;
  619. $data['HistoryWithDraw'] = 0;
  620. try {
  621. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  622. ->where('UserID', $UserID)
  623. ->insert($data);
  624. } catch (\Exception $e) {
  625. Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
  626. Util::WriteLog("withdrawInfo",[6, $request->all(),$data]);
  627. }
  628. } else {
  629. $data = array_filter($data, function ($value) {
  630. return !is_null($value) && $value !== '';
  631. });
  632. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  633. ->where('UserID', $UserID)
  634. ->update($data);
  635. }
  636. // 添加绑定记录
  637. if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
  638. try {
  639. if(!DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')->where('UserID', $UserID)->exists()&&is_numeric($PixNum)) {
  640. DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  641. ->insert([
  642. 'UserID' => $UserID,
  643. 'BankCard' => $PixNum ?? '',
  644. 'BindDate' => now()
  645. ]);
  646. Util::WriteLog('update_pix', [
  647. 'UserID' => $UserID,
  648. 'BankCard' => $PixNum ?? '',
  649. 'BindDate' => now()
  650. ]);
  651. }
  652. } catch (\Exception $e) {
  653. Log::error('insert RecordBankCardBind failed', ['data' => $data]);
  654. Util::WriteLog("withdrawInfo",[7, $request->all(),$data]);
  655. }
  656. }
  657. SetNXLock::release($redisKey);
  658. return apiReturnSuc();
  659. }
  660. public function kycSimpleEU(Request $request)
  661. {
  662. // return apiReturnFail('params error');
  663. $user = $request->user();
  664. $UserID=$user->UserID;
  665. $firstName = Util::filterNickName(urldecode($request->input('firstName')));
  666. $lastName = Util::filterNickName(urldecode($request->input('lastName')));
  667. // 原始代码
  668. $BankUserName = $firstName.'|'.$lastName;
  669. $PhoneNumber = $request->input('phone');
  670. $EmailAddress = $request->input('email');
  671. Util::WriteLog("kyc_eu",$request->all());
  672. if(isset($EmailAddress)&&!empty($EmailAddress)){
  673. $validator = Validator::make(
  674. ['email' => $EmailAddress],
  675. ['email' => 'required|email']
  676. );
  677. if ($validator->fails()) {
  678. return apiReturnFail(['web.user.email_fail','Wrong email format']);
  679. }
  680. }
  681. if (!$BankUserName || $BankUserName == 'undefined') {
  682. return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
  683. }
  684. $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
  685. if (!SetNXLock::getExclusiveLock($redisKey)) {
  686. return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
  687. }
  688. if (!$UserID) {
  689. Log::info('miss UserID', $request->all());
  690. SetNXLock::release($redisKey);
  691. return apiReturnFail(['web.bank.missing_userid', 'params error']);
  692. }
  693. $data = compact('BankUserName', 'PhoneNumber', 'EmailAddress');
  694. foreach ($data as $key => &$val) {
  695. $data[$key] = trim($val);
  696. if(empty($val))unset($data[$key]);
  697. }
  698. unset($val);
  699. $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  700. ->lock('WITH(NOLOCK)')
  701. ->where('UserID', $UserID)
  702. ->first();
  703. if (!$AccountWithDrawInfo) {
  704. $data['UserID'] = $UserID;
  705. $data['Achieves'] = 0;
  706. $data['HistoryWithDraw'] = 0;
  707. try {
  708. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  709. ->where('UserID', $UserID)
  710. ->insert($data);
  711. } catch (\Exception $e) {
  712. Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
  713. }
  714. } else {
  715. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  716. ->where('UserID', $UserID)
  717. ->update($data);
  718. }
  719. SetNXLock::release($redisKey);
  720. return apiReturnSuc();
  721. }
  722. public function withDrawInfoEU(Request $request)
  723. {
  724. // return apiReturnFail('params error');
  725. $user = $request->user();
  726. $UserID=$user->UserID;
  727. // $UserID = $request->input('UserID');
  728. // $RequestDynamicPass = $request->input('DynamicPass');
  729. $PixType = $request->input('cbPixType');
  730. $firstName = Util::filterNickName(urldecode($request->input('firstName')));
  731. $lastName = Util::filterNickName(urldecode($request->input('lastName')));
  732. // 原始代码
  733. $BankUserName = $firstName.'|'.$lastName;
  734. $BankNO = $request->input('account');
  735. $AccountsBank = $request->input('account');
  736. $PhoneNumber = $request->input('phone');
  737. $EmailAddress = $request->input('email');
  738. $IFSCNumber = $request->input('IFSCNumber');
  739. $BranchBank = $request->input('bank');//银行编号
  740. $PixNum = $request->input('account');
  741. Util::WriteLog("euwithdraw",$request->all());
  742. if(isset($EmailAddress)&&!empty($EmailAddress)){
  743. $validator = Validator::make(
  744. ['email' => $EmailAddress],
  745. ['email' => 'required|email']
  746. );
  747. if ($validator->fails()) {
  748. return apiReturnFail(['web.user.email_fail','Wrong email format']);
  749. }
  750. }
  751. if (!$AccountsBank || $AccountsBank == 'undefined') {
  752. return apiReturnFail(['web.bank.account_empty', 'The bank account cannot be empty']);
  753. }
  754. if (!(strlen($AccountsBank) == 16 || strlen($AccountsBank) == 18)) {
  755. return apiReturnFail(['web.bank.account_invalid_length', 'The bank number must have 16 or 18 digits']);
  756. }
  757. if (!(strlen($IFSCNumber) == 18 && $IFSCNumber)) {
  758. return apiReturnFail(['web.bank.clabe_invalid_length', 'The Clabe number must have 18 digits']);
  759. }
  760. if (!$BankUserName || $BankUserName == 'undefined') {
  761. return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
  762. }
  763. if (!$BranchBank || $BranchBank == 'undefined') {
  764. return apiReturnFail(['web.bank.branch_empty', 'The branch code cannot be empty']);
  765. }
  766. if (strlen($AccountsBank) == 16) {
  767. $PixType = 2;
  768. }
  769. if (strlen($AccountsBank) == 18) {
  770. $PixType = 1;
  771. }
  772. $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
  773. if (!SetNXLock::getExclusiveLock($redisKey)) {
  774. return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
  775. }
  776. if (!$UserID) {
  777. Log::info('miss UserID', $request->all());
  778. SetNXLock::release($redisKey);
  779. return apiReturnFail(['web.bank.missing_userid', 'params error']);
  780. }
  781. if (empty($PixType)) {
  782. SetNXLock::release($redisKey);
  783. return apiReturnFail(['web.bank.pix_type_missing', 'The PIX type is missing']);
  784. }
  785. // 验证PixNum绑定次数
  786. if (!empty($PixNum)) {
  787. $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  788. ->where('BankCard', $PixNum)
  789. ->lock('WITH(NOLOCK)')
  790. ->count();
  791. if ($BindCount >= 3) {
  792. SetNXLock::release($redisKey);
  793. return apiReturnFail(['web.bank.cpf_used_multiple_times', 'The CPF number has been used multiple times and cannot be saved'], [], 302);
  794. }
  795. }
  796. // 验证玩家信息
  797. if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
  798. return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  799. }
  800. if ($PixType < 10 && false) {
  801. $data = compact('PixType', 'BankUserName', 'PhoneNumber', 'EmailAddress', 'PixNum');
  802. } else {
  803. $data = compact('PixType', 'BankUserName','IFSCNumber', 'PhoneNumber', 'EmailAddress','BankNO', 'AccountsBank','BranchBank','PixNum');
  804. $PixNum = $BankNO;
  805. }
  806. foreach ($data as $key => &$val) {
  807. $data[$key] = trim($val);
  808. }
  809. unset($val);
  810. $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  811. ->lock('WITH(NOLOCK)')
  812. ->where('UserID', $UserID)
  813. ->first();
  814. if (!$AccountWithDrawInfo) {
  815. $data['UserID'] = $UserID;
  816. $data['Achieves'] = 0;
  817. $data['HistoryWithDraw'] = 0;
  818. try {
  819. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  820. ->where('UserID', $UserID)
  821. ->insert($data);
  822. } catch (\Exception $e) {
  823. Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
  824. }
  825. } else {
  826. DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  827. ->where('UserID', $UserID)
  828. ->update($data);
  829. }
  830. // 添加绑定记录
  831. if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
  832. try {
  833. DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
  834. ->insert([
  835. 'UserID' => $UserID,
  836. 'BankCard' => $PixNum ?: '',
  837. 'BindDate' => now()
  838. ]);
  839. } catch (\Exception $e) {
  840. Log::error('insert RecordBankCardBind failed', ['data' => $data]);
  841. }
  842. }
  843. SetNXLock::release($redisKey);
  844. return apiReturnSuc();
  845. }
  846. // 获取提现信息
  847. public function getWithDrawInfo(Request $request)
  848. {
  849. // $UserID = (int)$request->globalUser->UserID;//$request->input('UserID');
  850. $user = $request->user();
  851. $UserID=$user->UserID;
  852. // $paypass = $request->input('paypass');
  853. // if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
  854. // return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
  855. // }
  856. $info = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
  857. ->where('UserID', $UserID)
  858. ->lock('WITH(NOLOCK)')
  859. ->first();
  860. if (!$info) { // 赋值 -- 避免客户端报错
  861. $info = [
  862. // 'BankNO' => '',
  863. // 'AccountsBank' => '',
  864. 'BankUserName' => '',
  865. // 'PhoneNumber' => '',
  866. // 'IFSCNumber' => '',
  867. 'EmailAddress' => '',
  868. // 'Achieves' => '',
  869. // 'PANNumber' => '',
  870. // 'AdhaarNumber' => '',
  871. // 'BranchBank' => '',
  872. 'PixNum' => '',
  873. 'PixType' => '',
  874. ];
  875. }
  876. $info = json_decode(json_encode($info),true);
  877. if(env('REGION_24680')=='na-mexico') {
  878. $info['bank_list'] = config('games.mex_bank_list');
  879. }else if(env('REGION_24680')=='eu-russian') {
  880. $info['bank_list'] = config('games.ru_bank_list');
  881. }
  882. $AccountsInfoModel = new AccountsInfo();
  883. $total = $AccountsInfoModel->accountTotalStatistics([$UserID]);
  884. $totalRecharge= @$total[0]->Recharge ?? 0;
  885. $info['total_recharge'] = intval($totalRecharge);
  886. $info['withdraw_level'] = env('MIN_RECHARGE',20);
  887. return apiReturnSuc(compact('info'));
  888. }
  889. }