47 lines
1.8 KiB
PHP
47 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace Modules\Core\Payment\Events;
|
|
|
|
use Illuminate\Foundation\Events\Dispatchable;
|
|
use Modules\Core\Payment\DTOs\PaymentResult;
|
|
|
|
/**
|
|
* "This order has no money to collect yet, and never will via a gateway
|
|
* callback — nothing further will ever resolve this PaymentResult's
|
|
* Pending status into Captured/Authorized." Distinct from a Stripe-style
|
|
* Pending (3-D Secure, still resolving asynchronously via a later webhook
|
|
* or client-side confirmation) — that case correctly dispatches nothing
|
|
* yet, since PaymentCaptured/PaymentAuthorized WILL still follow once
|
|
* resolved.
|
|
*
|
|
* Dispatched by Modules\Core\Payment\Drivers\CashOnDeliveryPaymentDriver::
|
|
* pay() the moment it returns Pending — a COD order is fully placed at
|
|
* that instant, with reconciliation (Order::paid) happening independently,
|
|
* anywhere from same-day to months later, entirely outside any gateway's
|
|
* knowledge. Any other current or future "deferred capture, no gateway
|
|
* callback" driver dispatches this the same way, rather than each
|
|
* reinventing its own "mark placed" event.
|
|
*
|
|
* Handled by Modules\Core\Order\Listeners\MarkOrderPlacedOnDeferredPayment
|
|
* — sets ONLY Order::placed_at and fires Checkout\Events\OrderPlaced.
|
|
* Deliberately does not touch Order::paid/paid_at (see
|
|
* OrderStatusWriter::markPaid(), the only path that ever does) or create a
|
|
* Transaction row (RecordPaymentTransaction listens to PaymentCaptured/
|
|
* PaymentAuthorized/PaymentVoided/PaymentRefunded only — correctly not
|
|
* this event, since no money has moved and there is nothing to record
|
|
* yet).
|
|
*/
|
|
class PaymentDeferred
|
|
{
|
|
use Dispatchable;
|
|
|
|
/**
|
|
* @param array<string, mixed> $context
|
|
*/
|
|
public function __construct(
|
|
public readonly string $type,
|
|
public readonly PaymentResult $result,
|
|
public readonly array $context = [],
|
|
) {}
|
|
}
|