268 lines
15 KiB
PHP
268 lines
15 KiB
PHP
@extends('layouts.layout-2')
|
||
|
||
@section('content')
|
||
|
||
<h4 class="font-weight-bold mb-3">
|
||
Payone-Callback Testbench
|
||
</h4>
|
||
|
||
<p class="text-muted mb-4">
|
||
<strong>Erstbestellung Abo (realistisch):</strong> Zuerst legt der Checkout das Abo an
|
||
(<code>CheckoutController</code> → <code>AboHelper::createNewAbo</code>), danach meldet Payone per
|
||
<code>POST {{ route('api.payment_status', [], true) }}</code> den Zahlungsstatus – dann laufen u. a.
|
||
<code>Payment::paymentStatusPaidAction</code>, Abo-Freischaltung (<code>setAboActive</code>) und
|
||
<code>IncentiveTracker::trackAboActivated</code>. Die Testbench-Schritte sind in dieser Reihenfolge angeordnet.
|
||
Nur außerhalb Production.
|
||
</p>
|
||
|
||
@if (session('error'))
|
||
<div class="alert alert-danger">{{ session('error') }}</div>
|
||
@endif
|
||
|
||
<div class="card mb-4">
|
||
<div class="card-header font-weight-bold">1. Test-Bestellung anlegen</div>
|
||
<div class="card-body">
|
||
<form method="post" action="{{ route('sysadmin_tool_store', ['payone_callback_testbench']) }}">
|
||
@csrf
|
||
<input type="hidden" name="action" value="create_fixture">
|
||
|
||
<div class="form-group row">
|
||
<label class="col-md-3 col-form-label">Betrag (Brutto EUR)</label>
|
||
<div class="col-md-4">
|
||
<input type="number" name="amount_eur" class="form-control" step="0.01" min="0.01"
|
||
value="{{ old('amount_eur', '119.00') }}" required>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group row">
|
||
<label class="col-md-3 col-form-label">Berater (users.id)</label>
|
||
<div class="col-md-4">
|
||
<input type="number" name="consultant_user_id" class="form-control" min="1"
|
||
value="{{ old('consultant_user_id', '454') }}" required>
|
||
</div>
|
||
<div class="col-md-5">
|
||
<small class="form-text text-muted">
|
||
Bei <code>is_for = me</code> wird <code>auth_user_id</code> gesetzt; bei <code>ot</code> bleibt
|
||
<code>auth_user_id</code> leer und <code>member_id</code> wird auf diese Berater-ID gesetzt.
|
||
</small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group row">
|
||
<div class="col-md-6 offset-md-3">
|
||
<div class="form-check">
|
||
<input type="checkbox" name="is_abo" id="is_abo" class="form-check-input" value="1"
|
||
{{ old('is_abo') ? 'checked' : '' }}>
|
||
<label class="form-check-label" for="is_abo">Als Abo-Bestellung (<code>is_abo</code>)</label>
|
||
</div>
|
||
<div class="form-check mt-2">
|
||
<input type="checkbox" name="is_for_ot" id="is_for_ot" class="form-check-input" value="1"
|
||
{{ old('is_for_ot', true) ? 'checked' : '' }}>
|
||
<label class="form-check-label" for="is_for_ot">Kundenkontext <code>is_for = ot</code> (für
|
||
Incentive <code>trackAboActivated</code>)</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group row">
|
||
<div class="col-md-6 offset-md-3">
|
||
<button type="submit" class="btn btn-primary">Bestellung + Zahlung anlegen</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
@if (!empty($fixture))
|
||
<div class="card mb-4 border-success">
|
||
<div class="card-header font-weight-bold text-success">Angelegte Testdaten</div>
|
||
<div class="card-body">
|
||
<dl class="row mb-0">
|
||
<dt class="col-sm-3">shopping_order_id</dt>
|
||
<dd class="col-sm-9"><code>{{ $fixture['shopping_order_id'] }}</code></dd>
|
||
<dt class="col-sm-3">shopping_payment_id</dt>
|
||
<dd class="col-sm-9"><code>{{ $fixture['shopping_payment_id'] }}</code></dd>
|
||
<dt class="col-sm-3">reference (16)</dt>
|
||
<dd class="col-sm-9"><code>{{ $fixture['reference'] }}</code></dd>
|
||
<dt class="col-sm-3">amount (Cent)</dt>
|
||
<dd class="col-sm-9"><code>{{ $fixture['amount_cents'] }}</code> (=
|
||
{{ number_format($fixture['amount_eur'], 2, ',', '.') }} €)</dd>
|
||
<dt class="col-sm-3">Berater-ID</dt>
|
||
<dd class="col-sm-9"><code>{{ $fixture['consultant_user_id'] ?? '–' }}</code></dd>
|
||
<dt class="col-sm-3">Zuordnung</dt>
|
||
<dd class="col-sm-9"><small>{{ $fixture['assignment_note'] ?? '' }}</small></dd>
|
||
<dt class="col-sm-3">API-URL</dt>
|
||
<dd class="col-sm-9"><small class="text-break">{{ $fixture['api_url'] }}</small></dd>
|
||
</dl>
|
||
|
||
<hr>
|
||
<p class="mb-2 font-weight-bold">2. Checkout-Erfolg (nur Abo)</p>
|
||
<p class="small text-muted mb-2">
|
||
Wie <code>handleSuccessfulTransaction</code> / <code>transactionApproved</code>:
|
||
<code>AboHelper::createNewAbo($ShoppingPayment)</code> – legt UserAbo + UserAboOrder an.
|
||
Ohne vorherige <code>payment_transactions</code> wird eine Minimal-Transaktion angelegt.
|
||
</p>
|
||
@if (!empty($fixture['is_abo']))
|
||
<form method="post" action="{{ route('sysadmin_tool_store', ['payone_callback_testbench']) }}"
|
||
class="d-inline">
|
||
@csrf
|
||
<input type="hidden" name="action" value="simulate_checkout_success">
|
||
<input type="hidden" name="shopping_order_id" value="{{ $fixture['shopping_order_id'] }}">
|
||
<button type="submit" class="btn btn-success">Abo anlegen (<code>createNewAbo</code>)</button>
|
||
</form>
|
||
@else
|
||
<p class="small text-muted mb-0">Nicht-Abo – Schritt entfällt.</p>
|
||
@endif
|
||
|
||
<hr>
|
||
<p class="mb-2 font-weight-bold">3. Payone-API: Zahlung bestätigt (<code>paid</code>)</p>
|
||
<p class="small text-muted mb-2">
|
||
<code>Api\PayoneController::paymentStatus</code> → <code>Payment::paymentStatusPaidAction</code>
|
||
(Abo freischalten, Incentive, …). Bei Abo-Erstbestellung nur nach Schritt 2 (sonst Fehlermeldung).
|
||
</p>
|
||
<form method="post" action="{{ route('sysadmin_tool_store', ['payone_callback_testbench']) }}"
|
||
class="d-inline mr-2">
|
||
@csrf
|
||
<input type="hidden" name="action" value="simulate_paid">
|
||
<input type="hidden" name="shopping_order_id" value="{{ $fixture['shopping_order_id'] }}">
|
||
<button type="submit" class="btn btn-warning">Simulate <code>txaction=paid</code> (Erstbestellung)</button>
|
||
</form>
|
||
<form method="post" action="{{ route('sysadmin_tool_store', ['payone_callback_testbench']) }}"
|
||
class="d-inline">
|
||
@csrf
|
||
<input type="hidden" name="action" value="clear_fixture">
|
||
<button type="submit" class="btn btn-outline-secondary btn-sm">Session-Daten löschen</button>
|
||
</form>
|
||
|
||
@php
|
||
$benchUserAboId = $userAboId ?? ($checkoutSuccess['user_abo_id'] ?? null);
|
||
@endphp
|
||
@if (!empty($fixture['is_abo']) && $benchUserAboId)
|
||
<hr>
|
||
<p class="mb-2 font-weight-bold">4. Abo-Verlängerung (wie <code>user:make_abo_order</code> / Cron)</p>
|
||
<p class="small text-muted mb-2">
|
||
Setzt <code>next_date</code> auf heute, entfernt ggf. heutige <code>user_abo_orders</code> (Test-Wiederholung),
|
||
führt dann <code>UserMakeAboOrder::makeOrder</code> aus (neue Bestellung + Payone). Anschließend Incentive-Zähler
|
||
(z. B. qualifizierte Abos) und Umsatzpunkte prüfen – für Rechnung/SV wie in Produktion Schritt 5.
|
||
</p>
|
||
<form method="post" action="{{ route('sysadmin_tool_store', ['payone_callback_testbench']) }}"
|
||
class="mb-3">
|
||
@csrf
|
||
<input type="hidden" name="action" value="simulate_cron_renewal">
|
||
<div class="form-group row align-items-center">
|
||
<label class="col-md-3 col-form-label"><code>user_abos.id</code></label>
|
||
<div class="col-md-4">
|
||
<input type="number" name="user_abo_id" class="form-control" min="1"
|
||
value="{{ old('user_abo_id', $benchUserAboId) }}">
|
||
</div>
|
||
<div class="col-md-5">
|
||
<small class="form-text text-muted mb-0">Standard aus Session nach Schritt 2/3; anpassbar.</small>
|
||
</div>
|
||
</div>
|
||
<button type="submit" class="btn btn-outline-primary">Cron-Verlängerung ausführen</button>
|
||
</form>
|
||
@endif
|
||
|
||
@if (!empty($cronRenewalOrderId))
|
||
<hr>
|
||
<p class="mb-2 font-weight-bold">5. Payone-API: Verlängerung bestätigt (<code>paid</code>)</p>
|
||
<p class="small text-muted mb-2">
|
||
Wie Server-zu-Server-Callback nach Cron-Zahlung: <code>Payment::paymentStatusPaidAction</code> (Rechnung,
|
||
<code>createAndSalesVolume</code> → <code>IncentiveTracker::trackSalesVolume</code>, …).
|
||
</p>
|
||
<form method="post" action="{{ route('sysadmin_tool_store', ['payone_callback_testbench']) }}"
|
||
class="d-inline">
|
||
@csrf
|
||
<input type="hidden" name="action" value="simulate_paid">
|
||
<input type="hidden" name="shopping_order_id" value="{{ $cronRenewalOrderId }}">
|
||
<button type="submit" class="btn btn-warning">Simulate <code>txaction=paid</code> (Verlängerung)</button>
|
||
</form>
|
||
@endif
|
||
|
||
<hr>
|
||
<p class="mb-2 font-weight-bold">Manuell (z. B. Postman / curl)</p>
|
||
<pre class="bg-light p-3 small text-break mb-0" style="white-space: pre-wrap;">{{ $fixture['curl'] }}</pre>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@if (!empty($simulateResult))
|
||
<div class="card mb-4 border-info">
|
||
<div class="card-header font-weight-bold">Ergebnis Schritt 3 (Payone-API)</div>
|
||
<div class="card-body">
|
||
@if (!empty($simulateResult['hint']))
|
||
<p class="small text-muted mb-3">{{ $simulateResult['hint'] }}</p>
|
||
@endif
|
||
<dl class="row">
|
||
<dt class="col-sm-3">HTTP (Kernel)</dt>
|
||
<dd class="col-sm-9"><code>{{ $simulateResult['http_status'] }}</code></dd>
|
||
<dt class="col-sm-3">Body</dt>
|
||
<dd class="col-sm-9"><code>{{ $simulateResult['body'] }}</code> <span class="text-muted">(Payone
|
||
erwartet TSOK)</span></dd>
|
||
<dt class="col-sm-3">Order paid</dt>
|
||
<dd class="col-sm-9">{{ $simulateResult['order_paid'] ? 'true' : 'false' }}</dd>
|
||
<dt class="col-sm-3">Order txaction</dt>
|
||
<dd class="col-sm-9"><code>{{ $simulateResult['order_txaction'] ?? 'null' }}</code></dd>
|
||
</dl>
|
||
<p class="mb-1 font-weight-bold">Gesendeter Payload</p>
|
||
<pre class="bg-light p-3 small mb-0">{{ json_encode($simulateResult['payload'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@if (!empty($checkoutSuccess))
|
||
<div class="card mb-4 border-success">
|
||
<div class="card-header font-weight-bold text-success">Ergebnis Schritt 2 (Checkout / createNewAbo)</div>
|
||
<div class="card-body">
|
||
<dl class="row mb-0">
|
||
<dt class="col-sm-3">user_abo_id</dt>
|
||
<dd class="col-sm-9"><code>{{ $checkoutSuccess['user_abo_id'] ?? '–' }}</code></dd>
|
||
<dt class="col-sm-3">user_abo_orders.id</dt>
|
||
<dd class="col-sm-9"><code>{{ $checkoutSuccess['user_abo_order_id'] ?? '–' }}</code></dd>
|
||
<dt class="col-sm-3">shopping_order_id</dt>
|
||
<dd class="col-sm-9"><code>{{ $checkoutSuccess['shopping_order_id'] ?? '–' }}</code></dd>
|
||
<dt class="col-sm-3">Order paid (nachher)</dt>
|
||
<dd class="col-sm-9">{{ !empty($checkoutSuccess['order_paid_after']) ? 'true' : 'false' }}</dd>
|
||
</dl>
|
||
@if (!empty($checkoutSuccess['hint']))
|
||
<p class="small text-muted mb-0 mt-2">{{ $checkoutSuccess['hint'] }}</p>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@if (!empty($cronRenewal))
|
||
<div class="card mb-4 border-primary">
|
||
<div class="card-header font-weight-bold text-primary">Ergebnis Schritt 4 (Cron-Verlängerung)</div>
|
||
<div class="card-body">
|
||
<dl class="row mb-0">
|
||
<dt class="col-sm-3">Erfolg</dt>
|
||
<dd class="col-sm-9">{{ !empty($cronRenewal['success']) ? 'true' : 'false' }}</dd>
|
||
@if (!empty($cronRenewal['shopping_order_id']))
|
||
<dt class="col-sm-3">Neue shopping_order_id</dt>
|
||
<dd class="col-sm-9"><code>{{ $cronRenewal['shopping_order_id'] }}</code></dd>
|
||
@endif
|
||
@if (!empty($cronRenewal['user_abo_id']))
|
||
<dt class="col-sm-3">user_abo_id</dt>
|
||
<dd class="col-sm-9"><code>{{ $cronRenewal['user_abo_id'] }}</code></dd>
|
||
@endif
|
||
@if (!empty($cronRenewal['message']))
|
||
<dt class="col-sm-3">Hinweis</dt>
|
||
<dd class="col-sm-9">{{ $cronRenewal['message'] }}</dd>
|
||
@endif
|
||
@if (!empty($cronRenewal['diagnosis']))
|
||
<dt class="col-sm-3">Diagnose</dt>
|
||
<dd class="col-sm-9">
|
||
<pre class="bg-light p-2 small mb-0 text-break"
|
||
style="white-space: pre-wrap;">{{ json_encode($cronRenewal['diagnosis'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
||
</dd>
|
||
@endif
|
||
</dl>
|
||
@if (!empty($cronRenewal['hint']))
|
||
<p class="small text-muted mb-0 mt-2">{{ $cronRenewal['hint'] }}</p>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@endsection
|