fix: Evitar criação de faturas duplicadas no webhook PayPal

🐛 PROBLEMA IDENTIFICADO:
- Cliente pagava 1 assinatura mas recebia 2 faturas
- Fatura 1: subscription_create (método confirm())
- Fatura 2: subscription_cycle (webhook PAYMENT.SALE.COMPLETED)
- Ambas criadas com 8 segundos de diferença

 SOLUÇÃO IMPLEMENTADA:

handlePaymentCompleted() agora verifica:

1. Se já existe fatura com mesmo paypal_payment_id
   - Evita duplicação por webhook reprocessado

2. Se já existe fatura paga HOJE para esta subscription
   - Evita duplicação do pagamento inicial
   - Webhook vem depois do confirm()

3. Só cria nova fatura se for pagamento recorrente genuíno

📊 RESULTADO:
- Pagamento inicial: 1 fatura (subscription_create)
- Renovação mensal/anual: 1 fatura (subscription_cycle)
- Webhooks duplicados: ignorados com log

🗑️ LIMPEZA:
- Removida fatura duplicada WM-2025-000002 do user_id 35
This commit is contained in:
marco 2025-12-19 17:20:12 +01:00
parent 02529adc18
commit 0a10fd0194

View File

@ -843,6 +843,38 @@ private function handlePaymentCompleted(array $resource): void
$subscription = Subscription::where('paypal_subscription_id', $billingAgreementId)->first();
if (!$subscription) return;
$paymentId = $resource['id'] ?? null;
// Check if invoice already exists for this payment (avoid duplicates)
if ($paymentId) {
$existingInvoice = Invoice::where('paypal_payment_id', $paymentId)
->orWhere('paypal_capture_id', $paymentId)
->first();
if ($existingInvoice) {
Log::info('Invoice already exists for this payment', [
'payment_id' => $paymentId,
'invoice_id' => $existingInvoice->id,
]);
return;
}
}
// Check if a paid invoice was already created for this subscription today (initial payment)
$todayInvoice = Invoice::where('subscription_id', $subscription->id)
->where('status', Invoice::STATUS_PAID)
->whereDate('created_at', today())
->first();
if ($todayInvoice) {
Log::info('Invoice already created today for subscription, skipping duplicate', [
'subscription_id' => $subscription->id,
'existing_invoice_id' => $todayInvoice->id,
'payment_id' => $paymentId,
]);
return;
}
// Create invoice for recurring payment
$invoice = Invoice::createForSubscription(
$subscription,