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 Payments Laravel Package

goldnead/statamic-payments

Goldnead Statamic Payments is a Statamic addon for handling payments in your site, letting you integrate checkout flows and payment providers with your content. It aims to simplify common payment tasks for Statamic developers.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Shipping checkout without a homegrown double-charge guard. The package now owns the two failure modes that most directly cause support tickets and refunds in a paid checkout: duplicate payments from a double-clicked "buy" button, and silently unfulfilled orders where the buyer paid but the webhook acknowledged receipt before the order was actually processed. That means the build-vs-buy call tilts toward buy for anything short of a bespoke payment stack.
  • Committing to "order never lost after payment" as a product promise. The webhook now answers 503 when the provider is unreachable and lets Mollie redeliver (10 attempts over 26 hours) instead of returning 200 and ending the retry chain. This is a user-visible reliability guarantee you can put in front of support and finance: paid orders get fulfilled, not just recorded.
  • Deciding whether to invest in order-recovery tooling. Because the package absorbs retries, a roadmap item like "reconciliation job for stuck orders" can be dropped or descoped. Conversely, you may still want a backstop after the 26-hour redelivery window closes — that becomes a deliberate decision rather than an accident.
  • Scoping multi-provider expansion. Idempotency keys are now passed to every provider create call (Mollie as an Idempotency-Key header). Adding a second provider is no longer only an adapter exercise; it is a question of whether that provider supports idempotent create, which is now a requirement in your provider selection criteria.
  • Setting a dedupe policy that is a product decision, not just an engineering one. A repeated start of the same basket by the same buyer — same address, products, quantities, discount, return URL, and methods — returns the open payment from the last ten minutes. That is the right default for accidental double-clicks, but it is worth an explicit answer for the legitimate case: a buyer intentionally ordering the identical basket twice within ten minutes will be handed back the first checkout URL rather than a new payment. For most catalogues this is a non-issue; for low-value, high-frequency purchases (coffee, digital credits, repeated top-ups) it is a real behavioural edge case and should be validated against your actual order patterns.
  • Treating SQLite parity as a supported deployment target. The unique index on payments.checkout_key works where lockForUpdate() does nothing. If your roadmap includes single-tenant or on-prem deployments on SQLite, this is now a defended configuration rather than an untested one.

When to Consider This Package

Adopt when:

  • You are taking real money through a Laravel app and the checkout path is on the critical revenue route — the failure modes fixed here (double charge, paid-but-unfulfilled) are the expensive ones.
  • You use Mollie, or you use another provider and are willing to implement the PaymentGateway contract including idempotency handling.
  • You want duplicate-prevention and webhook-retry correctness without owning that code, its edge cases, or its tests.
  • You can run php artisan migrate as part of your deploy — this release adds payments.checkout_key (nullable, unique) and is not usable without it.

Look elsewhere, or plan extra work, when:

  • You maintain a custom PaymentGateway implementation. This is the one change in the release that can break you. createPayment() now receives idempotencyKey in the payload; you must either drop it or map it to your provider's idempotency header, and specifically must not forward it in a request body. Budget a small but non-optional engineering task before upgrading, and confirm each custom gateway's behaviour under retry.
  • Your payments table is very large and always under write load. Adding a unique index is a schema change with operational cost; plan the migration window and check for lock behaviour on your engine rather than assuming it is free.
  • You need dedupe windows longer than ten minutes, or need dedupe keyed on something the package does not inspect (for example, deliberately ignoring the return URL, or keying on customer ID rather than address). The matching rule is fixed, and the window is fixed at ten minutes.
  • You depend on the previous webhook semantics — for example, downstream systems that treat a 200 from the webhook as proof of processing. Those integrations will now see 503s during provider outages and must tolerate redelivery.
  • You need idempotency guarantees at a layer above payment creation (order placement, fulfilment, email dispatch). This release makes payment creation idempotent; it does not make your whole checkout pipeline idempotent.

How to Pitch It (Stakeholders)

To executives: This release closes a revenue leak. Two bugs were costing real money: a buyer who double-clicked "buy" could be charged twice, and a temporary network blip between our app and the payment provider could mark a paid order as handled while it was never fulfilled. Both are now fixed structurally — duplicate checkouts collapse to a single payment, and webhooks that cannot reach the provider now tell the provider to retry rather than falsely confirming success. The upgrade is a routine database migration plus a small, well-defined change for any custom payment integrations. There is also one product question to settle: a genuinely repeated identical purchase within ten minutes returns the original checkout rather than creating a new payment, which we should check against how customers actually buy.

To engineering: Upgrade requires php artisan migrate to add the nullable unique payments.checkout_key. Dedupe is enforced by that unique index rather than row locking, so it holds on SQLite and under two simultaneously in-flight requests — both requests resolve to one row. Provider create calls now carry an idempotencyKey (Mollie: Idempotency-Key header), so a retry after a lost response returns the first payment instead of creating a second. Any custom PaymentGateway must accept idempotencyKey in the createPayment() payload and either drop it or send it as the provider's idempotency header — never in a request body. Webhook behaviour change worth noting in runbooks: provider-unreachable conditions (network error, timeout, 5xx, 429, 408) now raise ProviderUnavailable and return 503, deliberately triggering redelivery; a 404 is still treated as a valid answer and returns 200. Anything downstream that consumed the webhook's 200 as a processing signal must be reviewed.

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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel