config = $square_config; // Initialize Square client $this->square_client = new SquareClient([ 'accessToken' => $this->config['square']['access_token'], 'environment' => $this->config['square']['environment'] === 'production' ? Environment::PRODUCTION : Environment::SANDBOX ]); } public function createDonation($streamer_id, $amount, $donor_name = '', $message = '') { try { $this->validateAmount($amount); $payment = $this->createSquarePayment($streamer_id, $amount, $donor_name, $message); if ($payment->isSuccess()) { $this->recordDonation($streamer_id, $amount, $donor_name, $message, $payment->getResult()->getPayment()->getId()); return [ 'success' => true, 'payment_id' => $payment->getResult()->getPayment()->getId(), 'message' => 'Donation processed successfully' ]; } return [ 'success' => false, 'message' => 'Failed to process donation: ' . $payment->getErrors()[0]->getDetail() ]; } catch (\Exception $e) { return [ 'success' => false, 'message' => 'Error processing donation: ' . $e->getMessage() ]; } } private function validateAmount($amount) { if ($amount < $this->config['square']['min_donation'] || $amount > $this->config['square']['max_donation']) { throw new \Exception('Invalid donation amount'); } } private function createSquarePayment($streamer_id, $amount, $donor_name, $message) { $money = new Money(); $money->setAmount($amount * 100); // Convert to cents $money->setCurrency($this->config['square']['currency']); $payment_request = new CreatePaymentRequest(); $payment_request->setSourceId('EXTERNAL'); $payment_request->setAmountMoney($money); $payment_request->setLocationId($this->config['square']['location_id']); // Add metadata $payment_request->setMetadata([ 'streamer_id' => $streamer_id, 'donor_name' => $donor_name, 'message' => $message ]); return $this->square_client->getPaymentsApi()->createPayment($payment_request); } private function recordDonation($streamer_id, $amount, $donor_name, $message, $payment_id) { $sql = "INSERT INTO donations ( streamer_id, amount, donor_name, message, payment_id, status, created_at ) VALUES (?, ?, ?, ?, ?, 'completed', NOW())"; $params = [$streamer_id, $amount, $donor_name, $message, $payment_id]; db()->executeQuery($sql, $params); // Update streamer's balance $sql = "UPDATE users SET donation_balance = donation_balance + ? WHERE user_id = ?"; db()->executeQuery($sql, [$amount, $streamer_id]); } public function getStreamerBalance($streamer_id) { $sql = "SELECT donation_balance FROM users WHERE user_id = ?"; $result = db()->getRow($sql, [$streamer_id]); return $result['donation_balance'] ?? 0; } public function requestPayout($streamer_id) { try { $balance = $this->getStreamerBalance($streamer_id); if ($balance < $this->config['streamer']['min_balance']) { return [ 'success' => false, 'message' => 'Insufficient balance for payout' ]; } $payout = $this->createSquarePayout($streamer_id, $balance); if ($payout->isSuccess()) { $this->recordPayout($streamer_id, $balance, $payout->getResult()->getPayout()->getId()); return [ 'success' => true, 'message' => 'Payout processed successfully', 'amount' => $balance ]; } return [ 'success' => false, 'message' => 'Failed to process payout: ' . $payout->getErrors()[0]->getDetail() ]; } catch (\Exception $e) { return [ 'success' => false, 'message' => 'Error processing payout: ' . $e->getMessage() ]; } } private function createSquarePayout($streamer_id, $amount) { // Calculate fees $fee_amount = ($amount * ($this->config['streamer']['payout_fee'] / 100)) + $this->config['streamer']['payout_fee_fixed']; $payout_amount = $amount - $fee_amount; return $this->square_client->getPayoutsApi()->createPayout([ 'amount_money' => [ 'amount' => $payout_amount * 100, // Convert to cents 'currency' => $this->config['square']['currency'] ], 'location_id' => $this->config['square']['location_id'] ]); } private function recordPayout($streamer_id, $amount, $payout_id) { // Calculate fees $fee_amount = ($amount * ($this->config['streamer']['payout_fee'] / 100)) + $this->config['streamer']['payout_fee_fixed']; $payout_amount = $amount - $fee_amount; // Record payout $sql = "INSERT INTO payouts ( streamer_id, amount, fee, payout_id, status, created_at ) VALUES (?, ?, ?, ?, 'completed', NOW())"; $params = [$streamer_id, $payout_amount, $fee_amount, $payout_id]; db()->executeQuery($sql, $params); // Reset streamer's balance $sql = "UPDATE users SET donation_balance = 0 WHERE user_id = ?"; db()->executeQuery($sql, [$streamer_id]); } public function getDonationHistory($streamer_id, $limit = 10) { $sql = "SELECT d.*, u.username as streamer_name FROM donations d JOIN users u ON d.streamer_id = u.user_id WHERE d.streamer_id = ? ORDER BY d.created_at DESC LIMIT ?"; return db()->getRows($sql, [$streamer_id, $limit]); } }