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.
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.
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.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.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.new Smsup\ApiBundle\SmsupApiBundle() in AppKernel::registerBundles(). On Symfony 4+: append to config/bundles.php manually (Flex will not discover it).Configuration.php names it, e.g. smsup_api:) and keep the password/key in parameters.yml/env, not committed YAML.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.
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.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.+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.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.var/cache as plaintext. Resolve them from env at runtime inside your adapter if that cache directory is ever shared or shipped.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.How can I help you explore Laravel packages today?