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

Yunpian Sms Bundle Laravel Package

tourze/yunpian-sms-bundle

Symfony bundle that integrates Yunpian SMS into your application, providing ready-made services and configuration for sending text messages through the Yunpian API with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

What this is. tourze/yunpian-sms-bundle is a Symfony bundle (note: bundle, not a Laravel package) that wraps the Yunpian (云片) SMS HTTP API — a Chinese SMS gateway. The 0.1.0 tag is the first meaningful release after a 0.0.1 placeholder, and the release notes contain no changelog detail beyond the compare link, so treat 0.1.0 as "initial usable surface" rather than a documented feature set.

Verify the target framework first. Before writing any code, check the type key and require block in composer.json:

composer require tourze/yunpian-sms-bundle
cat vendor/tourze/yunpian-sms-bundle/composer.json | head -40

If it declares symfony/* and type: symfony-bundle, there is no Laravel service provider and no package auto-discovery. In that case you have two options: (a) install tourze/symfony-laravel-bridge-style shims or manually bind the client class in a Laravel service provider, or (b) skip the bundle and depend on the underlying Yunpian HTTP client it wraps. Option (b) is usually less friction.

Register and configure.

// config/bundles.php  (Symfony)
return [
    Tourze\YunpianSmsBundle\YunpianSmsBundle::class => ['all' => true],
];
# config/packages/yunpian_sms.yaml — check DependencyInjection/Configuration.php
# for the real key names; the API key is the only mandatory value.
yunpian_sms:
    api_key: '%env(YUNPIAN_API_KEY)%'

First use case. A login verification code via template send, not raw text — Yunpian requires pre-approved templates and a signature prefix for mainland Chinese numbers:

$sms->sendTemplate('13800138000', '1234567', ['code' => '482913']);

Where to look first, in order: DependencyInjection/Configuration.php (authoritative config schema), src/ for the single service class you'll inject, tests/ for the only reliable usage examples in a package this young, and README.md — if the README is empty, the tests are your documentation.

Implementation Patterns

Wrap it, don't inject it everywhere. The bundle is at 0.x and the class names will move. Define your own narrow port and adapt:

interface SmsSender
{
    public function sendVerificationCode(string $e164, string $code): void;
}

final class YunpianSmsSender implements SmsSender
{
    public function __construct(private readonly YunpianClient $client) {}

    public function sendVerificationCode(string $e164, string $code): void
    {
        $this->client->sendTemplate($e164, config('sms.templates.verify'), ['code' => $code]);
    }
}

This costs 20 lines now and saves a rewrite when 0.2.0 renames things.

Always queue. SMS HTTP calls are 200–800 ms against a Chinese endpoint. Send from a queued job with retries and exponential backoff, never inside a request/response cycle:

final class SendVerificationSms implements ShouldQueue
{
    public int $tries = 3;
    public array $backoff = [10, 60, 300];

    public function __construct(public readonly string $mobile, public readonly string $code) {}

    public function handle(YunpianSmsSender $sender): void
    {
        $sender->sendVerificationCode($this->mobile, $this->code);
    }
}

Mark the job ShouldBeUnique keyed on the mobile number to collapse double-submits from impatient users tapping "resend".

Separate the two send paths. Yunpian's raw-text endpoint (/v2/sms/single_send.json) and template endpoint (/v2/sms/tpl_single_send.json) behave differently on failure: raw text with an unregistered signature is rejected at send time, whereas template sends are validated against your account's approved template IDs. Use templates for anything transactional and reserve raw text for internal ops alerting where you control the content.

Persist the response. Yunpian returns a sid per message. Store it alongside your own correlation ID so you can reconcile delivery reports later — the bundle likely exposes only the send call, so this is your responsibility:

$result = $client->sendTemplate($mobile, $tplId, $vars);
SmsLog::create([
    'mobile'  => $mobile,
    'sid'     => $result['sid'] ?? null,
    'code'    => $result['code'] ?? null,  // Yunpian business code, not HTTP status
    'payload' => $result,
]);

Test against a fake, not the API. Bind a stub SmsSender in your test container. If you need to exercise the real client's serialization, use Symfony's HttpClient mock or Laravel's Http::fake() against sms.yunpian.com/* — never point CI at the live endpoint.

Gotchas and Tips

It is not a Laravel package. This is the single biggest pitfall given the assessment context. There is no YunpianSmsServiceProvider, no facade, no config/sms.php publish step, and no auto-discovery. Plan for manual wiring or use the underlying client library directly.

Pin the exact version. "tourze/yunpian-sms-bundle": "0.1.0", not ^0.1. Pre-1.0 packages treat every minor bump as potentially breaking, and the 0.1.0 notes give you no changelog to diff against 0.0.1. Budget for reading the source on each upgrade.

HTTP 200 does not mean success. Yunpian returns 200 OK with an error object in the body for many failures (invalid key, insufficient balance, blacklisted number, template mismatch). Check the JSON code field — 0 is success — and throw on anything else. If the bundle throws a generic exception, catch it and inspect the previous response body.

Signature and template pre-approval are account-level prerequisites. Mainland Chinese SMS requires a registered signature (e.g. 【YourBrand】 prepended to raw text) and pre-approved template IDs. Neither can be created from code. If sends fail with a template/signature error on day one, that's an account provisioning problem, not a code bug. Yunpian also restricts which templates you may send outside 08:00–22:00 China time.

Encoding and billing. Text is UTF-8; a single message is billed at 70 characters if any CJK characters are present, 140 otherwise, and longer content silently splits into multiple billable parts. Truncating a verification code mid-way is a real failure mode — keep templates short.

Keep the API key out of logs and exception traces. The key travels as a form parameter, so naive HTTP client logging or a Symfony profiler dump will capture it. Configure your HTTP client to redact apikey from the request body in logs, and confirm the profiler is disabled in production.

Debugging checklist. Enable the Symfony profiler or log the raw response body plus the request URL (minus the key). Verify: key is loaded from env, mobile is 11 digits without +86 unless the bundle normalizes it, template ID exists in the Yunpian console, and the account has balance. Yunpian's console shows per-message delivery state, which is faster than reading your own logs.

Extension points. The reliable customization surface for a bundle this thin is service decoration rather than configuration:

services:
    App\Sms\LoggingYunpianClient:
        decorates: Tourze\YunpianSmsBundle\...

Decorate the client to add logging, metrics, or a circuit breaker without forking. If the bundle exposes no interface, decorate the concrete class via decoration_on_invalid: ignore and proxy only the methods you call.

Watch the upstream repository, not the release notes. 0.1.0 shipped with an empty changelog. Subscribe to the GitHub compare view and read the commit list for the next release; that is currently the only signal for breaking changes.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource