accountSid = getSetting('twilio_account_sid', 'YOUR_TWILIO_ACCOUNT_SID'); $this->authToken = getSetting('twilio_auth_token', 'YOUR_TWILIO_AUTH_TOKEN'); $this->fromNumber = getSetting('twilio_phone_number', '+1234567890'); } /** * Send SMS via Twilio API */ public function send(string $to, string $message): array { // Ensure phone number is in E.164 format $to = $this->formatPhoneNumber($to); if (!$to) { return ['success' => false, 'error' => 'Invalid phone number']; } $url = "https://api.twilio.com/2010-04-01/Accounts/{$this->accountSid}/Messages.json"; $data = [ 'To' => $to, 'From' => $this->fromNumber, 'Body' => $message ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($data), CURLOPT_USERPWD => "{$this->accountSid}:{$this->authToken}", CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error) { return ['success' => false, 'error' => $error]; } $result = json_decode($response, true); if ($httpCode >= 200 && $httpCode < 300) { return [ 'success' => true, 'sid' => $result['sid'] ?? null, 'status' => $result['status'] ?? 'queued' ]; } return [ 'success' => false, 'error' => $result['message'] ?? 'Failed to send SMS', 'code' => $result['code'] ?? $httpCode ]; } /** * Format phone number to E.164 format */ private function formatPhoneNumber(string $phone): ?string { // Remove all non-numeric characters except + $phone = preg_replace('/[^0-9+]/', '', $phone); // If already in E.164 format if (preg_match('/^\+[1-9]\d{1,14}$/', $phone)) { return $phone; } // US number without country code if (preg_match('/^1?\d{10}$/', $phone)) { $phone = preg_replace('/^1?/', '', $phone); return '+1' . $phone; } return null; } /** * Send order confirmation SMS */ public function sendOrderConfirmation(array $order, string $phone): array { $message = "Tom's Java Jive: Your order #{$order['order_number']} has been confirmed! " . "Total: " . formatCurrency($order['total']) . ". " . "Thank you for your purchase!"; return $this->send($phone, $message); } /** * Send shipping notification SMS */ public function sendShippingNotification(array $order, string $phone): array { $message = "Tom's Java Jive: Your order #{$order['order_number']} has shipped! " . "Tracking: {$order['tracking_number']}. " . "Track at: " . ($order['tracking_url'] ?? SITE_URL); return $this->send($phone, $message); } /** * Send delivery notification SMS */ public function sendDeliveryNotification(array $order, string $phone): array { $message = "Tom's Java Jive: Great news! Your order #{$order['order_number']} " . "has been delivered. Enjoy your coffee!"; return $this->send($phone, $message); } /** * Send password reset SMS */ public function sendPasswordResetCode(string $phone, string $code): array { $message = "Tom's Java Jive: Your password reset code is {$code}. " . "This code expires in 15 minutes. Don't share it with anyone."; return $this->send($phone, $message); } /** * Send OTP verification SMS */ public function sendVerificationCode(string $phone, string $code): array { $message = "Tom's Java Jive: Your verification code is {$code}. " . "Valid for 10 minutes."; return $this->send($phone, $message); } /** * Send promotional SMS (with opt-out info) */ public function sendPromotion(string $phone, string $promoMessage): array { $message = "Tom's Java Jive: {$promoMessage} " . "Reply STOP to unsubscribe."; return $this->send($phone, $message); } /** * Send order ready for pickup SMS */ public function sendReadyForPickup(array $order, string $phone): array { $message = "Tom's Java Jive: Your order #{$order['order_number']} is ready for pickup! " . "Show this message at the counter."; return $this->send($phone, $message); } /** * Send low wallet balance alert */ public function sendLowBalanceAlert(string $phone, float $balance): array { $message = "Tom's Java Jive: Your wallet balance is " . formatCurrency($balance) . ". " . "Top up now to continue enjoying fast checkout!"; return $this->send($phone, $message); } /** * Send loyalty tier upgrade notification */ public function sendTierUpgrade(string $phone, string $tierName): array { $message = "Tom's Java Jive: Congratulations! You've reached {$tierName} status! " . "Enjoy your new benefits and rewards. Thank you for being a loyal customer!"; return $this->send($phone, $message); } } // Helper function for easy access function sendSMS(): TwilioSMS { static $instance = null; if ($instance === null) { $instance = new TwilioSMS(); } return $instance; }