WithDrawInfoController.php 41 KB

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