PayPlusCashierLogic.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. namespace App\Http\logic\api;
  3. use App\dao\Estatisticas\RechargeWithDraw;
  4. use App\Http\helper\NumConfig;
  5. use App\Inter\CashierInterFace;
  6. use App\Models\PrivateMail;
  7. use App\Models\RecordUserDataStatistics;
  8. use App\Services\PayPlus;
  9. use App\Services\StoredProcedure;
  10. use App\Util;
  11. use Illuminate\Support\Facades\DB;
  12. use Illuminate\Support\Facades\Redis;
  13. class PayPlusCashierLogic implements CashierInterFace
  14. {
  15. const AGENT = 109;
  16. protected $service;
  17. public function __construct(PayPlus $service = null)
  18. {
  19. $this->service = $service ?: (new PayPlus())->getPayoutService();
  20. }
  21. public function payment(
  22. $RecordID,
  23. $amount,
  24. $accountName,
  25. $phone,
  26. $email,
  27. $OrderId,
  28. $PixNum,
  29. $PixType,
  30. $IFSCNumber,
  31. $BranchBank,
  32. $BankNO
  33. ) {
  34. $query = DB::connection('write')
  35. ->table('QPAccountsDB.dbo.OrderWithDraw')
  36. ->where('RecordID', $RecordID)
  37. ->first();
  38. if (!$query) {
  39. return 'fail';
  40. }
  41. $result = $this->createBeneficiaryAndPayout([
  42. 'user_id' => $query->UserID,
  43. 'amount' => round($amount / NumConfig::NUM_VALUE, 2),
  44. 'currency' => $this->service->getConfig()['currency'] ?? 'USD',
  45. 'order_id' => $OrderId,
  46. 'pix_type' => $PixType,
  47. 'cashapp_account' => $PixNum,
  48. 'email' => $email,
  49. 'phone' => $phone,
  50. 'name' => $accountName,
  51. ]);
  52. if ($result && isset($result['code']) && (int) $result['code'] === 200) {
  53. return $result;
  54. }
  55. return 'fail';
  56. }
  57. public function createBeneficiaryAndPayout(array $input)
  58. {
  59. $beneficiary = $this->resolveBeneficiary($input);
  60. if (!$beneficiary) {
  61. return false;
  62. }
  63. $payload = [
  64. 'amount' => (float) $input['amount'],
  65. 'currency' => strtoupper($input['currency'] ?? ($this->service->getConfig()['currency'] ?? 'USD')),
  66. 'reference_id' => (string) $input['order_id'],
  67. 'beneficiary_id' => (int) $beneficiary['beneficiary_id'],
  68. ];
  69. if ((int) ($input['pix_type'] ?? 1) === 2) {
  70. $payload['paypal_email'] = $input['email'] ?: $beneficiary['email'];
  71. return $this->service->postPayout('/rest/v2/payouts/paypal', $payload);
  72. }
  73. $cashAppAccount = (string) ($input['cashapp_account'] ?? '');
  74. if ($cashAppAccount !== '' && strpos($cashAppAccount, '$') !== 0) {
  75. $cashAppAccount = '$' . $cashAppAccount;
  76. }
  77. $payload['cashapp_account'] = $cashAppAccount ?: '$unknown';
  78. return $this->service->postPayout('/rest/v2/payouts/cashApp', $payload);
  79. }
  80. public function resolveBeneficiary(array $input)
  81. {
  82. $payload = $this->service->buildBeneficiaryPayload($input);
  83. $created = $this->service->postPayout('/rest/v2/beneficiaries/create', $payload);
  84. if ((int) ($created['code'] ?? 0) === 200 && !empty($created['data']['beneficiary_id'])) {
  85. return $created['data'];
  86. }
  87. if ((int) ($created['code'] ?? 0) !== 4002001) {
  88. Util::WriteLog('PayPlus_error', 'beneficiary create failed: ' . json_encode($created));
  89. return false;
  90. }
  91. $query = $this->service->postPayout('/rest/v2/beneficiaries/query', [
  92. 'payee_id' => $payload['payee_id'],
  93. ]);
  94. if ((int) ($query['code'] ?? 0) === 200 && !empty($query['data']['beneficiary_id'])) {
  95. return $query['data'];
  96. }
  97. Util::WriteLog('PayPlus_error', 'beneficiary query failed: ' . json_encode($query));
  98. return false;
  99. }
  100. public function notify($post)
  101. {
  102. if (!is_array($post)) {
  103. $post = json_decode($post, true) ?: [];
  104. }
  105. $detail = $this->queryPayoutDetailForNotify($post);
  106. if (empty($detail)) {
  107. return 'success';
  108. }
  109. $orderId = $detail['reference_id'] ?? ($post['reference_id'] ?? '');
  110. if ($orderId === '') {
  111. return 'success';
  112. }
  113. $query = DB::connection('write')
  114. ->table('QPAccountsDB.dbo.OrderWithDraw')
  115. ->where('OrderId', $orderId)
  116. ->first();
  117. if (!$query || ($query->State != 5 && $query->State != 7)) {
  118. return 'success';
  119. }
  120. $orderStatus = $this->resolvePayoutStatus($detail['transaction_status'] ?? '');
  121. if (!$orderStatus) {
  122. return 'success';
  123. }
  124. $agent = DB::connection('write')->table('agent.dbo.admin_configs')
  125. ->where('config_value', self::AGENT)
  126. ->where('type', 'cash')
  127. ->select('id')
  128. ->first();
  129. $agentId = $agent->id ?? '';
  130. $now = now();
  131. $userId = $query->UserID;
  132. $takeMoney = $query->WithDraw + $query->ServiceFee;
  133. $withdrawData = [
  134. 'agent' => $agentId,
  135. 'finishDate' => $now,
  136. ];
  137. if ($orderStatus === 1) {
  138. $withdrawData['State'] = 2;
  139. $this->handleSuccess($query, $takeMoney);
  140. } else {
  141. $withdrawData['State'] = 6;
  142. $failedMessage = $detail['description'] ?? ($post['msg'] ?? 'REJECTED');
  143. PrivateMail::failMail($userId, $orderId, $takeMoney, $failedMessage, '30000,' . $takeMoney);
  144. }
  145. DB::connection('write')->table('QPAccountsDB.dbo.AccountsRecord')->updateOrInsert(
  146. ['RecordID' => $query->RecordID, 'type' => 1],
  147. [
  148. 'before_state' => $query->State,
  149. 'after_state' => $withdrawData['State'],
  150. 'RecordID' => $query->RecordID,
  151. 'update_at' => date('Y-m-d H:i:s'),
  152. ]
  153. );
  154. DB::connection('write')
  155. ->table('QPAccountsDB.dbo.OrderWithDraw')
  156. ->where('OrderId', $query->OrderId)
  157. ->update($withdrawData);
  158. return 'success';
  159. }
  160. public function queryPayoutDetailForNotify(array $post)
  161. {
  162. $transactionId = (string) ($post['transaction_id'] ?? '');
  163. $referenceId = (string) ($post['reference_id'] ?? '');
  164. if ($transactionId === '' && $referenceId === '') {
  165. return [];
  166. }
  167. try {
  168. $result = $this->service->queryPayoutOrder($transactionId, $referenceId);
  169. } catch (\Exception $exception) {
  170. Util::WriteLog('PayPlus_error', 'payout query failed: ' . $exception->getMessage());
  171. return [];
  172. }
  173. if ((int) ($result['code'] ?? 0) !== 200 || empty($result['data']) || !is_array($result['data'])) {
  174. Util::WriteLog('PayPlus_error', 'payout query invalid response: ' . json_encode($result));
  175. return [];
  176. }
  177. return $result['data'];
  178. }
  179. public function resolvePayoutStatus($status)
  180. {
  181. switch (strtoupper((string) $status)) {
  182. case 'PAID':
  183. return 1;
  184. case 'REJECTED':
  185. case 'REFUNDED':
  186. return 2;
  187. default:
  188. return 0;
  189. }
  190. }
  191. protected function handleSuccess($query, $takeMoney)
  192. {
  193. $userId = $query->UserID;
  194. $first = DB::connection('write')
  195. ->table('QPAccountsDB.dbo.UserTabData')
  196. ->where('UserID', $userId)
  197. ->first();
  198. if ($first) {
  199. DB::connection('write')
  200. ->table('QPAccountsDB.dbo.UserTabData')
  201. ->where('UserID', $userId)
  202. ->increment('TakeMoney', $takeMoney);
  203. } else {
  204. DB::connection('write')
  205. ->table('QPAccountsDB.dbo.UserTabData')
  206. ->insert(['TakeMoney' => $takeMoney, 'UserID' => $userId]);
  207. PrivateMail::praiseSendMail($userId);
  208. }
  209. try {
  210. StoredProcedure::addPlatformData($userId, 4, $takeMoney);
  211. } catch (\Exception $exception) {
  212. Util::WriteLog('StoredProcedure', $exception);
  213. }
  214. RecordUserDataStatistics::updateOrAdd($userId, $takeMoney, 0, $query->ServiceFee);
  215. (new RechargeWithDraw())->withDraw($userId, $takeMoney, 0, $query->ServiceFee);
  216. Redis::connection()->incr('draw_' . date('Ymd') . $userId);
  217. PrivateMail::successMail($userId, $query->OrderId, $takeMoney);
  218. StoredProcedure::user_label($userId, 2, $takeMoney);
  219. }
  220. }