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:
parent
02529adc18
commit
0a10fd0194
@ -843,6 +843,38 @@ private function handlePaymentCompleted(array $resource): void
|
|||||||
$subscription = Subscription::where('paypal_subscription_id', $billingAgreementId)->first();
|
$subscription = Subscription::where('paypal_subscription_id', $billingAgreementId)->first();
|
||||||
if (!$subscription) return;
|
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
|
// Create invoice for recurring payment
|
||||||
$invoice = Invoice::createForSubscription(
|
$invoice = Invoice::createForSubscription(
|
||||||
$subscription,
|
$subscription,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user