Feat: Tying Specific Methods with Carrier Drivers
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Core\Payment\Contracts;
|
||||
|
||||
/**
|
||||
* Optional contract a payment driver implements to declare it only makes
|
||||
* sense for one fulfillment type — the payment-side mirror of
|
||||
* Modules\Core\Shipping\Contracts\DeclaresFulfillmentType. Two concrete
|
||||
* cases exist today, both hardcoded facts about the driver rather than a
|
||||
* merchant configuration choice:
|
||||
* - OfflinePaymentDriver ("pay in store," cash-in-hand) only makes
|
||||
* sense when the shopper collects in person — meaningless for a
|
||||
* carrier delivery, where no staff member is present to take the
|
||||
* cash.
|
||||
* - CashOnDeliveryPaymentDriver only makes sense when a carrier
|
||||
* physically hands over the parcel and collects payment at that
|
||||
* moment — meaningless for store pickup, which already has
|
||||
* OfflinePaymentDriver for exactly that in-person moment.
|
||||
*
|
||||
* A driver that doesn't implement this (Stripe, bank transfer) has no
|
||||
* fulfillment-type constraint — offered regardless of the cart's
|
||||
* currently selected shipping method's fulfillment type.
|
||||
*
|
||||
* Read by Modules\Core\Checkout\Services\CheckoutService::
|
||||
* getPaymentMethods(), which excludes a method whose driver implements
|
||||
* this and disagrees with the cart's current fulfillment type (via
|
||||
* Modules\Core\Shipping\Support\FulfillmentType::resolve() on the
|
||||
* currently selected ShippingMethod). A cart with no shipping option
|
||||
* selected yet imposes no constraint — every method is offered until a
|
||||
* fulfillment type is actually known.
|
||||
*/
|
||||
interface RequiresFulfillmentType
|
||||
{
|
||||
/**
|
||||
* @return 'carrier'|'store_pickup'
|
||||
*/
|
||||
public function requiredFulfillmentType(): string;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace Modules\Core\Payment\Drivers;
|
||||
use Illuminate\Support\Str;
|
||||
use Lunar\DataTypes\Price;
|
||||
use Modules\Core\Payment\Contracts\Configurable;
|
||||
use Modules\Core\Payment\Contracts\RequiresFulfillmentType;
|
||||
use Modules\Core\Payment\Contracts\SupportsPay;
|
||||
use Modules\Core\Payment\DTOs\PaymentResult;
|
||||
use Modules\Core\Payment\Enums\PaymentResultStatus;
|
||||
@@ -44,13 +45,24 @@ use Modules\Core\Payment\Events\PaymentDeferred;
|
||||
* — a real bug, not a hypothetical, caught and fixed after the fact. See
|
||||
* PaymentDeferred's own docblock for the full reasoning.
|
||||
*/
|
||||
class CashOnDeliveryPaymentDriver implements Configurable, SupportsPay
|
||||
class CashOnDeliveryPaymentDriver implements Configurable, SupportsPay, RequiresFulfillmentType
|
||||
{
|
||||
public function isConfigured(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* "On delivery" is the operative word — a carrier physically hands
|
||||
* over the parcel and collects payment at that moment. Meaningless
|
||||
* for store pickup, which already has OfflinePaymentDriver for the
|
||||
* equivalent in-person moment.
|
||||
*/
|
||||
public function requiredFulfillmentType(): string
|
||||
{
|
||||
return 'carrier';
|
||||
}
|
||||
|
||||
public function pay(string $type, Price $amount, array $data = [], array $context = []): PaymentResult
|
||||
{
|
||||
$result = new PaymentResult(
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Modules\Core\Payment\Drivers;
|
||||
use Illuminate\Support\Str;
|
||||
use Lunar\DataTypes\Price;
|
||||
use Modules\Core\Payment\Contracts\Configurable;
|
||||
use Modules\Core\Payment\Contracts\RequiresFulfillmentType;
|
||||
use Modules\Core\Payment\Contracts\SupportsPay;
|
||||
use Modules\Core\Payment\DTOs\PaymentResult;
|
||||
use Modules\Core\Payment\Enums\PaymentResultStatus;
|
||||
@@ -25,7 +26,7 @@ use Modules\Core\Payment\Events\PaymentCaptured;
|
||||
* none) purely so PaymentCaptured, and anything downstream keying on it,
|
||||
* have something to identify this attempt by.
|
||||
*/
|
||||
class OfflinePaymentDriver implements Configurable, SupportsPay
|
||||
class OfflinePaymentDriver implements Configurable, SupportsPay, RequiresFulfillmentType
|
||||
{
|
||||
/**
|
||||
* Always true — no external dependency to be missing.
|
||||
@@ -35,6 +36,16 @@ class OfflinePaymentDriver implements Configurable, SupportsPay
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cash-in-hand requires a staff member physically present to take the
|
||||
* payment — meaningless for a carrier delivery, where no such person
|
||||
* exists at handoff.
|
||||
*/
|
||||
public function requiredFulfillmentType(): string
|
||||
{
|
||||
return 'store_pickup';
|
||||
}
|
||||
|
||||
public function pay(string $type, Price $amount, array $data = [], array $context = []): PaymentResult
|
||||
{
|
||||
$reference = 'offline-'.Str::uuid();
|
||||
|
||||
Reference in New Issue
Block a user