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

Statamic Stripe Checkout Fieldtype Laravel Package

mitydigital/statamic-stripe-checkout-fieldtype

A Statamic fieldtype that adds Stripe Checkout to your site, letting editors place a buy button or link in their content that sends visitors to a Stripe-hosted checkout page to pay. Configure products and pricing in the fieldtype, then let Stripe handle payment collection, taxes, and receipts.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Statamic addon, so day-to-day work happens in blueprints and Antlers/Blade templates rather than in application code.

  1. Install the right major for your Statamic version. As of 3.0.0 the addon targets Statamic 6:

    composer require mitydigital/statamic-stripe-checkout-fieldtype:^3.0
    

    On a Statamic 5 site, stay on ^2.1 (see Gotchas — the 3.0 bump is a Statamic 6 compatibility release, not a feature release).

  2. Publish and configure. Publish the addon config (php artisan vendor:publish --provider="Mity\StatamicStripeCheckoutFieldtype\ServiceProvider") and set your Stripe credentials in .env. Use test keys first and confirm which env var names the config file actually reads — don't assume STRIPE_KEY/STRIPE_SECRET match your other Stripe integrations.

  3. Add the field to a blueprint. In the control panel, add the addon's fieldtype to a collection blueprint (e.g. products) and fill in the price/amount and success/cancel settings the field exposes. Blueprint YAML is version-controlled, so the checkout configuration becomes part of your content model.

  4. First use case: a single "Buy" action on a product entry. Render the field in your entry template, click it in a test environment, complete a payment with 4242 4242 4242 4242, and confirm you land on your success URL.

Where to look first: the published config file (available options), then the fieldtype's Blade view in vendor/mitydigital/statamic-stripe-checkout-fieldtype/resources/views (what markup and route it emits), then the README for the exact field config keys. Reading those three is usually faster than guessing.

Implementation Patterns

Blueprint-driven configuration. Keep Stripe price IDs and mode (payment vs subscription) in the field config rather than hard-coding them in templates. This lets editors swap a price or switch to a subscription without a deploy, and keeps the mapping visible in git.

Dynamic pricing from entry data. If prices vary per entry, either store the Stripe Price ID in a separate field on the entry and reference it in the checkout field's config, or use a Replicator/Grid of purchasable options and render one checkout action per row. Prefer Stripe Price IDs over ad-hoc price_data — ad-hoc amounts drift from your Stripe product catalogue and can't be reconciled in reporting.

Render as a form POST, not a link. The reliable pattern is: the template outputs a form that POSTs to the addon's route, the server creates the Checkout Session, and the user is redirected to Stripe. This keeps the secret key server-side, gives you CSRF protection for free, and avoids creating sessions on every page render (important with static caching). If the addon's default view emits an <a> that hits a GET route, wrap or override the view so it's a POST.

Success/cancel handling. Point success_url at a real Statamic route or entry (e.g. /checkout/success?session_id={CHECKOUT_SESSION_ID}) and treat it as a thank-you page, never as proof of payment. For cancel, return to the product entry with a query flag and render a non-blocking notice.

Fulfilment belongs in a webhook. This fieldtype starts checkout; it generally does not fulfil orders. Pair it with a checkout.session.completed listener (Laravel Cashier's webhook controller, or a small custom route excluded from CSRF) that marks the order paid, grants access, or sends the receipt. Retrieve the session server-side by ID and check payment_status before trusting anything.

Subscriptions and customers. For subscription mode, pass a customer or customer_email where possible so the same person doesn't accumulate duplicate Stripe customers. If the user is logged in, prefill from auth()->user().

Multi-site. URLs in the field config are per-blueprint, not per-site. On a multisite install, resolve success/cancel URLs from the current site (Site::current()->url()) in a view override, or duplicate the field config per site's blueprint.

Testing. Use Stripe test keys in .env.testing and fake the Stripe client (Stripe\StripeClient or the underlying HTTP client) in Pest/PHPUnit so feature tests assert on your redirect/URL logic rather than hitting the network. Use stripe listen --forward-to locally for webhook work.

Gotchas and Tips

  • 3.0.0 is a Statamic 6 compatibility bump. The only listed change is Statamic 6 support, which is why it's a major version — expect the composer.json constraint to now require statamic/cms:^6.0 and a newer PHP/Laravel baseline. On Statamic 5, pin ^2.1 and don't let a composer update pull 3.x in. Conversely, 3.x will not install on Statamic 5.
  • Because there are no new features in 3.0.0, the upgrade risk is environmental, not functional. Check your PHP and Laravel versions against Statamic 6's requirements first; a failed install here is almost always a platform constraint, not the addon.
  • Don't run vendor:publish --force on upgrade. It will overwrite any customisations to the config or views you've made. Diff the published files against the vendor copies instead.
  • Re-publish and re-read the config after major upgrades. Even with "only" a compatibility bump, upstream may have adjusted key names or defaults to match Statamic 6 conventions. If checkout silently stops working, a stale published config is the first suspect.
  • Clear caches after upgrading: php artisan config:clear && php artisan view:clear && php artisan statamic:stache:clear. Statamic's Stache caches blueprints and field config, so field changes can appear to be ignored until it's refreshed.
  • Never create Checkout Sessions at render time. If you're front-loading the session in a computed value or view composer, you'll mint a session per page view and break static caching. Sessions belong behind the POST route.
  • Test/live mode mismatch is the most common runtime error. "No such price" or "No such customer" almost always means a live-mode ID in a test-mode environment (or vice versa) — usually because the price ID was copied from the dashboard without switching the mode toggle.
  • success_url should be absolute and should include the scheme. Relative URLs produce confusing Stripe-side validation errors, and on multisite the wrong-site URL is easy to introduce.
  • Guard against double submission with a disabled button on submit; Stripe's idempotency keys are the server-side backstop if you control the session creation call.
  • Leaking keys: only the secret key is needed for the redirect flow. If any template or JS needs a publishable key, make sure it's the publishable one — a secret key in an Antlers template ends up in the page source and in your repo.
  • Debugging: Stripe Dashboard → Developers → Logs shows the exact API request the addon made with its error body; Laravel's storage/logs/laravel.log plus Ray/dd() around the session-creation response covers the rest. Enable Stripe client logging in a local .env if the addon exposes it.
  • Extension points: publish and override the fieldtype's view to control markup (Tailwind classes, button copy, POST form, analytics attributes), and publish the config to control defaults. If you need behaviour the fieldtype doesn't offer (quantities, coupons, tax), it's usually cleaner to write your own controller that calls the Stripe SDK directly and use the fieldtype only for the button/config surface.
  • Budget for the webhook. Any site taking real money needs one. If you're not already running Cashier, a small signed webhook route plus a checkout_sessions table is worth the half-day.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums