CoinPayCashierLogic.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace App\Http\logic\api;
  3. use App\dao\Estatisticas\RechargeWithDraw;
  4. use App\Inter\CashierInterFace;
  5. use App\Models\PrivateMail;
  6. use App\Models\RecordUserDataStatistics;
  7. use App\Services\CoinPay;
  8. use App\Services\StoredProcedure;
  9. use App\Util;
  10. use Illuminate\Support\Facades\DB;
  11. use Illuminate\Support\Facades\Log;
  12. use Illuminate\Support\Facades\Redis;
  13. class CoinPayCashierLogic implements CashierInterFace
  14. {
  15. const AGENT = 102;
  16. public function payment($RecordID, $amount, $accountName, $phone, $email, $OrderId, $PixNum, $PixType, $IFSCNumber, $BranchBank, $BankNO)
  17. {
  18. $query = DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('RecordID', $RecordID)->first();
  19. if (!$query) {
  20. return 'fail';
  21. }
  22. $service = new CoinPay('CoinPayOut');
  23. $config = $service->getConfig();
  24. $withdrawInfo = DB::table('QPAccountsDB.dbo.AccountWithDrawInfo')->where('UserID', $query->UserID)->first();
  25. $address = $PixNum ?: ($withdrawInfo->PixNum ?? $withdrawInfo->BankNO ?? $BankNO);
  26. if (!$address) {
  27. Util::WriteLog('CoinPay', 'missing wallet address for withdraw: ' . $OrderId);
  28. return 'fail';
  29. }
  30. $language = strtoupper($config['language'] ?? 'EN');
  31. $coin = strtoupper($config['coin'] ?? 'USDT');
  32. $protocol = strtoupper($config['protocol'] ?? 'TRC20');
  33. $rateType = (int)($config['rateType'] ?? 2);
  34. $currency = strtoupper($config['currency'] ?? 'USD');
  35. $amountDecimal = number_format($amount / 100, 2, '.', '');
  36. $params = [
  37. 'merchantMemberNo' => (string)$query->UserID,
  38. 'merchantOrderNo' => $OrderId,
  39. 'language' => $language,
  40. 'coin' => $coin,
  41. 'rateType' => $rateType,
  42. 'protocol' => $protocol,
  43. 'notifyUrl' => $config['cashNotify'] ?? '',
  44. 'toAddress' => $address,
  45. 'timestamp' => time(),
  46. ];
  47. if ($rateType === 1) {
  48. $params['amount'] = number_format($amountDecimal, 8, '.', '');
  49. $params['rate'] = $config['rate'] ?? '1';
  50. } else {
  51. $params['currencyAmount'] = $amountDecimal;
  52. $params['currency'] = $currency;
  53. }
  54. $signedParams = $service->sign($params);
  55. $response = $service->post('/order/withdrawOrderCoinCreate', $signedParams);
  56. Log::info('CoinPay withdraw request', $signedParams);
  57. Log::info('CoinPay withdraw response', [$response]);
  58. try {
  59. $data = \GuzzleHttp\json_decode($response, true);
  60. } catch (\Throwable $e) {
  61. Util::WriteLog('CoinPay_error', $e->getMessage());
  62. return 'fail';
  63. }
  64. if (isset($data['code']) && (int)$data['code'] === 0) {
  65. return $data;
  66. }
  67. return 'fail';
  68. }
  69. public function notify($post)
  70. {
  71. if (!is_array($post)) {
  72. $post = \GuzzleHttp\json_decode($post, true);
  73. }
  74. Util::WriteLog('CoinPay', 'withdraw notify: ' . json_encode($post, JSON_UNESCAPED_UNICODE));
  75. $OrderId = $post['merchantOrderNo'] ?? '';
  76. $query = DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderId', $OrderId)->first();
  77. if (!$query) {
  78. Util::WriteLog('CoinPay', 'withdraw order not found');
  79. return '{"success":true,"message":"order not found"}';
  80. }
  81. if (!in_array($query->State, [5, 7])) {
  82. Util::WriteLog('CoinPay', 'withdraw already handled: ' . $OrderId);
  83. return 'SUCCESS';
  84. }
  85. $status = (int)($post['state'] ?? 0);
  86. $now = now();
  87. $withdraw_data = [];
  88. $msg = $post['msg'] ?? '';
  89. $TakeMoney = $query->WithDraw + $query->ServiceFee;
  90. $UserID = $query->UserID;
  91. switch ($status) {
  92. case 3:
  93. $withdraw_data = [
  94. 'State' => 2,
  95. 'agent' => self::AGENT,
  96. 'finishDate' => $now,
  97. ];
  98. $this->handleSuccess($UserID, $TakeMoney, $OrderId, $query->ServiceFee);
  99. break;
  100. case 4:
  101. case 5:
  102. case 6:
  103. case 7:
  104. $msg = $msg ?: 'Withdraw rejected';
  105. $bonus = '30000,' . $TakeMoney;
  106. PrivateMail::failMail($UserID, $OrderId, $TakeMoney, $msg, $bonus);
  107. $withdraw_data = [
  108. 'State' => 6,
  109. 'agent' => self::AGENT,
  110. 'remark' => $msg,
  111. ];
  112. break;
  113. default:
  114. return 'SUCCESS';
  115. }
  116. $recordData = [
  117. 'before_state' => $query->State,
  118. 'after_state' => $withdraw_data['State'] ?? $query->State,
  119. 'RecordID' => $query->RecordID,
  120. 'update_at' => date('Y-m-d H:i:s'),
  121. ];
  122. DB::connection('write')->table('QPAccountsDB.dbo.AccountsRecord')
  123. ->updateOrInsert(['RecordID' => $query->RecordID, 'type' => 1], $recordData);
  124. DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')
  125. ->where('OrderId', $OrderId)
  126. ->update($withdraw_data);
  127. return 'SUCCESS';
  128. }
  129. protected function handleSuccess($UserID, $TakeMoney, $OrderId, $serviceFee): void
  130. {
  131. $first = DB::connection('write')->table('QPAccountsDB.dbo.UserTabData')->where('UserID', $UserID)->first();
  132. if ($first) {
  133. DB::connection('write')->table('QPAccountsDB.dbo.UserTabData')->where('UserID', $UserID)->increment('TakeMoney', $TakeMoney);
  134. } else {
  135. DB::connection('write')->table('QPAccountsDB.dbo.UserTabData')->insert(['TakeMoney' => $TakeMoney, 'UserID' => $UserID]);
  136. try {
  137. PrivateMail::praiseSendMail($UserID);
  138. } catch (\Throwable $e) {
  139. }
  140. }
  141. try {
  142. StoredProcedure::addPlatformData($UserID, 4, $TakeMoney);
  143. } catch (\Throwable $exception) {
  144. Util::WriteLog('StoredProcedure', $exception->getMessage());
  145. }
  146. $withdrawal_position_log = DB::connection('write')->table('agent.dbo.withdrawal_position_log')->where('order_sn', $OrderId)->first();
  147. if ($withdrawal_position_log) {
  148. DB::connection('write')->table('agent.dbo.withdrawal_position_log')
  149. ->where('order_sn', $OrderId)
  150. ->update(['take_effect' => 2, 'update_at' => date('Y-m-d H:i:s')]);
  151. }
  152. RecordUserDataStatistics::updateOrAdd($UserID, $TakeMoney, 0, $serviceFee);
  153. (new RechargeWithDraw())->withDraw($UserID, $TakeMoney);
  154. $redis = Redis::connection();
  155. $redis->incr('draw_' . date('Ymd') . $UserID);
  156. StoredProcedure::user_label($UserID, 2, $TakeMoney);
  157. }
  158. }