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.
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.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.Adopt when:
PaymentGateway contract including idempotency handling.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:
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.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.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.
How can I help you explore Laravel packages today?