billing: Nebenläufigkeit & Idempotenz härten (H4, Stripe, Boost-Slots)
- CreditTopup-Gutschrift, MAN-Rechnung, Proof-PDF und Stripe-Webhook- Spiegelung sperren die betroffene Zeile innerhalb der Transaktion und prüfen die Idempotenz erst danach (verhindert Doppelgutschrift bei at-least-once-Webhooks, H4). - Gemeinsamer LocksModelForUpdate-Trait für die häufige Lock-by-Key-Form (CreditTopup, ManualInvoice). - Unique-Index auf invoices.stripe_invoice_id; Boost-Inventar über boost_slot_locks serialisiert, verwaiste Kategorie-Locks werden beim Löschen der Rubrik entfernt. Deployment: vor migrate prüfen, ob invoices.stripe_invoice_id bereits Duplikate enthält (die Unique-Migration bricht sonst bewusst ab). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
3295f47556
commit
aae456954a
14 changed files with 418 additions and 106 deletions
|
|
@ -53,16 +53,21 @@ class ProofPdfService
|
|||
throw ProofPdfNotAvailableException::notPublished();
|
||||
}
|
||||
|
||||
$existing = $this->purchaseQuery($user, $pressRelease)->first();
|
||||
|
||||
if ($existing) {
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$credits = $this->priceCredits();
|
||||
|
||||
return DB::transaction(function () use ($user, $pressRelease, $credits): SinglePurchase {
|
||||
$purchase = $user->singlePurchases()->create([
|
||||
$lockedUser = User::query()
|
||||
->whereKey($user->getKey())
|
||||
->lockForUpdate()
|
||||
->firstOrFail();
|
||||
|
||||
$existing = $this->purchaseQuery($lockedUser, $pressRelease)->first();
|
||||
|
||||
if ($existing) {
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$purchase = $lockedUser->singlePurchases()->create([
|
||||
'type' => SinglePurchaseType::ProofPdf,
|
||||
'status' => SinglePurchaseStatus::Paid,
|
||||
'price_cents' => $credits * 100,
|
||||
|
|
@ -72,7 +77,7 @@ class ProofPdfService
|
|||
]);
|
||||
|
||||
$this->wallet->debit(
|
||||
$user,
|
||||
$lockedUser,
|
||||
$credits,
|
||||
"Veröffentlichungsnachweis – PM #{$pressRelease->id}",
|
||||
$purchase,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue