SMSFactor for SMS Framework - 3.0.x
==================================

Supported dependencies
----------------------
Drupal ^10.6 || ^11.4; PHP >=8.1, or >=8.3 on Drupal 11.
SMS Framework ^2.3 || ^3.0@alpha; Guzzle ^7.0; ext-json.

The gateway implements the typed Framework 3 contract, also tested unchanged
with Framework 2.3.0 and 2.4.0. Drupal 10 uses Framework 2.3; Framework 2.4 and
3.0.0-alpha1 require Drupal 11/PHP 8.3. Framework 3 requires explicit prerelease
permission in the ROOT project's Composer requirements. Stable installations
can keep Framework 2.3/2.4 without changing global minimum-stability.
Framework 3 uses the new attribute; Framework 2 still requires the annotation.
There is one implementation of the gateway, with no version-dependent logic.

Framework 4 replaces this contract with Symfony Notifier/Texter and is excluded;
it requires a separate configuration/consumer migration. The tested Framework
releases do not allow Drupal 12. Drupal 12 is NOT declared or runtime verified.

Configuration and breaking changes
----------------------------------
Plugin ID smsfactor and the token configuration key are unchanged. Existing
gateway entities keep their token. Authentication now uses Authorization: Bearer,
as documented by the provider; the token is no longer placed in the JSON body.

Breaking: older Drupal/PHP/Framework releases are excluded. The constructor now
requires a Guzzle ClientInterface (normally supplied by the plugin manager).
Raw cURL is replaced with the injected Drupal HTTP client. An HTTP success alone
is insufficient: status must be 1 and sent must be 1 for QUEUED. Filtered/invalid
recipients, missing fields, malformed JSON and non-2xx responses fail explicitly.
Transaction errors and recipient reports are consistent. Extra recipients are
rejected rather than silently ignored. No tokens, remote bodies, or exception
messages are logged or returned. QUEUED does not claim final delivery.

No automatic retry is implemented. In particular provider status -8 and network
timeouts may occur after acceptance; check provider history before resubmitting.
Redirects are disabled; connect and total timeouts are 5 and 30 seconds.

Verification
------------
tests/src/Unit/SMSFactorGatewayTest.php covers discovery, injected HTTP transport,
exact request/auth payload, queued response, filtered recipients, status -8,
HTTP failures, malformed JSON, network failures, defaults and recipient limits.
All requests use Guzzle MockHandler; no provider connection or SMS is made.
With Drupal/core-dev and dependencies installed:
  vendor/bin/phpunit -c core/phpunit.xml.dist modules/contrib/sms_smsfactor/tests
Rebuild caches after deployment. Live credentials, delivery, configuration forms
and site integration still require staging validation. No config update hook is
needed because existing settings keys remain unchanged.

References
----------
https://www.drupal.org/project/smsframework
https://dev.smsfactor.com/en/api/sms/send/send-campaign
