Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Smsup Api Bundle Laravel Package

smsup/smsup-api-bundle

Symfony bundle for integrating the SMSUP API into PHP applications. It provides configuration and service wiring to help connect your Symfony project to SMSUP and send SMS messages with less setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony 2-era bundle (2 stars, 0 dependents, no maintenance signal), so treat step one as a compatibility audit, not an install.

  1. Read the constraints before installing. Check composer.json in the repo for require entries (symfony/symfony, PHP version) and the autoload section (Symfony2 bundles are usually PSR-0, not PSR-4). If it pins symfony/symfony: ~2.x, it will not resolve on Symfony 4+ alongside your framework packages.
  2. Find the three files that define the contract:
    • DependencyInjection/Configuration.php — the real config keys (account/user, password or API key, sender name, sandbox flag). This is more authoritative than the README.
    • Resources/config/services.xml|yml — the service ID you'll inject. Likely something like smsup.api; confirm rather than guess.
    • The client class (usually under Api/, Client/, or Service/) — this tells you whether the bundle wraps cURL, Guzzle, or raw file_get_contents, and whether it returns a parsed result or a raw string.
  3. Register it. On Symfony 2/3: new Smsup\ApiBundle\SmsupApiBundle() in AppKernel::registerBundles(). On Symfony 4+: append to config/bundles.php manually (Flex will not discover it).
  4. Configure credentials under the bundle's root key (whatever Configuration.php names it, e.g. smsup_api:) and keep the password/key in parameters.yml/env, not committed YAML.
  5. First use case: a single transactional SMS — an OTP or an appointment reminder — sent from a console command rather than a controller. That isolates "is the credential and endpoint correct?" from "is my web request path correct?" Once a test SMS lands on a real handset, wire it into the app.

Implementation Patterns

Inject, don't fetch. Never $this->get('smsup.api') — that's removed in Symfony 4+ and untestable even on Symfony 2. Alias the bundle service to your own interface and depend on that:

services:
    App\Sms\SmsSender: '@smsup.api'

Wrap it in an adapter. The bundle is a thin, unmaintained dependency; you want exactly one file in your codebase that knows its class names. Define App\Sms\SmsSenderInterface::send(string $to, string $body): SmsResult and let the bundle-backed implementation be one of possibly several providers. When the vendor changes or you migrate, you swap one class.

Send out-of-band. The API call is a network round-trip to Spain; a slow response should never block a checkout or a login. Push sends onto a queue (Messenger on modern Symfony, or your existing queue/kernel.terminate listener on legacy) and only fail the user-facing flow if the enqueue fails.

Compose messages from templates. Build the body with Twig (or a small formatter service) so copy changes don't require deploys of business logic. Keep the template aware of the character budget: GSM-7 gives 160 chars, but a single á, ñ, € or emoji flips the whole message to UCS-2 and drops you to 70. Spanish transactional copy hits this constantly — mb_strlen in the right encoding, not strlen.

Persist what you send. Store recipient, normalized body, timestamp, returned message ID, status and (if returned) cost. Delivery reports and support questions are unanswerable otherwise, and this table is what lets you prove a duplicate charge.

Testing pattern: the bundle's service performs real HTTP. In functional tests, rebind the service ID to a fake that records calls and returns canned responses; assert on the recorded calls, not on the vendor response shape.

Gotchas and Tips

  • The hard blocker is Symfony version, not the code. Symfony 2 has been EOL since 2019. Before investing any time, run composer require smsup/smsup-api-bundle --dry-run in your actual project. Expect a conflict; if so, the pragmatic move is to extract the single API client class, replace its transport with symfony/http-client, and drop the bundle entirely. You lose nothing — the bundle is mostly DI wiring.
  • HTTP 200 does not mean sent. SMS gateways routinely return 200 OK with an error code in the body (invalid number, insufficient balance, blocked sender). Parse the payload and branch on the vendor's status field; log the raw body on any non-success. This is the single most common integration bug with SMS APIs.
  • Phone number normalization is on you. Decide once whether you store +34600123456 or 34600123456 and convert at the adapter boundary. The API likely wants digits with country code and no +; Spanish numbers without the 34 prefix will either fail or silently route wrong.
  • No default timeout. Older clients use file_get_contents/cURL without one. Wrap the call with an explicit connect/read timeout (a few seconds) or a hung gateway becomes hung queue workers.
  • Retries cause double SMS. Network timeouts are ambiguous — the message may have gone out. Only retry on explicit pre-acceptance failures, and cap attempts at 2–3 with backoff. There is no idempotency key here unless the API supports one; check.
  • Secrets in the compiled container. Credentials set as container parameters get dumped into var/cache as plaintext. Resolve them from env at runtime inside your adapter if that cache directory is ever shared or shipped.
  • Config quirks: expect a flat, undocumented tree and no validation of required keys. If Configuration.php doesn't mark the password as isRequired(), a missing credential surfaces as an authentication failure at send time, not at boot. Add a kernel.boot or health-check assertion yourself.
  • Debugging: the Symfony profiler won't show this HTTP call unless the bundle uses an event-dispatcher-aware client — it almost certainly doesn't. Add explicit logging (recipient masked, response code, latency) around your adapter; that log is your only observability.
  • Zero dependents / no test suite means edge cases are unexercised. Before production, write one contract test against the provider's sandbox and one against a fake, and keep the sandbox test tagged so it doesn't run in CI without credentials.
  • Extension point worth knowing: because the bundle is DI + a client class, the cleanest long-term path is to fork, keep the config shape and service ID (so your app config doesn't change), and replace only the transport. That gives you modern HTTP, timeouts, and testability without a migration.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core