mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-10 10:53:23 +00:00
fix: Address critical webhook and optimistic locking issues
🔒 Critical Fixes: - Implement proper optimistic locking with conflict detection and verification - Only register webhook endpoints when providers are properly configured - Move provider validation to initialization for early error detection - Fix TypeScript query structure for payment conflict checking 🛡️ Security Improvements: - Stripe webhooks only registered when webhookSecret is provided - Mollie validation ensures API key is present at startup - Prevent exposure of unconfigured webhook endpoints 🚀 Reliability Enhancements: - Payment update conflicts are properly detected and logged - Invoice updates only proceed when payment updates succeed - Enhanced error handling with graceful degradation - Return boolean success indicators for better error tracking 🐛 Bug Fixes: - Fix PayloadCMS query structure for optimistic locking - Proper webhook endpoint conditional registration - Early validation prevents runtime configuration errors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -38,10 +38,17 @@ export const mollieProvider = (mollieConfig: MollieProviderConfig & {
|
||||
webhookUrl?: string
|
||||
redirectUrl?: string
|
||||
}) => {
|
||||
// Validate required configuration at initialization
|
||||
if (!mollieConfig.apiKey) {
|
||||
throw new Error('Mollie API key is required')
|
||||
}
|
||||
|
||||
const singleton = createSingleton<MollieClient>(symbol)
|
||||
return {
|
||||
key: 'mollie',
|
||||
onConfig: (config, pluginConfig) => {
|
||||
// Always register Mollie webhook since it doesn't require a separate webhook secret
|
||||
// Mollie validates webhooks through payment ID verification
|
||||
config.endpoints = [
|
||||
...(config.endpoints || []),
|
||||
{
|
||||
@@ -77,7 +84,7 @@ export const mollieProvider = (mollieConfig: MollieProviderConfig & {
|
||||
const status = mapMollieStatusToPaymentStatus(molliePayment.status)
|
||||
|
||||
// Update the payment status and provider data
|
||||
await updatePaymentStatus(
|
||||
const updateSuccess = await updatePaymentStatus(
|
||||
payload,
|
||||
payment.id,
|
||||
status,
|
||||
@@ -85,9 +92,11 @@ export const mollieProvider = (mollieConfig: MollieProviderConfig & {
|
||||
pluginConfig
|
||||
)
|
||||
|
||||
// If payment is successful and linked to an invoice, update the invoice
|
||||
if (status === 'succeeded') {
|
||||
// If payment is successful and update succeeded, update the invoice
|
||||
if (status === 'succeeded' && updateSuccess) {
|
||||
await updateInvoiceOnPaymentSuccess(payload, payment, pluginConfig)
|
||||
} else if (!updateSuccess) {
|
||||
console.warn(`[Mollie Webhook] Failed to update payment ${payment.id}, skipping invoice update`)
|
||||
}
|
||||
|
||||
return webhookResponses.success()
|
||||
|
||||
Reference in New Issue
Block a user