PHP Integration
Complete guide to integrate NestSMS into your PHP applications with practical examples using cURL for sending SMS, handling responses, and tracking delivery status.
Setup
Environment Variables
Create a .env file or use php.ini:
<?php
// config.php
define('NESTSMS_API_KEY', 'nsms_live_your_api_key_here');
define('NESTSMS_BASE_URL', 'https://api.nestsms.com/api/v1');
define('NESTSMS_SENDER_ID', 'YourBrand');
?>PHP Examples
Send SMS
<?php
// send_sms.php
require_once 'config.php';
function sendSMS($phoneNumber, $message, $senderName = 'YourBrand') {
$url = NESTSMS_BASE_URL . '/sms/send';
$data = array(
'to' => $phoneNumber,
'message' => $message,
'sender_id' => $senderName,
'message_type' => 'transactional'
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-API-Key: ' . NESTSMS_API_KEY,
'Content-Type: application/json'
));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 200 && $result['success']) {
echo "✓ SMS sent successfully!\n";
echo "Job ID: " . $result['job_id'] . "\n";
echo "Cost: " . $result['cost'] . "\n";
return $result;
} else {
echo "✗ Error: " . $result['error'] . "\n";
echo "Code: " . $result['code'] . "\n";
return false;
}
}
// Usage
sendSMS('9840123456', 'Hello from NestSMS API!');
?>Send Bulk SMS
<?php
// send_bulk_sms.php
function sendBulkSMS($recipients, $message, $senderName = 'YourBrand') {
if (!is_array($recipients) || count($recipients) > 1000) {
die("Recipients must be an array (max 1000)\n");
}
$url = NESTSMS_BASE_URL . '/sms/send';
$data = array(
'to' => $recipients,
'message' => $message,
'sender_id' => $senderName,
'message_type' => 'promotional'
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-API-Key: ' . NESTSMS_API_KEY,
'Content-Type: application/json'
));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 200 && $result['success']) {
echo "✓ Bulk SMS sent to " . $result['recipients_count'] . " recipients\n";
echo "Total cost: " . $result['cost'] . "\n";
return $result;
} else {
echo "✗ Error: " . $result['error'] . "\n";
return false;
}
}
// Usage
$recipients = array('9840123456', '9851234567', '9861345678');
sendBulkSMS($recipients, 'Special offer! Get 50% off today.');
?>Check SMS Status
<?php
// check_status.php
function checkSMSStatus($messageId) {
$url = NESTSMS_BASE_URL . '/sms/status/' . $messageId;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-API-Key: ' . NESTSMS_API_KEY
));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 200 && $result['success']) {
echo "Status: " . $result['status'] . "\n";
echo "Sent at: " . $result['sent_at'] . "\n";
echo "Delivered at: " . ($result['delivered_at'] ?? 'N/A') . "\n";
return $result;
} else {
echo "✗ Error: " . $result['error'] . "\n";
return false;
}
}
// Usage
checkSMSStatus('550e8400-e29b-41d4-a716-446655440000');
?>Get Account Balance
<?php
// get_balance.php
function getBalance() {
$url = NESTSMS_BASE_URL . '/sms/balance';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-API-Key: ' . NESTSMS_API_KEY
));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 200 && $result['success']) {
echo "Balance: " . $result['balance'] . " " . $result['currency'] . "\n";
echo "SMS sent today: " . $result['sms_sent_today'] . "\n";
echo "SMS sent this month: " . $result['sms_sent_this_month'] . "\n";
return $result;
} else {
echo "✗ Error: " . $result['error'] . "\n";
return false;
}
}
// Usage
getBalance();
?>PHP Client and Framework Integration
Complete PHP Client Class
<?php
// NestSMSClient.php
class NestSMSClient {
private $apiKey;
private $baseUrl;
public function __construct($apiKey, $baseUrl = 'https://api.nestsms.com/api/v1') {
$this->apiKey = $apiKey;
$this->baseUrl = $baseUrl;
}
public function sendSMS($to, $message, $options = array()) {
$url = $this->baseUrl . '/sms/send';
$data = array_merge(array(
'to' => $to,
'message' => $message,
'sender_id' => 'YourBrand',
'message_type' => 'transactional'
), $options);
return $this->makeRequest('POST', $url, $data);
}
public function sendBulkSMS($recipients, $message, $options = array()) {
if (!is_array($recipients) || count($recipients) > 1000) {
throw new Exception('Recipients must be an array (max 1000)');
}
$url = $this->baseUrl . '/sms/send';
$data = array_merge(array(
'to' => $recipients,
'message' => $message,
'sender_id' => 'YourBrand',
'message_type' => 'promotional'
), $options);
return $this->makeRequest('POST', $url, $data);
}
public function checkStatus($messageId) {
$url = $this->baseUrl . '/sms/status/' . $messageId;
return $this->makeRequest('GET', $url);
}
public function getBalance() {
$url = $this->baseUrl . '/sms/balance';
return $this->makeRequest('GET', $url);
}
private function makeRequest($method, $url, $data = null) {
$ch = curl_init($url);
$headers = array(
'X-API-Key: ' . $this->apiKey,
'Content-Type: application/json'
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new Exception('cURL Error: ' . $error);
}
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode >= 400) {
throw new Exception(
'API Error (' . $httpCode . '): ' .
($result['error'] ?? 'Unknown error') .
' [' . ($result['code'] ?? 'N/A') . ']'
);
}
return $result;
}
}
// Usage Example
$client = new NestSMSClient(NESTSMS_API_KEY);
try {
// Send SMS
$result = $client->sendSMS('9840123456', 'Hello from PHP!');
print_r($result);
// Get balance
$balance = $client->getBalance();
print_r($balance);
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
?>Laravel Configuration
<?php
// config/nestsms.php
return [
'api_key' => env('NESTSMS_API_KEY'),
'base_url' => env('NESTSMS_BASE_URL', 'https://api.nestsms.com/api/v1'),
'sender_id' => env('NESTSMS_SENDER_ID', 'YourBrand'),
];
?>Laravel Service Class
<?php
// app/Services/SMSService.php
namespace App\Services;
use Illuminate\Support\Facades\Http;
class SMSService {
protected $apiKey;
protected $baseUrl;
protected $senderId;
public function __construct() {
$this->apiKey = config('nestsms.api_key');
$this->baseUrl = config('nestsms.base_url');
$this->senderId = config('nestsms.sender_id');
}
public function sendSMS($phoneNumber, $message, $messageType = 'transactional') {
$response = Http::withHeaders([
'X-API-Key' => $this->apiKey,
'Content-Type' => 'application/json'
])->post($this->baseUrl . '/sms/send', [
'to' => $phoneNumber,
'message' => $message,
'sender_id' => $this->senderId,
'message_type' => $messageType
]);
if ($response->failed()) {
throw new \Exception('Failed to send SMS: ' . $response->json('error'));
}
return $response->json();
}
public function sendBulkSMS($recipients, $message) {
if (!is_array($recipients) || count($recipients) > 1000) {
throw new \Exception('Recipients must be an array (max 1000)');
}
$response = Http::withHeaders([
'X-API-Key' => $this->apiKey,
'Content-Type' => 'application/json'
])->post($this->baseUrl . '/sms/send', [
'to' => $recipients,
'message' => $message,
'sender_id' => $this->senderId,
'message_type' => 'promotional'
]);
if ($response->failed()) {
throw new \Exception('Failed to send bulk SMS: ' . $response->json('error'));
}
return $response->json();
}
public function checkStatus($messageId) {
$response = Http::withHeaders([
'X-API-Key' => $this->apiKey
])->get($this->baseUrl . '/sms/status/' . $messageId);
if ($response->failed()) {
throw new \Exception('Failed to check status: ' . $response->json('error'));
}
return $response->json();
}
public function getBalance() {
$response = Http::withHeaders([
'X-API-Key' => $this->apiKey
])->get($this->baseUrl . '/sms/balance');
if ($response->failed()) {
throw new \Exception('Failed to get balance: ' . $response->json('error'));
}
return $response->json();
}
}
?>Laravel Controller
<?php
// app/Http/Controllers/SMSController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\SMSService;
class SMSController extends Controller {
protected $smsService;
public function __construct(SMSService $smsService) {
$this->smsService = $smsService;
}
public function send(Request $request) {
$request->validate([
'to' => 'required|string',
'message' => 'required|string|max:720'
]);
try {
$result = $this->smsService->sendSMS(
$request->input('to'),
$request->input('message')
);
return response()->json([
'success' => true,
'job_id' => $result['job_id'],
'cost' => $result['cost']
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'error' => $e->getMessage()
], 500);
}
}
public function bulk(Request $request) {
$request->validate([
'recipients' => 'required|array|max:1000',
'message' => 'required|string|max:720'
]);
try {
$result = $this->smsService->sendBulkSMS(
$request->input('recipients'),
$request->input('message')
);
return response()->json([
'success' => true,
'job_id' => $result['job_id'],
'recipients_count' => $result['recipients_count'],
'cost' => $result['cost']
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'error' => $e->getMessage()
], 500);
}
}
public function status($messageId) {
try {
$result = $this->smsService->checkStatus($messageId);
return response()->json([
'success' => true,
'status' => $result['status'],
'sent_at' => $result['sent_at'],
'delivered_at' => $result['delivered_at'] ?? null
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'error' => $e->getMessage()
], 500);
}
}
}
?>Laravel Routes
<?php
// routes/api.php
use App\Http\Controllers\SMSController;
Route::prefix('sms')->group(function () {
Route::post('/send', [SMSController::class, 'send']);
Route::post('/bulk', [SMSController::class, 'bulk']);
Route::get('/status/{messageId}', [SMSController::class, 'status']);
});
?>OTP Verification
OTP Service
<?php
// OTPService.php
class OTPService {
private $smsClient;
public function __construct($smsClient) {
$this->smsClient = $smsClient;
}
public function generateOTP() {
return str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
}
public function sendOTP($phoneNumber) {
$otp = $this->generateOTP();
// Store OTP in session or database
$_SESSION['otp_' . $phoneNumber] = array(
'code' => $otp,
'expires_at' => time() + 300 // 5 minutes
);
// Send SMS
$message = "Your verification code is $otp. Valid for 5 minutes.";
$result = $this->smsClient->sendSMS(
$phoneNumber,
$message,
array('message_type' => 'otp')
);
return array(
'success' => true,
'job_id' => $result['job_id']
);
}
public function verifyOTP($phoneNumber, $enteredOTP) {
$key = 'otp_' . $phoneNumber;
if (!isset($_SESSION[$key])) {
return array(
'success' => false,
'error' => 'OTP not found or expired'
);
}
$stored = $_SESSION[$key];
if (time() > $stored['expires_at']) {
unset($_SESSION[$key]);
return array(
'success' => false,
'error' => 'OTP expired'
);
}
if ($stored['code'] !== $enteredOTP) {
return array(
'success' => false,
'error' => 'Invalid OTP'
);
}
// Clear OTP after successful verification
unset($_SESSION[$key]);
return array(
'success' => true,
'message' => 'OTP verified successfully'
);
}
}
// Usage
session_start();
$otpService = new OTPService(new NestSMSClient(NESTSMS_API_KEY));
// Send OTP
$otpService->sendOTP('9840123456');
// Verify OTP
$result = $otpService->verifyOTP('9840123456', '123456');
?>Responses and Error Handling
Successful Response
{
"success": true,
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "SMS queued successfully",
"recipients_count": 1,
"cost": 1.5
}Error Response
{
"success": false,
"error": "Insufficient balance",
"code": "INSUFFICIENT_BALANCE"
}Error Handling
<?php
function sendSMSWithRetry($phoneNumber, $message, $maxRetries = 3) {
$attempt = 0;
while ($attempt < $maxRetries) {
try {
$result = sendSMS($phoneNumber, $message);
return $result;
} catch (Exception $e) {
$attempt++;
echo "Attempt $attempt failed: " . $e->getMessage() . "\n";
if ($attempt >= $maxRetries) {
throw new Exception('Max retries exceeded');
}
// Exponential backoff
sleep(pow(2, $attempt));
}
}
}
?>Best Practices
- Never expose API keys in client-side code
- Use environment variables for sensitive data
- Implement proper error handling with try-catch blocks
- Store session data securely (use Redis for production OTP storage)
- Validate phone numbers before sending
- Log SMS activities for audit trails
- Implement rate limiting to prevent abuse