Abo: Kreditkarte aktualisieren (CRM, Portal, Berater-Link) + Admin-Abo-Löschung
- Karten-Update ohne Abbuchung via PAYONE creditcardcheck/pseudocardpan (AboPaymentMethodService, CardUpdateResult/CreditCardCheckData-DTOs) - Eingabe nur durch Abo-Inhaber: CRM- und Portal-Formular + zeitlich begrenzter Berater→Kunde-Link (AboCardUpdateLink + Mail) - Änderungshistorie in user_abo_card_changes, Anzeige im Admin-Abo-Detail - Admin: Abo löschen (destroy) inkl. Test - Portal-Fix: myOrderCreate wirft 404 statt TypeError bei ungültiger ID - VIP-Sichtbarkeitstests für Einmalartikel-Fenster ergänzt - Enthält bereits die Freeze-Guards für den Stripe-Notbetrieb (Folge-Commit) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
63c36555a5
commit
671022a28d
36 changed files with 2366 additions and 26 deletions
107
resources/views/portal/abo/_payment_method_form.blade.php
Normal file
107
resources/views/portal/abo/_payment_method_form.blade.php
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="font-weight-bold">{{ __('abo.update_card_title') }}</h5>
|
||||
@if(app(\App\Services\Payment\PaymentProviderManager::class)->aboPaymentsFrozen())
|
||||
<div class="alert alert-warning mb-0">
|
||||
<strong>{{ __('payment.abo_payments_frozen_title') }}</strong><br>
|
||||
{{ __('payment.abo_payments_frozen') }}
|
||||
</div>
|
||||
<a href="{{ $backUrl ?? route('portal.my_subscriptions') }}" class="btn btn-default mt-3">{{ __('abo.back') }}</a>
|
||||
@else
|
||||
<p class="text-muted">{{ __('abo.card_update_intro') }}</p>
|
||||
|
||||
|
||||
|
||||
@if (isset($errors) && $errors->any())
|
||||
<div class="alert alert-danger p-2">
|
||||
<ul class="mb-0">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Session::has('alert-error'))
|
||||
<div class="alert alert-danger p-2">{{ Session::get('alert-error') }}</div>
|
||||
@endif
|
||||
|
||||
@if ($user_abo->maskedCard())
|
||||
<div class="alert alert-info p-2">
|
||||
<i class="ion ion-md-card mr-2" style="font-size: 1.2rem; line-height: 1rem;"></i>
|
||||
<span>{{ __('abo.current_card') }}: <strong>{{ $user_abo->maskedCard() }}</strong></span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ $formAction ?? route('portal_abos_payment_method_update', [$user_abo->id]) }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cc_cardtype">{{ __('payment.credit_card') }}*</label>
|
||||
<select id="cc_cardtype" name="cc_cardtype" class="form-control custom-select">
|
||||
<option value="V" @if (old('cc_cardtype') === 'V') selected @endif>{{ __('payment.VISA') }}
|
||||
</option>
|
||||
<option value="M" @if (old('cc_cardtype') === 'M') selected @endif>
|
||||
{{ __('payment.Mastercard') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label>{{ __('payment.owner') }}*</label>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<input type="text" name="cc_cardholder_first" id="cc_cardholder_first" class="form-control"
|
||||
value="{{ old('cc_cardholder_first') }}" placeholder="{{ __('First name') }}">
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<input type="text" name="cc_cardholder_last" id="cc_cardholder_last" class="form-control"
|
||||
value="{{ old('cc_cardholder_last') }}" placeholder="{{ __('Last name') }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label>{{ __('payment.credit_card_number') }}*</label>
|
||||
<input type="text" name="cc_cardpan" id="cc_cardpan" class="form-control"
|
||||
value="{{ old('cc_cardpan') }}" placeholder="{{ __('payment.credit_card_number') }}"
|
||||
inputmode="numeric" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-6">
|
||||
<label for="cc_cardexpiremonth">{{ __('payment.valid') }}
|
||||
{{ __('validation.attributes.month') }}*</label>
|
||||
<select id="cc_cardexpiremonth" name="cc_cardexpiremonth" class="form-control custom-select">
|
||||
@foreach (range(1, 12) as $month)
|
||||
@php($month = sprintf('%02d', $month))
|
||||
<option value="{{ $month }}" @if (old('cc_cardexpiremonth') === $month) selected @endif>
|
||||
{{ $month }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="cc_cardexpireyear">{{ __('payment.valid') }}
|
||||
{{ __('validation.attributes.year') }}*</label>
|
||||
<select id="cc_cardexpireyear" name="cc_cardexpireyear" class="form-control custom-select">
|
||||
@foreach (range(date('Y'), date('Y', strtotime('+10 years'))) as $year)
|
||||
<option value="{{ $year }}" @if (old('cc_cardexpireyear') === (string) $year) selected @endif>
|
||||
{{ $year }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="cc_cardcvc2">{{ __('payment.verification_no') }}*</label>
|
||||
<input type="text" name="cc_cardcvc2" id="cc_cardcvc2" class="form-control"
|
||||
value="{{ old('cc_cardcvc2') }}" placeholder="CVC*" inputmode="numeric" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
||||
<i class="ion ion-md-lock mr-2" style="font-size: 1.5rem; line-height: 1;"></i>
|
||||
<span>{{ __('abo.card_security_notice') }}</span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2">{{ __('abo.update_payment_method') }}</button>
|
||||
<a href="{{ $backUrl ?? route('portal.my_subscriptions') }}" class="btn btn-default mt-2">{{ __('abo.back') }}</a>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
20
resources/views/portal/abo/card_update_done.blade.php
Normal file
20
resources/views/portal/abo/card_update_done.blade.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
@extends('portal.layouts.public')
|
||||
|
||||
@section('content')
|
||||
<div class="text-center" style="max-width: 640px; margin: 0 auto;">
|
||||
@if ($success)
|
||||
<i class="ion ion-md-checkmark-circle text-success" style="font-size: 3rem;"></i>
|
||||
<h4 class="font-weight-bold mt-3">{{ __('abo.card_update_done_success_title') }}</h4>
|
||||
<p class="text-muted">{{ __('abo.card_update_done_success_copy') }}</p>
|
||||
@else
|
||||
<i class="ion ion-md-close-circle text-danger" style="font-size: 3rem;"></i>
|
||||
<h4 class="font-weight-bold mt-3">{{ __('abo.card_update_done_failed_title') }}</h4>
|
||||
<p class="text-muted">{{ __('abo.card_update_done_failed_copy') }}</p>
|
||||
@endif
|
||||
|
||||
<p class="text-muted mt-3">{{ __('abo.card_update_portal_hint') }}</p>
|
||||
<a href="{{ \App\Services\Util::getMyMivitaPortalUrl() }}" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="ion ion-md-home mr-1"></i>{{ __('abo.card_update_to_portal') }}
|
||||
</a>
|
||||
</div>
|
||||
@endsection
|
||||
20
resources/views/portal/abo/card_update_link.blade.php
Normal file
20
resources/views/portal/abo/card_update_link.blade.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
@extends('portal.layouts.public')
|
||||
|
||||
@section('content')
|
||||
<div style="max-width: 640px; margin: 0 auto;">
|
||||
<h4 class="font-weight-bold mb-3">{{ __('abo.update_card_title') }}</h4>
|
||||
|
||||
@include('portal.abo._payment_method_form', [
|
||||
'user_abo' => $user_abo,
|
||||
'formAction' => route('abo_card_update_store', [$token]),
|
||||
'backUrl' => \App\Services\Util::getMyMivitaPortalUrl(),
|
||||
])
|
||||
|
||||
<div class="alert alert-light border mt-3 text-center">
|
||||
<p class="mb-2 text-muted">{{ __('abo.card_update_portal_hint') }}</p>
|
||||
<a href="{{ \App\Services\Util::getMyMivitaPortalUrl() }}" class="btn btn-secondary btn-sm">
|
||||
<i class="ion ion-md-home mr-1"></i>{{ __('abo.card_update_to_portal') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
12
resources/views/portal/abo/payment_method.blade.php
Normal file
12
resources/views/portal/abo/payment_method.blade.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
@extends('portal.layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
{{ __('abo.update_card_title') }}
|
||||
<span class="text-muted">{{ '#' . $user_abo->payone_userid }}</span>
|
||||
</h4>
|
||||
|
||||
@include('portal.abo._payment_method_form', ['user_abo' => $user_abo])
|
||||
|
||||
@endsection
|
||||
Loading…
Add table
Add a link
Reference in a new issue