Files
fotospiel-app/app/Notifications/Customer/WithdrawalConfirmed.php
Codex Agent 42b4b647d7 • Added the two‑step Widerruf flow with an auth‑only CTA on the Widerrufsbelehrung page and a dedicated confirmation
screen where users pick an eligible end‑customer purchase and confirm. Eligibility is enforced server‑side
  (endcustomer_event, within 14 days, no event package created after purchase), refund is issued via Paddle, the
  purchase is marked refunded, the tenant package is deactivated, and a new confirmation email is sent using resources/
  views/emails/partials/layout.blade.php.

  Details

  - New controller + form request for the confirm flow: app/Http/Controllers/WithdrawalController.php, app/Http/
    Requests/Marketing/WithdrawalConfirmRequest.php
  - New confirmation page + CTA: resources/js/pages/marketing/WithdrawalConfirm.tsx, resources/js/pages/legal/Show.tsx
  - Routes + locale rewrites: routes/web.php, resources/js/lib/localizedPath.ts
  - New email notification + template: app/Notifications/Customer/WithdrawalConfirmed.php, resources/views/emails/
    withdrawal-confirmation.blade.php
  - Translations added for marketing UI + backend flash + email copy: public/lang/de/marketing.json, public/lang/en/
    marketing.json, resources/lang/de/marketing.php, resources/lang/en/marketing.php, resources/lang/de/emails.php,
    resources/lang/en/emails.php
  - Tests: tests/Feature/Marketing/WithdrawalConfirmationTest.php
2025-12-24 11:54:15 +01:00

62 lines
2.0 KiB
PHP

<?php
namespace App\Notifications\Customer;
use App\Models\PackagePurchase;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Carbon;
class WithdrawalConfirmed extends Notification implements ShouldQueue
{
use Queueable;
public function __construct(
private readonly PackagePurchase $purchase,
private readonly Carbon $confirmedAt,
) {}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
$tenant = $this->purchase->tenant;
$package = $this->purchase->package;
$amount = number_format((float) $this->purchase->price, 2);
$currency = data_get($this->purchase->metadata, 'currency', 'EUR');
$locale = app()->getLocale();
$packageName = $package?->getNameForLocale($locale)
?? $package?->name
?? __('emails.package_limits.package_fallback', [], $locale);
$subject = __('emails.withdrawal_confirmation.subject', ['package' => $packageName]);
$greeting = __('emails.withdrawal_confirmation.greeting', [
'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
]);
return (new MailMessage)
->subject($subject)
->view('emails.withdrawal-confirmation', [
'subject' => $subject,
'greeting' => $greeting,
'packageName' => $packageName,
'amount' => $amount,
'currency' => $currency,
'providerId' => $this->purchase->provider_id ?? '—',
'confirmedAt' => $this->confirmedAt,
]);
}
}