lanos/laravel-cashier-stripe-connect
Laravel Cashier Stripe Connect adds Stripe Connect support to Laravel Cashier, helping you manage connected accounts, charges, and payouts for marketplace or platform payments with familiar Cashier APIs.
Architecture fit. The package targets a genuine gap in Laravel's first-party billing stack: Cashier models a single platform Stripe account (stripe_id on the billable, one customer per model), while Stripe Connect requires a second identity dimension — the connected account — plus onboarding state, capability requirements, and money-movement semantics (destination charges, application fees, transfers). Extending Cashier is the idiomatic Laravel path (service provider, publishable config/migrations, traits on the billable model), but it is also the fragile path: the package must reach into Cashier's Billable trait, StripeClient resolution, and WebhookController, all of which are internal surfaces with no stability guarantee across Cashier majors. v1.3.2 adds a third migration tag, tenancy-migrations, which materially changes the architecture picture: the package now carries an opinion about multi-tenant deployments, meaning connected-account identity is expected to be scoped per tenant in some installations. That is a real capability for marketplace/SaaS-of-marketplaces products, but it widens the surface the package owns (tenant resolution, migration ordering, per-tenant Stripe credentials or per-tenant account mapping) and adds a dependency on whichever tenancy package the migrations assume. The architecture is appropriate for a marketplace that already uses Stripe Billing subscriptions and needs seller payouts; it is over-engineered for a product doing only one-off Connect payments, where the plain stripe/stripe-php SDK is a simpler and more durable dependency. For single-tenant products, the tenancy migrations are dead weight that must be deliberately not published.
Integration feasibility. Composer install, config/migration publish, trait addition, and platform key configuration remain low-friction for a team already on Cashier. v1.3.2 improves this: publishing is now conventional and granular — --tag="config", --tag="migrations", --tag="tenancy-migrations", or untagged for everything — which lets a single-tenant install skip tenancy migrations entirely rather than pruning them by hand. This is a developer-experience improvement, not a capability unlock, but it removes a class of "published files I have to delete and remember not to re-publish" mistakes that plague forked Cashier extensions. Note that any internal or vendor onboarding docs written against the previous publish command should be re-verified; the untagged form still publishes everything, so existing instructions degrade rather than break, but the tag names are now part of your install contract and should be pinned alongside the version. The real integration cost still sits outside the package: Stripe Connect platform activation, branding, account-type selection (Express vs. Standard vs. Custom), and a webhook topology that separates platform events from connected-account events (Cashier's default route handles the former; Connect events arrive with an account field and typically need either a second endpoint or a delegating controller). Testing requires Stripe test-mode connected accounts and the Stripe CLI's Connect forwarding, which adds CI complexity. Feasible for a mid-senior Laravel team in a bounded scope; not turnkey.
Technical risk. The dominant risk is version coupling: Cashier 13/14/15 introduced breaking changes, and a package that patches Cashier internals will lag those majors. v1.3.2 does not address that axis — it is a packaging and tenancy-surface release, not a compatibility release — so the coupling risk is unchanged. Secondary risks: Stripe API version drift (Connect's Accounts v2 controller model is displacing the legacy type field), correctness of money movement (fees, refunds, disputes, partial reversals, idempotency), and webhook signature verification on the Connect endpoint. The new tenancy migrations introduce a distinct risk: migration ordering against the tenancy package's own migrations, and the possibility of connected-account records being written without a tenant scope if the trait is applied inconsistently — a data-integrity and cross-tenant leakage concern rather than a billing-correctness one. Supply-chain risk remains material — low stars, zero dependents, single maintainer, no independent production signal. The release cadence is at least alive, which is a mild positive against the "fork or vendor" recommendation, but it does not overturn it: treat the package as a reference implementation to vendor or fork rather than a black-box dependency, and pin to v1.3.2 as the reviewed baseline.
Key questions.
tenancy-migrations target, and is the tenant scope mandatory or optional?account.updated, capability.updated, payout.*, connected charge.*) handled, and how does that coexist with Cashier's webhook route?requirements.due handling) included?Stack fit. Best fit: Laravel 10–12 + Cashier + Stripe Billing, marketplace or platform model where the same User is both buyer and seller. The package lets one billable model carry both a platform customer identity and a connected-account identity. v1.3.2 extends the fit to multi-tenant marketplaces (a platform hosting many independent seller-tenants), but only if your tenancy stack matches what the migrations assume — verify before committing. Poor fit: non-Stripe billing, pure one-off payments, or platforms on Paddle/Chargebee. Confirm early whether subscriptions and Connect must coexist; if not, drop Cashier and use the raw SDK. Also confirm early whether you are multi-tenant, because that decision changes which migrations you publish and is expensive to reverse after data exists.
Migration path. Assume additive-only schema (new columns and a connected-accounts table) and verify migrations are reversible. Publish selectively rather than wholesale — config always, base migrations always, tenancy migrations only if the tenancy model is genuinely in scope — so the schema you own matches the schema you intend to support. If tenancy is in scope, sequence tenancy migrations strictly after the tenancy package's own migrations and test a fresh-install path, not only an incremental one. Sandbox first in a dedicated Stripe test platform account, not the production account. Pilot one account type and one charge pattern end-to-end before broadening. Feature-flag the Connect charge path so checkout can fall back to the legacy flow.
Compatibility. Pin Cashier, stripe/stripe-php, and this package explicitly — v1.3.2 is the reviewed baseline and its publish-tag names are now part of your install contract. Pin the tenancy package too if tenancy migrations are published; an unpinned tenancy major is a silent migration-ordering hazard. Audit the package's calls into Cashier internals and record them — that list is your upgrade checklist. Record the published file manifest per tag so upgrades can be diffed. Decide up front whether you will vendor the package into the repo; given the zero-dependents signal, vendoring is the safer default.
Sequencing.
account.updated webhook, UI states for requirements.due and restricted.Maintenance. Expect to own this. Budget a recurring line item for (a) Cashier major upgrades, (b) Stripe API version bumps, and (c) patching or forking when the upstream maintainer is inactive. v1.3.2 is a positive cadence signal but also evidence of scope growth — packaging and tenancy now sit alongside Connect, so the diff surface you must review per release is broader than "billing logic." Track the issue queue and release cadence as a leading indicator; a six-month gap is your trigger to fork. Re-run the publish-tag manifest check on every upgrade.
Support. Stripe supports Stripe; nobody supports the glue. Internal runbooks must cover onboarding failures, capability loss, and webhook replay. If tenancy migrations are in play, add a runbook for tenant-scoped connected-account resolution failures — the class of bug where an account exists but is invisible to the tenant that owns it, or visible to the wrong one. Finance needs a documented process for failed payouts and dispute handling.
Scaling. Webhook throughput and queueing are the first pressure points — queue Connect webhooks, enforce idempotency, index connected-account IDs and, where applicable, the tenant foreign key. Watch Stripe rate limits during onboarding bursts and payout runs. Reporting queries against connected-account dimensions will need indexes early; with tenancy these become composite indexes and the cost of getting them wrong rises.
Failure modes. Incomplete onboarding blocking payout; capability revocation; charge failure scoped to a connected account (not the platform); webhook delivery gaps causing state divergence; API version drift silently changing response shapes; a Cashier upgrade breaking the extension. v1.3.2 adds two: migration misordering or partial publishing when upgrading from a pre-tag release, and tenant-scope leakage or orphaning if the tenancy trait and migrations disagree. Each needs a detection signal and a manual recovery path — Stripe is the system of record, so reconciliation jobs are non-negotiable.
Ramp-up. A competent Laravel engineer needs roughly one to two sprints to ship a scoped Connect flow, plus a half-sprint for finance reconciliation and a compliance review covering PCI scope (SAQ A vs. A-EP depending on integration) and KYC ownership (Stripe handles it for Express/Standard; Custom shifts more onto the platform). Multi-tenant installs add roughly another half-sprint for tenancy wiring and fresh-install validation. v1.3.2's conventional publish tags shave a little off initial setup and reduce onboarding friction for new engineers, but they do not change the underlying learning curve: the package reduces the Connect learning curve without removing the need to understand Connect's charge semantics — the abstraction is thin enough that engineers will read Stripe docs regardless.
How can I help you explore Laravel packages today?