Reference for implementing a custom SMS transport.
For the basic SMS OTP setup (configuration, controller actions, phone enrollment) see sms_verification.md.
Every SMS transport must implement CakeVerification\Transport\Sms\TransportInterface:
namespace CakeVerification\Transport\Sms;
interface TransportInterface
{
public function send(Message $message): Result;
}| Property | Type | Description |
|---|---|---|
$recipient |
string |
Destination phone number (E.164 recommended) |
$body |
string |
Full message text including the OTP code |
$sender |
string|null |
Sender ID or number (optional) |
| Property | Type | Description |
|---|---|---|
$success |
bool |
true if the message was accepted by the provider |
$error |
string|null |
Error description on failure |
$message |
Message|null |
The original message |
$providerId |
string|null |
Provider-assigned message ID |
$statusCode |
int|null |
HTTP or provider status code |
$retryAfter |
int|null |
Seconds to wait before retrying (rate-limit hint) |
namespace App\Sms;
use CakeVerification\Transport\Sms\Message;
use CakeVerification\Transport\Sms\Result;
use CakeVerification\Transport\Sms\TransportInterface;
class TwilioTransport implements TransportInterface
{
public function __construct(private array $options = []) {}
public function send(Message $message): Result
{
$result = new Result();
// call Twilio API with $message->recipient and $message->body ...
$result->success = true;
$result->providerId = 'twilio-message-id';
return $result;
}
}If the transport constructor requires no arguments, it is instantiated directly.
If it requires one argument, the options array from the transport config is passed.
// config/verification.php
'sms' => [
'defaultTransport' => 'twilio',
'transports' => [
'twilio' => [
'className' => \App\Sms\TwilioTransport::class,
'options' => [
'sid' => env('TWILIO_SID'),
'token' => env('TWILIO_TOKEN'),
'from' => env('TWILIO_FROM'),
],
],
],
],The plugin ships a DummyTransport that logs the message and stores it in the
CakePHP default cache instead of sending a real SMS. Use it during development:
'sms' => [
'defaultTransport' => 'dummy',
],VerificationHelper::lastSmsCode() reads the cached message and returns the
numeric code — convenient for checking the OTP without a real phone.
See ../verification_helper.md.
Full documentation index: ../index.md