Sell plans and subscriptions with Stripe
Products, prices and checkout, managed in your app instead of the Stripe dashboard.
The problem
Your pricing lives in the Stripe dashboard. Your app has a hardcoded list of plans that has to agree with it. When someone edits a price in Stripe, nothing tells your app, and the mismatch surfaces as a customer being charged something your pricing page does not show.
You want the catalog to live in your application, synced outward — one place to change a price, and checkout that follows from it.
What you are building
Live surfaces, not screenshots — every one composed from the same components you would install.
Plan picker
The vendorable catalog-fms block — copied into your project, then yours to restyle.
Starter
- 3 projects
- 1 seat
Team
- Unlimited projects
- 10 seats
- Audit log
Scale
- SSO
- Priority support
The code
use LaravelCatalog\Facades\Catalog;
// A plan is a product with a recurring price -- no second model to keep in step.
$pro = Catalog::createProduct(['name' => 'Pro', 'description' => 'Professional features']);
Catalog::createPrice($pro, [
'amount' => 2999,
'currency' => 'usd',
'recurring' => ['interval' => 'month'],
]);
Catalog::syncProductAndPrices($pro);// One call for subscriptions and one-offs alike, so the purchase flow carries no
// Stripe-specific branching into your controllers.
$checkout = Catalog::createCheckoutSession($user, [
'price' => $price->stripe_price_id,
'mode' => 'subscription',
'success_url' => route('checkout.success'),
'cancel_url' => route('pricing'),
]);
return redirect($checkout->url);How to solve it
Install the catalog
Products and prices as models in your own database, synced to Stripe.
Run thisbash composer require particle-academy/laravel-catalogCreate products and prices
A plan is simply a product with a recurring price — there is no separate plan model to keep in step. Every product needs at least one price before it can sync.
Sync to Stripe
Sync explicitly, or turn on auto-sync so a saved product reaches Stripe without a second step. Queue it in production.
Send the customer to checkout
Checkout sessions for both subscriptions and one-off payments come from the same facade, so the purchase flow does not need Stripe-specific code in your controllers.
Build the pricing page from your own data
Because the catalog is local, the pricing page reads from your database — no API call on page load, and no second copy of the prices to keep honest.
