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

Stripe Bundle Laravel Package

scribe/stripe-bundle

A Symfony bundle that streamlines Stripe integration with preconfigured services, dependency injection and thin wrappers around the Stripe PHP SDK, so you can add payments, customers, subscriptions and webhooks to your app with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framework mismatch. scribe/stripe-bundle is a Symfony bundle, not a Laravel package. It ships a Bundle subclass plus a DI Extension and service definitions — none of which Laravel's container reads. composer require scribe/stripe-bundle in a Laravel app installs Symfony DI components and wires nothing. The realistic day-to-day posture for a Laravel developer is: read it for reference, install stripe/stripe-php, write the binding yourself.

Where to look first in the source. The DependencyInjection/Extension class and the service definition file under Resources/config/ (YAML or XML). That is effectively the entire feature set: one StripeClient service, a key parameter sourced from config, a public alias for injection, and a webhook helper. Read those two files and you have internalised everything the package does.

Minimal steps for the Laravel equivalent (roughly the same effort as installing the bundle, ~20–40 lines):

  1. composer require stripe/stripe-php
  2. Add a stripe block to config/services.php:
    'stripe' => [
        'secret'         => env('STRIPE_SECRET'),
        'public'         => env('STRIPE_KEY'),
        'webhook_secret' => env('STRIPE_WEBHOOK_SECRET'),
        'api_version'    => env('STRIPE_API_VERSION'),
    ],
    
  3. Register a singleton in a small StripeServiceProvider:
    $this->app->singleton(\Stripe\StripeClient::class, fn ($app) =>
        new \Stripe\StripeClient([
            'api_key'     => $app['config']['services.stripe.secret'],
            'api_version' => $app['config']['services.stripe.api_version'],
        ])
    );
    
  4. Constructor-inject StripeClient into a controller or job and make one call ($stripe->customers->retrieve($id)) to prove config wiring before building charges.

First use case. A single read call (retrieve customer/subscription) from a controller confirms keys, API version, and container binding. Do that before touching write paths — the bundle adds no retries or idempotency, and neither does the SDK, so get the wire right first.

Implementation Patterns

What the Symfony bundle gives you, translated to Laravel.

  • Injected client. Symfony: constructor-inject StripeClient via service alias. Laravel: public function __construct(private StripeClient $stripe) works once the singleton is bound.
  • Overridable for tests. The bundle exposes a service alias you can swap in services_test.yaml. Laravel: call $this->app->instance(StripeClient::class, $fake) in a base TestCase::setUp() and use a Mockery fake.
  • Multiple accounts / Stripe Connect. The bundle's "sensible defaults with full override" usually means a named alias per configured account. In Laravel, either named bindings (app()->bind('stripe.connect', ...)) or build a per-request client in a service:
    $client = new \Stripe\StripeClient([
        'api_key' => $connectedAccount->secret,
        'stripe_account' => $connectedAccount->stripe_id,
    ]);
    
    Don't try to make one global singleton serve multiple accounts; the stripe_account header changes per call.

Webhook handling — the part the bundle advertises and the part you must own in Laravel:

  • Route must receive the raw body. Use $request->getContent(), not $request->all().
  • Verify with \Stripe\Webhook::constructEvent($payload, $request->header('Stripe-Signature'), config('services.stripe.webhook_secret')).
  • Exclude the webhook route from VerifyCsrfToken and from TrimStrings/ConvertEmptyStringsToNull middleware — those mutate the body and break signature matching.
  • Store the event->id in a unique column before processing. Retries are guaranteed; the bundle doesn't give you idempotency, and Stripe will resend on non-2xx.

Job / queue pattern. Inject the singleton into jobs. Pass idempotency_key explicitly on every write:

$this->stripe->charges->create(
    ['amount' => 1000, 'currency' => 'usd', 'source' => $token],
    ['idempotency_key' => $order->uuid]
);

Testing pattern. Use Stripe test keys in phpunit.xml; mock the client in unit tests via container swap. The bundle's test-friendly override maps cleanly to Laravel's $this->app->instance().

Gotchas and Tips

  • Do not pull Symfony DI into a Laravel app. You'll end up with two containers, ambiguous injection, and a class of "which container resolved this?" bugs that are expensive to trace. If someone has prototyped with the bundle, the exit is one file — replace the injected client with your own singleton.
  • License is NOASSERTION. No verified SPDX license. Do not copy source verbatim into a distributed artifact without legal sign-off. Writing the ~40 lines yourself removes the question.
  • Supply chain on the money path. 0 stars, 0 dependents, no release cadence. For payment code you want a maintained dependency and a CVE path; an unstarred Symfony bundle offers neither. Assume you're the first and only consumer.
  • SDK version pin. Check the bundle's composer.json constraint on stripe/stripe-php. Thin wrappers often cap it below current, which blocks API-version and security upgrades. If it does, that alone disqualifies it regardless of everything else.
  • Signature verification failure modes. Webhook::constructEvent throws UnexpectedValueException on any body mutation — the most common cause in Laravel is middleware (TrimStrings, ConvertEmptyStringsToNull) touching the payload. Scope webhook routes outside that group. Also: Stripe rejects events older than 5 minutes by default, so clock skew on your hosts causes intermittent 400s.
  • Pin api_version explicitly. Passing api_version on client construction prevents Stripe from silently upgrading your response schema when the account default changes. The bundle may or may not expose this — verify, and set it in your own provider either way.
  • Key handling. Confirm (or replicate carefully) that keys come from env/secret manager only, never from a committed YAML. In Laravel, config('services.stripe.*') is env-backed and config:cache-safe; don't read env() outside config files.
  • Logging leakage. Any wrapper that logs request/response bodies can leak card-adjacent data and keys. Stripe's SDK logging is opt-in (setLogger) — keep it off in production and audit any wrapper you adopt for what it writes.
  • Extension points worth replicating, not inheriting. The client factory (for tests and Connect), a WebhookVerifier helper class, and a const map for event types. The Symfony service definitions themselves are not worth dragging across the framework boundary.
  • When to reconsider this bundle. Only if you migrate to Symfony, or if the project gains active maintenance, a declared license, and a current stripe/stripe-php range. Until then, file it as "reference only, reason reviewed" so the next engineer doesn't rediscover it and reopen the decision.
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.
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json
refinery29/php-cs-fixer-config
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules