WithDrawInfoController.php 41 KB

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