CluPilotCloud/app/Livewire/OpenInvoices.php

78 lines
2.6 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\Customer;
use App\Services\Stripe\StripeClient;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
/**
* Was der Kunde noch schuldet, und der Knopf, es zu begleichen.
*
* Die Liste kommt bei jedem Rendern frisch von Stripe. Eine zwischengelagerte
* Kopie zeigte einen Bezahlknopf neben einer Rechnung, die inzwischen beglichen
* ist — und der zweite Klick wäre eine zweite Abbuchung.
*/
class OpenInvoices extends Component
{
/**
* Was Stripe zur letzten Zahlung gesagt hat, wenn sie nicht durchging.
*
* Stripes eigener Wortlaut, nicht eine eigene Umschreibung: er nennt den
* Grund — abgelaufen, abgelehnt, Deckung — und danach kann der Kunde
* handeln. „Zahlung fehlgeschlagen" könnte er nur weiterreichen.
*/
public ?string $failure = null;
public function pay(string $invoiceId): void
{
$stripe = app(StripeClient::class);
$customerId = $this->stripeCustomerId();
// Die ID kommt aus dem Browser. Nur was in DIESER Liste steht, darf
// eingezogen werden — sonst reicht jemand eine fremde Rechnungs-ID ein
// und Stripe bucht sie von der Karte eines fremden Kunden ab.
$offen = array_column($stripe->openInvoices($customerId), 'id');
abort_unless(in_array($invoiceId, $offen, true), 403);
$ergebnis = $stripe->payInvoice($invoiceId);
$this->failure = $ergebnis['paid'] ? null : $ergebnis['failure'];
if ($ergebnis['paid']) {
$this->dispatch('notify', message: __('billing.invoice_paid'));
}
}
public function payAll(): void
{
foreach (app(StripeClient::class)->openInvoices($this->stripeCustomerId()) as $rechnung) {
$this->pay($rechnung['id']);
// Nach der ersten Ablehnung anhalten. Alle weiteren scheitern an
// derselben Karte, und drei Ablehnungen hintereinander lassen
// Stripes Betrugserkennung anschlagen — danach lehnt sie auch die
// Karte ab, die in Ordnung wäre.
if ($this->failure !== null) {
return;
}
}
}
private function stripeCustomerId(): string
{
$customer = Customer::forUser(Auth::user());
abort_if($customer === null || blank($customer->stripe_customer_id), 404);
return (string) $customer->stripe_customer_id;
}
public function render()
{
return view('livewire.open-invoices', [
'invoices' => app(StripeClient::class)->openInvoices($this->stripeCustomerId()),
]);
}
}