service = $service ?: (new PayPlus())->getPayoutService(); } public function payment( $RecordID, $amount, $accountName, $phone, $email, $OrderId, $PixNum, $PixType, $IFSCNumber, $BranchBank, $BankNO ) { $query = DB::connection('write') ->table('QPAccountsDB.dbo.OrderWithDraw') ->where('RecordID', $RecordID) ->first(); if (!$query) { return 'fail'; } $result = $this->createBeneficiaryAndPayout([ 'user_id' => $query->UserID, 'amount' => round($amount / NumConfig::NUM_VALUE, 2), 'currency' => $this->service->getConfig()['currency'] ?? 'USD', 'order_id' => $OrderId, 'pix_type' => $PixType, 'cashapp_account' => $PixNum, 'email' => $email, 'phone' => $phone, 'name' => $accountName, ]); if ($result && isset($result['code']) && (int) $result['code'] === 200) { return $result; } return 'fail'; } public function createBeneficiaryAndPayout(array $input) { $beneficiary = $this->resolveBeneficiary($input); if (!$beneficiary) { return false; } $payload = [ 'amount' => (float) $input['amount'], 'currency' => strtoupper($input['currency'] ?? ($this->service->getConfig()['currency'] ?? 'USD')), 'reference_id' => (string) $input['order_id'], 'beneficiary_id' => (int) $beneficiary['beneficiary_id'], ]; if ((int) ($input['pix_type'] ?? 1) === 2) { $payload['paypal_email'] = $input['email'] ?: $beneficiary['email']; return $this->service->postPayout('/rest/v2/payouts/paypal', $payload); } $cashAppAccount = (string) ($input['cashapp_account'] ?? ''); if ($cashAppAccount !== '' && strpos($cashAppAccount, '$') !== 0) { $cashAppAccount = '$' . $cashAppAccount; } $payload['cashapp_account'] = $cashAppAccount ?: '$unknown'; return $this->service->postPayout('/rest/v2/payouts/cashApp', $payload); } public function resolveBeneficiary(array $input) { $payload = $this->service->buildBeneficiaryPayload($input); $created = $this->service->postPayout('/rest/v2/beneficiaries/create', $payload); if ((int) ($created['code'] ?? 0) === 200 && !empty($created['data']['beneficiary_id'])) { return $created['data']; } if ((int) ($created['code'] ?? 0) !== 4002001) { Util::WriteLog('PayPlus_error', 'beneficiary create failed: ' . json_encode($created)); return false; } $query = $this->service->postPayout('/rest/v2/beneficiaries/query', [ 'payee_id' => $payload['payee_id'], ]); if ((int) ($query['code'] ?? 0) === 200 && !empty($query['data']['beneficiary_id'])) { return $query['data']; } Util::WriteLog('PayPlus_error', 'beneficiary query failed: ' . json_encode($query)); return false; } public function notify($post) { if (!is_array($post)) { $post = json_decode($post, true) ?: []; } $detail = $this->queryPayoutDetailForNotify($post); if (empty($detail)) { return 'success'; } $orderId = $detail['reference_id'] ?? ($post['reference_id'] ?? ''); if ($orderId === '') { return 'success'; } $query = DB::connection('write') ->table('QPAccountsDB.dbo.OrderWithDraw') ->where('OrderId', $orderId) ->first(); if (!$query || ($query->State != 5 && $query->State != 7)) { return 'success'; } $orderStatus = $this->resolvePayoutStatus($detail['transaction_status'] ?? ''); if (!$orderStatus) { return 'success'; } $agent = DB::connection('write')->table('agent.dbo.admin_configs') ->where('config_value', self::AGENT) ->where('type', 'cash') ->select('id') ->first(); $agentId = $agent->id ?? ''; $now = now(); $userId = $query->UserID; $takeMoney = $query->WithDraw + $query->ServiceFee; $withdrawData = [ 'agent' => $agentId, 'finishDate' => $now, ]; if ($orderStatus === 1) { $withdrawData['State'] = 2; $this->handleSuccess($query, $takeMoney); } else { $withdrawData['State'] = 6; $failedMessage = $detail['description'] ?? ($post['msg'] ?? 'REJECTED'); PrivateMail::failMail($userId, $orderId, $takeMoney, $failedMessage, '30000,' . $takeMoney); } DB::connection('write')->table('QPAccountsDB.dbo.AccountsRecord')->updateOrInsert( ['RecordID' => $query->RecordID, 'type' => 1], [ 'before_state' => $query->State, 'after_state' => $withdrawData['State'], 'RecordID' => $query->RecordID, 'update_at' => date('Y-m-d H:i:s'), ] ); DB::connection('write') ->table('QPAccountsDB.dbo.OrderWithDraw') ->where('OrderId', $query->OrderId) ->update($withdrawData); return 'success'; } public function queryPayoutDetailForNotify(array $post) { $transactionId = (string) ($post['transaction_id'] ?? ''); $referenceId = (string) ($post['reference_id'] ?? ''); if ($transactionId === '' && $referenceId === '') { return []; } try { $result = $this->service->queryPayoutOrder($transactionId, $referenceId); } catch (\Exception $exception) { Util::WriteLog('PayPlus_error', 'payout query failed: ' . $exception->getMessage()); return []; } if ((int) ($result['code'] ?? 0) !== 200 || empty($result['data']) || !is_array($result['data'])) { Util::WriteLog('PayPlus_error', 'payout query invalid response: ' . json_encode($result)); return []; } return $result['data']; } public function resolvePayoutStatus($status) { switch (strtoupper((string) $status)) { case 'PAID': return 1; case 'REJECTED': case 'REFUNDED': return 2; default: return 0; } } protected function handleSuccess($query, $takeMoney) { $userId = $query->UserID; $first = DB::connection('write') ->table('QPAccountsDB.dbo.UserTabData') ->where('UserID', $userId) ->first(); if ($first) { DB::connection('write') ->table('QPAccountsDB.dbo.UserTabData') ->where('UserID', $userId) ->increment('TakeMoney', $takeMoney); } else { DB::connection('write') ->table('QPAccountsDB.dbo.UserTabData') ->insert(['TakeMoney' => $takeMoney, 'UserID' => $userId]); PrivateMail::praiseSendMail($userId); } try { StoredProcedure::addPlatformData($userId, 4, $takeMoney); } catch (\Exception $exception) { Util::WriteLog('StoredProcedure', $exception); } RecordUserDataStatistics::updateOrAdd($userId, $takeMoney, 0, $query->ServiceFee); (new RechargeWithDraw())->withDraw($userId, $takeMoney, 0, $query->ServiceFee); Redis::connection()->incr('draw_' . date('Ymd') . $userId); PrivateMail::successMail($userId, $query->OrderId, $takeMoney); StoredProcedure::user_label($userId, 2, $takeMoney); } }