Laravel Fast2SMS v2.0 ships with six opt-in features that help you avoid unnecessary API calls, prevent accidental duplicate sends, and keep your SMS spend under control. All features are disabled by default — enable only what you need.
| Feature | Config key | Env variable(s) | Default | Exception thrown |
|---|---|---|---|---|
| Recipient deduplication | fast2sms.recipients.deduplicate |
FAST2SMS_DEDUP_RECIPIENTS |
true |
— |
| Invalid recipient stripping | fast2sms.validation.strip_invalid_recipients |
FAST2SMS_STRIP_INVALID |
false |
ValidationException (all invalid) |
| Idempotency / dedup guard | fast2sms.deduplication.enabled |
FAST2SMS_DEDUP_ENABLED |
false |
DuplicateSendException |
| Send-rate throttle | fast2sms.throttle.enabled |
FAST2SMS_THROTTLE_ENABLED |
false |
ThrottleExceededException |
| Balance gate | fast2sms.balance_gate.enabled |
FAST2SMS_BALANCE_GATE |
false |
InsufficientBalanceException |
| Batch splitting | fast2sms.recipients.batch_size |
FAST2SMS_BATCH_SIZE |
0 (off) |
— |
Strips duplicate phone numbers from the recipient list before every SMS send. Enabled by default.
// config/fast2sms.php
'recipients' => [
'deduplicate' => env('FAST2SMS_DEDUP_RECIPIENTS', true),
],
FAST2SMS_DEDUP_RECIPIENTS=true
If you pass ['9876543210', '9876543210', '9123456789'], only ['9876543210', '9123456789'] will be sent to the API.
Validates each number against the Fast2smsPhone rule before sending. Invalid numbers are silently removed and a warning is logged. If all numbers are invalid, a ValidationException is thrown.
'validation' => [
'strip_invalid_recipients' => env('FAST2SMS_STRIP_INVALID', false),
],
FAST2SMS_STRIP_INVALID=true
use Shakil\Fast2sms\Exceptions\ValidationException;
try {
Fast2sms::quick(numbers: '9876543210', message: 'Hello!');
} catch (ValidationException $e) {
// All recipients were invalid — nothing was sent
}
Caches a hash of (recipients + message + route) for a configurable TTL. A second identical call within that window throws DuplicateSendException instead of hitting the API again. Also applied to WhatsApp sends.
'deduplication' => [
'enabled' => env('FAST2SMS_DEDUP_ENABLED', false),
'ttl' => env('FAST2SMS_DEDUP_TTL', 60), // seconds
'store' => env('FAST2SMS_DEDUP_STORE', null), // null = default cache store
],
FAST2SMS_DEDUP_ENABLED=true
FAST2SMS_DEDUP_TTL=120
FAST2SMS_DEDUP_STORE=redis
use Shakil\Fast2sms\Exceptions\DuplicateSendException;
try {
Fast2sms::quick(numbers: '9876543210', message: 'Hello!');
} catch (DuplicateSendException $e) {
// Identical send attempted within the dedup window
}
Sliding-window per-minute counter backed by the Laravel cache. Throws ThrottleExceededException when the configured limit is reached. Also applied to WhatsApp sends.
'throttle' => [
'enabled' => env('FAST2SMS_THROTTLE_ENABLED', false),
'max_per_minute' => env('FAST2SMS_THROTTLE_MAX', 60),
'store' => env('FAST2SMS_THROTTLE_STORE', null),
],
FAST2SMS_THROTTLE_ENABLED=true
FAST2SMS_THROTTLE_MAX=30
FAST2SMS_THROTTLE_STORE=redis
use Shakil\Fast2sms\Exceptions\ThrottleExceededException;
try {
Fast2sms::quick(numbers: '9876543210', message: 'Hello!');
} catch (ThrottleExceededException $e) {
// Too many sends in the current minute
}
Checks your Fast2SMS wallet balance before every send. Fires the LowBalanceDetected event and — when abort is true — throws InsufficientBalanceException if the balance is below the threshold. Also applied to WhatsApp sends.
'balance_gate' => [
'enabled' => env('FAST2SMS_BALANCE_GATE', false),
'threshold' => env('FAST2SMS_BALANCE_THRESHOLD', 10.0),
'abort' => env('FAST2SMS_BALANCE_ABORT', true),
],
FAST2SMS_BALANCE_GATE=true
FAST2SMS_BALANCE_THRESHOLD=25.0
FAST2SMS_BALANCE_ABORT=true
use Shakil\Fast2sms\Exceptions\InsufficientBalanceException;
try {
Fast2sms::quick(numbers: '9876543210', message: 'Hello!');
} catch (InsufficientBalanceException $e) {
// Wallet balance is below the configured threshold
}
Set FAST2SMS_BALANCE_ABORT=false to fire LowBalanceDetected as a warning without blocking the send:
FAST2SMS_BALANCE_GATE=true
FAST2SMS_BALANCE_ABORT=false
Splits large recipient lists into chunks and issues one API call per chunk. Set batch_size to 0 to disable (all recipients in a single call).
'recipients' => [
'batch_size' => env('FAST2SMS_BATCH_SIZE', 0),
],
FAST2SMS_BATCH_SIZE=50
With batch_size=50 and 120 recipients, the package will make three API calls: 50 + 50 + 20.
SmsMessage exposes helper methods for pre-send cost estimation:
$msg = SmsMessage::create('Hello! Your OTP is 123456.');
$msg->charCount(); // int — number of characters
$msg->isUnicode(); // bool — true if message contains non-GSM characters
$msg->creditCount(); // int — estimated SMS credits consumed
$msg->exceedsOneSms(); // bool — true if message spans more than one SMS part
# Recipient safety
FAST2SMS_DEDUP_RECIPIENTS=true
FAST2SMS_STRIP_INVALID=true
# Idempotency (requires a persistent cache store)
FAST2SMS_DEDUP_ENABLED=true
FAST2SMS_DEDUP_TTL=60
FAST2SMS_DEDUP_STORE=redis
# Rate limiting
FAST2SMS_THROTTLE_ENABLED=true
FAST2SMS_THROTTLE_MAX=60
FAST2SMS_THROTTLE_STORE=redis
# Balance protection
FAST2SMS_BALANCE_GATE=true
FAST2SMS_BALANCE_THRESHOLD=10.0
FAST2SMS_BALANCE_ABORT=true
# Batch splitting (0 = disabled)
FAST2SMS_BATCH_SIZE=0
How can I help you explore Laravel packages today?