PHPackages                             alexgeno/phone-verification - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. alexgeno/phone-verification

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

alexgeno/phone-verification
===========================

An extensible and configurable php library for phone verification

v1.0.6(2y ago)65.8k[1 issues](https://github.com/alexeygeno/phone-verification-php/issues)2MITPHPPHP &gt;=7.4

Since Apr 26Pushed 2y ago1 watchersCompare

[ Source](https://github.com/alexeygeno/phone-verification-php)[ Packagist](https://packagist.org/packages/alexgeno/phone-verification)[ Docs](https://github.com/alexeygeno/phone-verification-php)[ RSS](/packages/alexgeno-phone-verification/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (11)Versions (8)Used By (2)

Phone Verification
==================

[](#phone-verification)

[![Build Status](https://github.com/alexeygeno/phone-verification-php/workflows/Tests/badge.svg)](https://github.com/alexeygeno/phone-verification-php/actions/workflows/tests.yml)[![Build Status](https://github.com/alexeygeno/phone-verification-php/workflows/PHPStan/badge.svg)](https://github.com/alexeygeno/phone-verification-php/actions/workflows/phpstan.yml)[![Build Status](https://github.com/alexeygeno/phone-verification-php/workflows/CodeSniffer/badge.svg)](https://github.com/alexeygeno/phone-verification-php/actions/workflows/cs.yml)[![Coverage Status](https://camo.githubusercontent.com/0267e3aee8fac854758543121b7df05e8f0852c35befcc8727a499383ee81b05/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f616c6578657967656e6f2f70686f6e652d766572696669636174696f6e2d7068702f62616467652e737667)](https://coveralls.io/github/alexeygeno/phone-verification-php)

Signing in or signing up on a modern website or mobile app typically follows these steps:

- A user initiates verification by submitting a phone number
- The user receives an SMS or a call with a one-time password [(OTP)](https://en.wikipedia.org/wiki/One-time_password)
- The user completes verification by submitting the [OTP](https://en.wikipedia.org/wiki/One-time_password)

This extensible and configurable library allows to set this up just with a few lines of code

Requirements
------------

[](#requirements)

- Supported PHP versions: 7.4, 8.0, 8.1, 8.2
- [ Composer](https://getcomposer.org/)
- Any of the supported sender SDKs: [twilio/sdk](https://github.com/twilio/twilio-php), [messagebird/php-rest-api](https://github.com/messagebird/php-rest-api), [vonage/client](https://github.com/vonage/vonage-php-sdk-core)
- Any of the supported storage clients: [predis/predis](https://github.com/predis/predis), [mongodb/mongo-php-library](https://github.com/mongodb/mongo-php-library)

Installation
------------

[](#installation)

```
composer require alexgeno/phone-verification
```

**Note:** All supported storage clients and sender SDKs are in **require-dev** section. In a production environment you must manually install only what you use.

Basic Usage
-----------

[](#basic-usage)

### Instantiation

[](#instantiation)

[ Predis](https://github.com/predis/predis) as a **storage** and [ Twilio](https://github.com/twilio/twilio-php) as a **sender** are used for the demonstration

```
use AlexGeno\PhoneVerification\Storage\Redis;
use AlexGeno\PhoneVerification\Sender\Twilio;
use AlexGeno\PhoneVerification\Manager;

$storage = new Redis(new \Predis\Client('tcp://127.0.0.1:6379'));
$sender = new Twilio(new \Twilio\Rest\Client('ACXXXXXX', 'YYYYYY'), ['from' => '+442077206312']);
$manager = new Manager($storage);
```

### There are two stages in the verification process

[](#there-are-two-stages-in-the-verification-process)

**Initiation** - a **storage** and a **sender** are required for this stage. A user submits a phone and as a result receives an [otp](https://en.wikipedia.org/wiki/One-time_password)

```
$manager->sender($sender)->initiate('+15417543010');
```

**Completion** - only a storage is required for this stage. The user submits the [ otp](https://en.wikipedia.org/wiki/One-time_password) to verify the phone

```
$manager->complete('+15417543010', 1234);
```

That's basically it. More advanced usage including **otp length customization**, **rate limiters**, **messages customization** you can derive from the following sections.

Demo
----

[](#demo)

**Initiation**

```
php example/initiate.php --storage redis --sender messageBird --to +15417543010
```

**Completion**

```
php example/complete.php --storage redis --to +15417543010 --otp 1111
```

**Note**: See [DEVELOPMENT.md](DEVELOPMENT.md) as an option for how to set up a development environment

Extending
---------

[](#extending)

To add a new **sender** just create a new class

```
namespace AlexGeno\PhoneVerification\Sender;

class Plivo implements I
{
    //...
}
```

To add a new **storage** just create a new class

```
namespace AlexGeno\PhoneVerification\Storage;

class DynamoDb implements I
{
    //...
}
```

Advanced usage
--------------

[](#advanced-usage)

Rate limit params and otp params might be customized

**Initiation**

```
use AlexGeno\PhoneVerification\Storage\Redis;
use AlexGeno\PhoneVerification\Sender\Twilio;
use AlexGeno\PhoneVerification\Manager;
use AlexGeno\PhoneVerification\Exception\RateLimit;

$config = [
    'rate_limits' => [
        'initiate' => [
            'period_secs' => 86400,
            'count' => 10,
            'message' =>
                fn($phone, $periodSecs, $count) =>
                    sprintf('You can send only %d sms in %d hours.', $count, $periodSecs / 60 / 60)
        ]
    ],
    'otp' => [
        'length' => 4, // 1000..9999
        'message' =>  fn($otp) => sprintf('Your code is %d', $otp) // The text a user receives
    ]
];

$storage = new Redis(new \Predis\Client('tcp://127.0.0.1:6379'));
$sender = new Twilio(new \Twilio\Rest\Client('ACXXXXXX', 'YYYYYY'), ['from' => '+442077206312']);

try {
    (new Manager($storage, $config))->sender($sender)->initiate('+15417543010');
} catch (RateLimit $e) {
    echo $e->getMessage(); // 'You can send only 10 sms in 24 hours'
}
```

**Completion**

```
use AlexGeno\PhoneVerification\Storage\Redis;
use AlexGeno\PhoneVerification\Manager;
use AlexGeno\PhoneVerification\Exception\RateLimit;
use AlexGeno\PhoneVerification\Exception\Otp;

$config = [
    'rate_limits' => [
        'complete' => [
            'period_secs' => 300,
            'count' => 5,
            'message' =>
                fn($phone, $periodSecs, $count) =>
                    sprintf('You are trying to use an incorrect code %d times in %d minutes', $count, $periodSecs / 60)
        ]
    ],
    'otp' => [
        'message_expired' =>
            fn($periodSecs, $otp) =>
                sprintf('Code is expired. You have only %d minutes to use it.', $periodSecs / 60),
        'message_incorrect' =>  fn($otp) => 'Code is incorrect'
    ]
];
$storage = new Redis(new \Predis\Client('tcp://127.0.0.1:6379'));

try {
    (new Manager($storage, $config))->complete('+15417543010', 1234);
} catch (RateLimit | Otp $e) {
    // 'Code is incorrect' ||
    // 'Code is expired. You have only 5 minutes to use it.' ||
    // 'You are trying to use an incorrect code 5 times in 5 minutes'
    echo $e->getMessage();
}
```

**Note:** Of course, you can define all **$config** options and instantiate all classes at the same place in your code. It is split here just to make it more clear what belongs to **the initiation stage** and what to **the completion stage**
**Note:** Each **$config** option has a default value. You should redefine only what you need.

### MongoDb indexes

[](#mongodb-indexes)

If you use MongoDb as a **storage** you may have noticed that the expiration functionality is based on indexes. They can be created automatically. It's recommended though to use this option only in a non-production environment. It's disabled by default.

```
use AlexGeno\PhoneVerification\Storage\MongoDb;

$storage = new MongoDb(new \MongoDB\Client('mongodb://127.0.0.1:27017'), ['indexes'=> true]);
```

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md)

Development
-----------

[](#development)

See [DEVELOPMENT.md](DEVELOPMENT.md) as an option for how to set up a development environment

Licence
-------

[](#licence)

The code for **Phone Verification** is distributed under the terms of the [MIT](LICENSE.txt) license.

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance17

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~14 days

Total

7

Last Release

973d ago

PHP version history (2 changes)v1.0.0PHP &gt;=7.4,&lt;8.3

v1.0.1PHP &gt;=7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/de16405efe763dfcc146024181c9d084b83044f9a3225a11405819737e866edb?d=identicon)[alexgeno](/maintainers/alexgeno)

---

Top Contributors

[![alexeygeno](https://avatars.githubusercontent.com/u/742557?v=4)](https://github.com/alexeygeno "alexeygeno (73 commits)")

---

Tags

2famessage-birdmongodbotpotp-verificationphonephpredissmstwilioverificationverifyvonageotpAuthenticationverify2faredisphonesmstwiliosigninmongovonageverificationsignup2factorcallverify-by-phonemessagebird

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/alexgeno-phone-verification/health.svg)

```
[![Health](https://phpackages.com/badges/alexgeno-phone-verification/health.svg)](https://phpackages.com/packages/alexgeno-phone-verification)
```

###  Alternatives

[alexgeno/phone-verification-laravel

A library for phone verification via Laravel notification channels. Any notification channel can be used as a sender, and Redis or MongoDB can be used as a storage.

112.4k](/packages/alexgeno-phone-verification-laravel)[rinvex/authy

Rinvex Authy is a simple wrapper for Authy TOTP API, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest API for developers and a strong authentication platform for the enterprise.

35188.4k1](/packages/rinvex-authy)[rinvex/laravel-authy

Rinvex Authy is a simple wrapper for Authy TOTP, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest API for developers and a strong authentication platform for the enterprise.

3376.7k1](/packages/rinvex-laravel-authy)[ellaisys/aws-cognito

AWS Cognito package that allows Auth and other related features using the AWS SDK for PHP

120220.7k1](/packages/ellaisys-aws-cognito)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
