51 lines
1.9 KiB
PHP
51 lines
1.9 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace Modules\Core\Payment\Drivers;
|
||
|
|
|
||
|
|
use Illuminate\Support\Str;
|
||
|
|
use Lunar\DataTypes\Price;
|
||
|
|
use Modules\Core\Payment\Contracts\Configurable;
|
||
|
|
use Modules\Core\Payment\Contracts\SupportsPay;
|
||
|
|
use Modules\Core\Payment\DTOs\PaymentResult;
|
||
|
|
use Modules\Core\Payment\Enums\PaymentResultStatus;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Cash-on-delivery/cash-on-pickup — the shopper pays staff in person, at
|
||
|
|
* delivery or pickup, not at checkout, and reconciliation can happen
|
||
|
|
* anywhere from same-day to months later, entirely independent of the
|
||
|
|
* order's fulfillment progress (this is WHY Order::paid is its own field,
|
||
|
|
* not a status-sequence step — see Modules\Core\Order\Services\
|
||
|
|
* OrderStatusFlow's own docblock).
|
||
|
|
*
|
||
|
|
* Unlike OfflinePaymentDriver (cash-in-hand, immediate capture), pay()
|
||
|
|
* here must NOT dispatch PaymentCaptured — doing so would immediately
|
||
|
|
* flip Order::paid via Modules\Core\Order\Listeners\
|
||
|
|
* ApplyResolvedPaymentStatus, which is exactly wrong: no money has
|
||
|
|
* changed hands yet. Returns PaymentResultStatus::Pending instead — the
|
||
|
|
* documented convention for "unresolved" (see SupportsPay's own
|
||
|
|
* docblock). ApplyResolvedPaymentStatus and RecordPaymentTransaction both
|
||
|
|
* only listen to Captured/Authorized/Voided/Refunded, so a Pending result
|
||
|
|
* triggers neither.
|
||
|
|
*
|
||
|
|
* Order::paid only ever becomes true for a COD order via staff explicitly
|
||
|
|
* marking it received (Modules\Core\Order\Services\
|
||
|
|
* OrderFulfillmentService::markPaid()), offered by the single "Update
|
||
|
|
* Status" action at any time, independent of status.
|
||
|
|
*/
|
||
|
|
class CashOnDeliveryPaymentDriver implements Configurable, SupportsPay
|
||
|
|
{
|
||
|
|
public function isConfigured(): bool
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function pay(string $type, Price $amount, array $data = [], array $context = []): PaymentResult
|
||
|
|
{
|
||
|
|
return new PaymentResult(
|
||
|
|
status: PaymentResultStatus::Pending,
|
||
|
|
reference: 'cod-'.Str::uuid(),
|
||
|
|
amount: $amount,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|