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

Siru Php Sdk Laravel Package

sirumobile/siru-php-sdk

A PHP SDK for integrating Siru Mobile payments into your app, offering a simple client for the Siru Mobile API so you can initiate and manage mobile and carrier-billing payments from Laravel or plain PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and inspect before wiring anything up. The package is a thin, low-traffic wrapper (0 stars, no dependents, last release Dec 2021), so budget 15 minutes to read the source before you commit to it:

composer require sirumobile/siru-php-sdk

Then look at, in order:

  1. composer.json — check the PHP constraint and the guzzlehttp/guzzle / psr/* versions it pins. This is the single most likely reason installation fails on a modern Laravel app (Laravel 10/11 ship Guzzle 7.x; a 2021 SDK may pin ^6.0).
  2. src/ — find the main client class and the request/response value objects. Note whether the client takes config in the constructor or via setters.
  3. README.md — for the endpoint hostnames (sandbox vs. production) and the signing scheme.

There is almost certainly no Laravel service provider. Don't expect auto-discovery, a publishable config, or a facade. Register it yourself in AppServiceProvider:

// app/Providers/AppServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Siru\Client::class, fn () => new \Siru\Client(
        merchantId: config('services.siru.merchant_id'),
        secret:     config('services.siru.secret'),
        endpoint:   config('services.siru.endpoint'),
    ));
}
// config/services.php
'siru' => [
    'merchant_id' => env('SIRU_MERCHANT_ID'),
    'secret'      => env('SIRU_SECRET'),
    'endpoint'    => env('SIRU_ENDPOINT', 'https://sandbox.siru.example/'),
],

First use case: a carrier-billing / mobile-payment checkout. Typical shape is create payment → redirect the user to the gateway URL → receive a server-to-server callback → confirm status. Start by getting the sandbox create-payment call returning a redirect URL in a Tinker session or a throwaway artisan command; that validates credentials, signing, and endpoint in one shot before you touch a controller.

Implementation Patterns

Wrap it, don't sprinkle it. Because the SDK is unmaintained, put your own interface in front of it so a swap (or a fork into app/Support/Siru) is a one-file change:

interface PaymentGateway
{
    public function createPayment(Order $order): PaymentRedirect;
    public function fetchStatus(string $reference): PaymentStatus;
}

Bind the SDK-backed implementation in the container. Your controllers, jobs, and tests then never reference Siru\* directly.

Initiation flow. Do the create-payment call inside a DB transaction that also writes your own payments row with a generated reference — never rely on the gateway's ID as your primary key, and never trust a client-supplied amount:

public function store(CheckoutRequest $request, PaymentGateway $gateway)
{
    $order = Order::create([...]); // amount in minor units, from your own cart

    $redirect = $gateway->createPayment($order);

    $order->payments()->create([
        'reference' => $order->reference,
        'status'    => 'pending',
        'redirect_url' => $redirect->url,
    ]);

    return redirect()->away($redirect->url);
}

Callback controller. This is where most of the day-to-day work is. Keep it dumb: verify, persist, dispatch, return 200.

public function __invoke(Request $request, PaymentGateway $gateway)
{
    abort_unless($gateway->verifySignature($request->getContent(), $request->headers->all()), 403);

    $payload = $request->all();

    $payment = Payment::where('reference', $payload['reference'])->firstOrFail();

    // idempotency: callbacks get retried
    if ($payment->status !== 'pending') {
        return response('ok');
    }

    $payment->update(['status' => $payload['status'], 'raw' => $payload]);
    PaymentReceived::dispatch($payment);

    return response('ok');
}

Order state machine + events. Map gateway statuses onto your own small enum (Pending, Paid, Failed, Cancelled) and fire domain events. Listeners handle fulfilment, receipt email, and stock decrement — not the controller, and not the SDK callback path.

Reconciliation job. Callbacks get lost. Schedule an hourly job that finds pending payments older than N minutes and polls status via the SDK, then routes through the same PaymentReceived/PaymentFailed handling. Make the event handling idempotent so the poller and the webhook can race safely.

Testing. Swap the gateway binding for a fake in tests (that's the payoff of the interface). If you want to test the SDK layer itself, inject a Guzzle client with a MockHandler — the SDK almost certainly accepts a ClientInterface or a base URI, which lets you replay captured sandbox responses without network calls. Use Http::fake() only if the SDK is built on the Laravel HTTP client (it isn't; it predates it).

Gotchas and Tips

  • PHP and dependency drift is the headline risk. A 2021 release, zero dependents, and no commits in years means it was never tested against PHP 8.2/8.3 or Laravel 10/11. Expect to need "sirumobile/siru-php-sdk": "*" plus a composer.json conflict/replace or a vcs fork if Guzzle constraints clash. Check for #[\ReturnTypeWillChange]-era issues and dynamic-property deprecations in PHP 8.2 (common in SDKs of that vintage).
  • Signing is the thing that breaks silently. Siru-style gateways sign a canonical string with a shared secret. Compute over the raw request body ($request->getContent()), never over $request->all() — PHP's array reordering and numeric-string coercion will change the payload and produce a mismatch you'll chase for hours. Compare with hash_equals(), not ===.
  • Sandbox and production differ by host and often by merchant credentials. Keep them as separate env vars; never let a staging deploy inherit the production key. Add a guard: abort_if(app()->isProduction() && str_contains(config('services.siru.endpoint'), 'sandbox'), 500).
  • Callbacks arrive unauthenticated by design. Exclude the callback route from VerifyCsrfToken (bootstrap/app.php → validateCsrfTokens(except: ['siru/*']) in Laravel 11) and, critically, exclude it from any auth middleware. Signature verification is the only authentication.
  • Money is in minor units. Carrier-billing gateways take integer cents; your decimal(10,2) column will cause off-by-100 errors. Store amount_minor as an integer and cast once at the boundary.
  • Carrier billing has hard caps and geographic limits. Per-transaction and monthly ceilings are set by the operator, not the SDK. Handle the gateway's "amount not allowed" rejection as a normal user-facing failure, not an exception that 500s the checkout.
  • Don't log the secret or full callback payloads at debug. Payment payloads contain MSISDN/phone numbers — PII under GDPR. Log the reference and status only; keep the raw payload in an encrypted column if you need it for disputes.
  • Extension points are thin. If you need retries with backoff, timeouts, or connection pooling, wrap the SDK's transport rather than patching the SDK: pass a configured Guzzle client into the constructor if it accepts one, otherwise decorate your PaymentGateway implementation with retry() and a circuit breaker.
  • Vendor it if you're serious. With no upstream maintainers, copy src/ into app/Support/Siru behind your interface once it works. You get PHP 8 type declarations, tests, and a namespace you control — and you stop being one composer update away from a broken checkout.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route