php
PHP 8.3 implementation of the aice-otp channel contract: Channel interface, typed SendException hierarchy, recipient validator, MockChannel reference, and a YAML conformance harness.
git@gitlab.com:aice-lab/otp/php.git
Latest release
v1.0.0 ·
README
aice-otp — PHP
PHP 8.3+ implementation of the aice-otp channel contract. Defines the abstract delivery interface that every concrete OTP provider adapter (SMS, WhatsApp, email) implements, plus a mock channel and a vector-driven conformance harness.
This release covers the abstract interface and the in-process mock provider. Concrete provider adapters (vendor-specific SMS/email APIs) live in downstream projects that import this package.
Status
- Contract: aice-otp/spec
- Pre-1.0 — public API may change between minor versions until 1.0.0.
Install
composer require aice-lab/otp
Requires PHP 8.3 or newer.
Quickstart
use AiceLab\Otp\{Channel, ChannelKind, SendRequest};
use AiceLab\Otp\Mock\MockChannel;
$channel = new MockChannel(); // swap for a concrete adapter in production
$response = $channel->send(new SendRequest(
channel: ChannelKind::Sms,
recipient: '+8801712345678',
code: '123456',
locale: 'en-US',
));
echo $response->deliveryId, ' ', $response->status->value, "\n";
Each typed Send*Exception corresponds 1:1 to a spec error code (invalid_recipient, rate_limited, provider_unavailable, quota_exceeded, unsupported_locale, internal_error). RateLimitedException exposes retryAfterSeconds when the provider sets it.
Implementing a provider
Implement the AiceLab\Otp\Channel interface and throw the appropriate typed exception on failure:
final class MyProviderChannel implements Channel
{
public function send(SendRequest $req): SendResponse
{
Validator::validate($req);
// ... call provider HTTP API ...
return new SendResponse(
deliveryId: $providerId,
status: SendStatus::Accepted,
providerMetadata: ['vendor' => 'my-provider'],
);
}
}
Run the conformance harness to verify your adapter matches the contract:
$vectors = (new VectorLoader())->load(__DIR__ . '/path/to/vectors');
$results = (new Runner())->run(new MyProviderChannel(), $vectors);
Development
composer install
composer test # phpunit
composer coverage # phpunit + clover xml + text summary
composer analyse # phpstan level 9
composer lint # php-cs-fixer dry-run
Coverage floor: 90% lines on src/.
License
Source: FSL-1.1-Apache-2.0 (see LICENSE and LICENSE.FAQ.md).
Documentation
Full contract and concept docs: https://otp.aice-lab.org
Contributing
See CONTRIBUTING.md. All commits require DCO sign-off (git commit -s).
Reporting security issues
See SECURITY.md. Do not open public issues for vulnerabilities.
This is a snapshot generated from GitLab. For the live README, see the project page.