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.
This is a Statamic addon, so day-to-day work happens in blueprints and Antlers/Blade templates rather than in application code.
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).
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.
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.
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.
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.
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.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.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.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.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.checkout_sessions table is worth the half-day.How can I help you explore Laravel packages today?