Abo-Recovery: fehlgeschlagene Folgezahlung im Checkout nachholen
- Pay-now-Flow: bei fehlgeschlagenem Abo (Status 3) begleicht der Inhaber die offene Rechnung im Standard-Checkout mit frei waehlbarer, abo-faehiger Zahlart (nur eigenes Abo: Berater me-View + Kundenportal), payNow-Controller + Routen - AboRecoveryCheckoutService baut die ShoppingInstance aus den Abo-Artikeln; neue Spalte shopping_orders.recovery_user_abo_id verknuepft Bestellung<->Abo - Bei Erfolg: AboHelper::advanceAboAfterRecoveryPayment schreibt das Abo fort (Status->2, next_date) und uebernimmt die gewaehlte Zahlart als neues Token fuer kuenftige Abbuchungen - Neue Pay-now-Fehlermail (AboPaymentFailedMail) ersetzt die generische Fehlermail im Abo-Cron; Link fuehrt auf die Abo-Detailseite (CRM bzw. Portal) - Retry-/"extern erledigt"-Buttons nur noch fuer Admins; tote user/portal- Retry-Routen entfernt - Checkout: Recovery-Hinweis statt "Abschluss des Abonnements", Lieferadresse vorbelegt, korrekter Zurueck-Link (Abo statt Shop) - UserAbo::selfServiceDetailUrl zentralisiert die Abo-URL (Mail, Back-Links) - Test-Command abo:test-recovery; Tests fuer payNow, Advance-Logik, Fehlermail Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
78db952130
commit
0660f4e0a0
28 changed files with 1535 additions and 181 deletions
42
tests/Feature/AboPaymentFailedMailTest.php
Normal file
42
tests/Feature/AboPaymentFailedMailTest.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use App\Mail\AboPaymentFailedMail;
|
||||
use App\Models\UserAbo;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(Tests\TestCase::class, RefreshDatabase::class);
|
||||
|
||||
function makeFailedAbo(string $isFor): UserAbo
|
||||
{
|
||||
return UserAbo::create([
|
||||
'user_id' => 1,
|
||||
'member_id' => 1,
|
||||
'shopping_user_id' => 1,
|
||||
'is_for' => $isFor,
|
||||
'email' => 'owner-'.uniqid('', true).'@example.com',
|
||||
'payone_userid' => 500100,
|
||||
'clearingtype' => 'cc',
|
||||
'active' => true,
|
||||
'status' => 3,
|
||||
'abo_interval' => 5,
|
||||
'next_date' => now()->toDateString(),
|
||||
]);
|
||||
}
|
||||
|
||||
it('verlinkt bei einem Berater-Abo (me) auf die CRM-Detailseite', function () {
|
||||
$abo = makeFailedAbo('me');
|
||||
|
||||
$mail = (new AboPaymentFailedMail($abo))->build();
|
||||
|
||||
expect($mail->viewData['link'])->toContain('/user/abos/detail/me/'.$abo->id);
|
||||
expect($mail->subject)->toBe(__('abo.payment_failed_mail_subject'));
|
||||
});
|
||||
|
||||
it('verlinkt bei einem Kunden-Abo (ot) auf das Kundenportal', function () {
|
||||
$abo = makeFailedAbo('ot');
|
||||
|
||||
$mail = (new AboPaymentFailedMail($abo))->build();
|
||||
|
||||
expect($mail->viewData['link'])->toContain('/portal/my-subscriptions');
|
||||
expect($mail->viewData['link'])->not->toContain('/user/abos/detail');
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue