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

serendipity_hq/stripe-bundle

Symfony bundle that simplifies integrating Stripe payments into PHP applications. It wires up Stripe's SDK as a service, exposes configuration options, and helps reduce boilerplate for payment processing, subscriptions, and webhook handling.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Symfony bundle, not a Laravel package. There is no service provider, no config/stripe.php publish tag, and no facade. If you are working in Laravel, the realistic first step is to confirm whether you actually need it at all — you almost certainly do not. The underlying value is a thin DI wiring around the official stripe/stripe-php SDK; in Laravel you would get the same result by requiring stripe/stripe-php directly and binding a configured StripeClient in a service provider.

If you are in a Symfony app (or maintaining one that already pulls this in), the minimal path is:

  1. composer require serendipity_hq/stripe-bundle
  2. Register the bundle in config/bundles.php
  3. Add a minimal config block with your secret/public keys (typically under a serendipity_hq_stripe or similarly namespaced key — verify against DependencyInjection/Configuration.php)
  4. Inject the Stripe service/client into a controller or command and make one API call (e.g. $stripe->customers->create([...]))

Where to look first, in order:

  • README.md — likely thin, but check for the config key name and the service ID
  • DependencyInjection/Configuration.php — the authoritative list of config options (keys, API version, etc.)
  • Resources/config/services.* — the actual service IDs and constructor arguments you will inject
  • composer.json — pinned Symfony and stripe/stripe-php version ranges

First use case worth validating: create a customer and a PaymentIntent on test keys, then confirm the bundle's configured API version matches what your account/dashboard expects. Treat that as a smoke test before building anything else.

Implementation Patterns

Treat it as a configured Stripe client, nothing more. The bundle’s job is to hold your keys and hand you an SDK instance. Do not let bundle-specific types leak into your domain code. Wrap it:

final class StripeGateway
{
    public function __construct(private \Stripe\StripeClient $client) {}

    public function charge(int $amountCents, string $currency, string $customerId): \Stripe\PaymentIntent
    {
        return $this->client->paymentIntents->create([
            'amount'   => $amountCents,
            'currency' => $currency,
            'customer' => $customerId,
            'automatic_payment_methods' => ['enabled' => true],
        ]);
    }
}

Bind your gateway interface in your own service config and inject that everywhere. This gives you a single seam to swap in stripe/stripe-php directly when you drop the bundle — which, given it is archived, you should plan for.

Config-driven keys per environment. Keep test and live keys in environment variables, not in committed YAML. Symfony’s %env(STRIPE_SECRET_KEY)% resolves cleanly into the bundle config. Never read the key back out of the container in application code; let the bundle hold it.

Webhook handling belongs outside the bundle. The bundle will not verify signatures for you. Implement a dedicated controller/route that reads the raw body, calls \Stripe\Webhook::constructEvent($payload, $sigHeader, $secret), and dispatches to your own handlers. Keep the webhook secret as a separate env var from the API key.

Idempotency and persistence. Every mutating call should carry an Idempotency-Key derived from your own order/attempt record. Store the Stripe object ID (pi_..., cus_...) alongside your local row in the same transaction boundary where possible, and reconcile via webhook rather than trusting the synchronous response alone.

Testing. Point the bundle at test keys and use Stripe test card numbers. For unit tests, do not boot the bundle — mock your StripeGateway interface. For integration tests, hit the Stripe test API in a dedicated CI job, or use a recorded-HTTP approach against the SDK’s Guzzle client if the bundle exposes it.

If you are actually on Laravel: skip this package. Require stripe/stripe-php, register a singleton in AppServiceProvider:

$this->app->singleton(\Stripe\StripeClient::class, fn () => new \Stripe\StripeClient(
    config('services.stripe.secret')
));

You lose nothing except a layer of indirection you did not want, and you gain a supported dependency.

Gotchas and Tips

  • Archived. No security patches, no compatibility updates for new Symfony or stripe/stripe-php majors. Check the composer.json constraints; a stripe/stripe-php major bump will likely break installs. Pin both and budget for removal.
  • Symfony-only by design. There is no Laravel integration and no community bridge with any traction (0 dependents). Do not attempt to shoehorn the bundle into Laravel via a manual container binding — you would be reimplementing two lines of service provider code.
  • Low adoption means thin docs. Service IDs and config keys are whatever Configuration.php and the service definitions say, not what a blog post says. Read those files rather than guessing.
  • API version drift. The SDK’s default API version is pinned by the installed stripe/stripe-php release, not by your Stripe dashboard. If the bundle lets you set an API version, set it explicitly; otherwise expect occasional shape changes on upgrade.
  • Key leakage via the container. Dumping the container (debug:container) can expose constructor arguments. Ensure the secret key comes from env and that you are not logging the client object or its config in dev.
  • Webhook signatures are on you. Raw request body, correct header, timing-safe verification. Framework middleware that parses JSON before your handler runs will break signature checks — read the body first.
  • Idempotency is not optional. Retries on network timeouts without an idempotency key produce duplicate charges. Generate the key from your own record ID, not a random UUID per attempt.
  • Debugging. Use debug:container --show-private to confirm the service ID, and Symfony’s HTTP client profiler if the SDK’s Guzzle client is wired through it. If requests fail silently, check that the configured key is not an empty string from a missing env var — the bundle will happily construct a client with null.
  • Extension points are minimal. There is no event system worth building on. If you need behaviour around API calls, put it in your gateway wrapper (logging, metrics, retries), not in bundle hooks.
  • Migration path. Because the bundle is a thin wrapper, removal is mechanical: add stripe/stripe-php directly, replace the injected bundle service with your own configured StripeClient, and delete the bundle registration. Do that migration before you build significant surface area on top of it.
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.
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
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect