makfly / stripe-cashier-bundle
Stripe Cashier integration for Symfony 7 and 8
Package info
github.com/MakFly/stripe-cashier-bundle
Type:symfony-bundle
pkg:composer/makfly/stripe-cashier-bundle
Requires
- php: ^8.2
- doctrine/doctrine-bundle: ^2.13|^3.0
- doctrine/orm: ^3.0
- dompdf/dompdf: ^3.1
- moneyphp/money: ^4.5
- nesbot/carbon: ^3.0
- phpseclib/bcmath_compat: ^1.0
- stripe/stripe-php: ^16.0
- symfony/doctrine-bridge: ^7.0|^8.0
- symfony/framework-bundle: ^7.0|^8.0
- symfony/twig-bundle: ^7.0|^8.0
- twig/twig: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.66
- phpstan/phpstan: ^1.12
- phpunit/phpunit: ^11.0
- symfony/phpunit-bridge: ^7.0|^8.0
- symfony/var-exporter: ^7.0|^8.0
Suggests
- symfony/messenger: For processing webhooks asynchronously
README
Stripe billing for Symfony 7.x and 8.x, inspired by Laravel Cashier.
Installation
composer require makfly/stripe-cashier-bundle php bin/console cashier:install
The installer creates the missing bundle files and directories:
config/packages/cashier.yamlconfig/packages/cashier_doctrine.yamlconfig/routes/cashier.yaml- Stripe env vars in
.env var/datavar/data/invoices
Runtime requirements
| Dependency | Version |
|---|---|
| PHP | ^8.2 |
| Symfony | ^7.0 or ^8.0 |
| Doctrine ORM | ^3.0 |
| Stripe PHP SDK | ^16.0 |
ext-intl
ext-intl is recommended, but not required.
Without intl, the bundle still works:
- currency formatting falls back safely
- invoice dates fall back to ISO format
- invoice translations still work for shipped locales
With intl, invoice rendering is cleaner and more locale-aware.
Minimal configuration
cashier: key: '%env(STRIPE_KEY)%' secret: '%env(STRIPE_SECRET)%' path: cashier webhook: secret: '%env(STRIPE_WEBHOOK_SECRET)%' tolerance: 300 currency: usd currency_locale: en default_subscription_type: default invoices: renderer: CashierBundle\Service\InvoiceRenderer\DompdfInvoiceRenderer default_locale: en supported_locales: ['en', 'fr'] storage: driver: local path: '%kernel.project_dir%/var/data/invoices'
Invoice pipeline
The bundle can:
- read Stripe invoices
- render a PDF through the configured renderer
- archive paid invoice PDFs to
var/data/invoices - persist invoice archive metadata in
cashier_generated_invoices
Stripe Checkout sessions created by the bundle propagate checkout metadata to invoice creation metadata. That makes it easier for consumer applications to link:
- checkout session
- payment intent
- Stripe invoice
- archived PDF
- local order or booking
For deterministic consumer-side linking, use explicit metadata keys:
app_resource_typeapp_resource_idapp_user_idplan_codebilling_cycle
The archive service persists these values into cashier_generated_invoices so the consumer application can resolve invoices without amount/date heuristics.
Invoice customization
You can customize invoices at four levels:
- override
templates/bundles/CashierBundle/invoice/default.html.twig - replace
cashier.invoices.renderer - replace
CashierBundle\Contract\InvoiceLocaleResolverInterface - replace
CashierBundle\Contract\InvoiceTranslationProviderInterface
For production storage, replace CashierBundle\Contract\InvoiceStorageInterface with your own implementation if invoices must be stored on S3, GCS, or any shared storage.
Webhooks
The bundle exposes POST /cashier/webhook and ships a local CLI helper:
php bin/console cashier:webhook:listen --forward-to --base-url http://localhost:8000
This command forwards Stripe CLI events, persists the signing secret, and colorizes incoming events and HTTP responses.
Documentation
Source documentation lives in docs/ and the main sections are:
- introduction
- installation
- configuration
- customers
- payments
- subscriptions
- checkout
- invoices
- webhooks
- events
- commands
- twig
- API reference
Compatibility policy
The documented configuration under cashier.*, documented commands, documented public contracts, and documented events are the supported public API surface.
Breaking changes should only be released in a new major version.