File: /home/xedaptot/ai.naniguide.com/app/Notifications/Admin/RemoteInvoiceFailed.php
<?php
namespace App\Notifications\Admin;
use App\Model\Customer;
use App\Model\Invoice;
use App\Model\PaymentGateway;
use App\Notifications\AppNotification;
use Illuminate\Database\Eloquent\Model;
/**
* A remote-managed subscription attempted an auto-billing charge and the
* vendor reported failure (declined / past_due).
*
* Severity=warning, category=alert — admin attention recommended:
* - Customer's card may have expired / insufficient funds
* - Vendor will retry per its own dunning rules (Stripe Smart Retries,
* Paddle's payment recovery), but admins may want to email the customer
* directly to reduce churn.
*
* Group key = remote_invoice_id → re-sync collapses into the same row.
* Body identifies customer + gateway + amount + currency + failure reason.
*/
class RemoteInvoiceFailed extends AppNotification
{
public function __construct(
public Invoice $invoice,
public Customer $customer,
public PaymentGateway $gateway,
public float $amount,
public string $currency,
public ?string $failureReason = null,
) {}
public function audience(): string { return self::AUDIENCE_ADMINS; }
public function category(): string { return self::CATEGORY_ALERT; }
public function severity(): string { return self::SEVERITY_WARNING; }
public function groupKey(): string
{
return 'remote-invoice-failed:' . ($this->invoice->remote_invoice_id ?: $this->invoice->id);
}
public function subject(): ?Model
{
return $this->invoice;
}
public function toArray(object $notifiable = null): array
{
$customerName = $this->customer->displayName() ?? $this->customer->name ?? 'Customer';
$amountStr = number_format($this->amount, 2) . ' ' . $this->currency;
$reasonSuffix = $this->failureReason ? ' Reason: ' . $this->failureReason . '.' : '';
return [
'title' => 'Recurring payment failed',
'body' => sprintf(
'%s — %s charge via %s declined.%s Vendor will retry automatically.',
$customerName,
$amountStr,
$this->gateway->name,
$reasonSuffix
),
'meta' => [
'remote_invoice_id' => $this->invoice->remote_invoice_id,
'gateway_id' => $this->gateway->id,
'gateway_name' => $this->gateway->name,
'gateway_type' => $this->gateway->type,
'customer_id' => $this->customer->id,
'customer_name' => $customerName,
'invoice_uid' => $this->invoice->uid,
'amount' => $this->amount,
'currency' => $this->currency,
'failure_reason' => $this->failureReason,
],
'action' => [
'label' => 'View invoice',
'route' => 'refactor.admin.invoices.index',
'params' => [],
],
];
}
}