hooman-mirghasemi/laravel-iran-sms
Laravel package for integrating Iranian SMS providers into your application. It offers a simple, unified API for sending messages, configurable gateways, and easy setup so you can add SMS notifications, OTP codes, and transactional messaging to Laravel apps.
Architecture fit. This package sits in the notification/messaging layer of a Laravel application, wrapping an SMS gateway (Ghasedak) behind what is presumably a Laravel service provider, facade, and notification channel. Removing the ghasedak Composer dependency in favour of a first-party implementation does not change where the package sits in the architecture, but it does change what the package is responsible for. Previously the package was an adapter; it now owns the HTTP contract, request signing, endpoint URLs, and response parsing for the provider. That is a meaningful increase in the package's own surface area and a corresponding increase in the blast radius of any provider-side change.
Integration feasibility. The integration seam should remain stable if the package preserved its public API — config keys, facade methods, notification channel class, and any DTOs or events. The release is versioned as a patch (1.4.2), which implies the maintainer considers this non-breaking. Treat that claim as unverified. Concretely, the following may have shifted without a major version bump: configuration key names or nesting (base URL, endpoint paths, credentials shape), exception class names and hierarchy, response object properties, timeout/retry defaults, and whether HTTP calls now go through Laravel's Http client (and therefore respect Http::fake() in tests) rather than the vendor SDK's own transport. That last point is the most likely to break existing test suites silently.
Technical risk. Three risks dominate. First, behavioural drift: a reimplementation of "all APIs" is unlikely to be byte-for-byte equivalent to the vendor SDK on error handling, encoding, delivery-receipt polling, and rate-limit backoff. Second, maintenance transfer: the project has taken on the obligation to track Ghasedak's API changes indefinitely, with no vendor SDK as a canary. Third, versioning discipline: shipping a transport-layer rewrite as a patch release means automated dependency updates (composer update, Dependabot, Renovate) will pull it in with no human review trigger. The stated benefit is real — one fewer transitive dependency, one fewer supply-chain and abandonment risk, no version conflicts with the vendor SDK — but it is a trade, not a pure win.
Key questions.
Illuminate\Support\Facades\Http? If not, how are outbound calls faked in tests?Stack fit. Standard Laravel package shape — Composer-installed, service provider with auto-discovery, publishable config. It slots into the existing notification stack without architectural change. The one thing to confirm is PHP and Laravel version constraints in composer.json, since removing a dependency often accompanies a floor bump (e.g. dropping support for older Laravel versions that the vendor SDK required).
Migration path. Because this is a patch release, composer update will take it. That is the wrong way to adopt it. Pin the current version, then upgrade deliberately in a branch: run the full test suite, inspect the published config diff (php artisan vendor:publish --tag=... --force into a scratch directory and diff), and exercise one real send against a sandbox account. If config keys moved, add a compatibility shim in config/ rather than editing application code. Budget half a day, not an hour — the config diff is the part people skip and then debug in production.
Compatibility. Assume the public API is source-compatible and the runtime behaviour is what changed. Test doubles are the likely casualty: if the old vendor SDK was mocked via its own client class or Guzzle handler stack, those mocks no longer intercept anything and tests will pass while making real network calls, or fail confusingly. Audit every test that touches SMS. Also check any code that catches vendor-SDK-specific exception classes or reads response properties off the returned object.
Sequencing.
Maintenance. The centre of gravity moves from "wait for the vendor SDK to be updated" to "we own the HTTP client." That is cheaper when the provider's API is stable and the maintainer is responsive; it is more expensive when the provider ships breaking changes and the maintainer is a volunteer. Note that the release credits an external contributor — a good sign for community health, but it also means the transport layer's authorship is distributed. There is no stated support policy, which for a messaging dependency is worth pinning down before it becomes load-bearing.
Support. Failure diagnosis changes shape. Today a bug is often "the vendor SDK doesn't do X"; after this release it is "the package's HTTP layer mishandles X," and the fix lands on the package maintainer's timeline rather than the vendor's. When filing issues, include the request/response pair — the package now presumably logs or throws with more of that detail, which helps, provided it does not log credentials. Verify redaction of API keys and message bodies in whatever logging was added.
Scaling. No change to throughput characteristics: SMS delivery is bounded by the provider's rate limits and per-request latency, and the package is a thin client. What does change is connection reuse and concurrency behaviour if the new implementation dropped a pooled Guzzle client for per-call instantiation. If you send at volume, check for keep-alive and confirm the timeout and retry defaults are explicit and configurable rather than inherited from the removed SDK. Queued notifications should still be the pattern; confirm the new implementation does not introduce blocking retries inside the request cycle.
Failure modes. Watch for: silent failures where a non-2xx response is coerced into a "sent" object instead of throwing; changed timeout defaults causing queue workers to hang longer than their own timeout; unvalidated response parsing raising PHP warnings or type errors on unexpected payloads; and, during the transition, tests that mock the old SDK and therefore assert nothing. The reimplementation of "all APIs" also means a wider surface than your application actually exercises — code paths for delivery receipts, bulk sends, or account balance that nobody on your team has ever run.
Ramp-up. Low for a developer familiar with Laravel packages: an hour to read the service provider, config, and channel class. The cost is not learning the package, it is unlearning the assumption that the vendor SDK is underneath — every mock, every caught exception, every place a response property is read. Build the sandbox test script once and keep it in the repo; it is the artifact that makes the next upgrade cheap.
Recommendation. Adopt, but not on the patch-release autopilot. Pin the version, upgrade in a branch with a config diff and a sandbox send, fix the test doubles, then move on. Separately, ask the maintainer why a transport rewrite shipped as 1.4.2 — the answer tells you a lot about how much to trust future version numbers from this project.
How can I help you explore Laravel packages today?