Feat: Updating PaymentDrivers and CheckoutService to handle payment methods

This commit is contained in:
2026-08-31 14:12:21 +03:00
parent 2db1e1331f
commit 9529036585
7 changed files with 179 additions and 71 deletions
@@ -1,46 +0,0 @@
<?php
namespace Modules\Core\Payment\Drivers;
use Lunar\Exceptions\Carts\CartException;
use Lunar\Exceptions\DisallowMultipleCartOrdersException;
use Lunar\Exceptions\FingerprintMismatchException;
use Lunar\Models\Cart;
use Lunar\Models\Order;
use Modules\Core\Checkout\Contracts\PaymentDriver;
use Modules\Core\Checkout\Services\CheckoutService;
/**
* Cash-on-delivery has no gateway to confirm against — the shopper pays the
* courier on delivery, not at checkout — so confirm() has nothing to wait
* on and places the order immediately, same as Lunar's own OfflinePayment
* would, but through CheckoutService::placeOrder() so it goes through the
* same fingerprint check every other driver does. $data is unused: nothing
* about this confirmation depends on gateway-specific payload.
*
* Sets the order status to config('lunar.payments.types.cash-on-delivery.authorized')
* afterward — placeOrder() itself leaves the order at Lunar's configured
* draft_status, same as every driver is responsible for moving it on from.
*/
class CashOnDeliveryPaymentDriver implements PaymentDriver
{
public function __construct(
private readonly CheckoutService $checkout,
) {}
/**
* @throws FingerprintMismatchException
* @throws CartException
* @throws DisallowMultipleCartOrdersException
*/
public function confirm(Cart $cart, string $fingerprint, array $data): Order
{
$order = $this->checkout->placeOrder($fingerprint);
$order->update([
'status' => config('lunar.payments.types.cash-on-delivery.authorized', $order->status),
]);
return $order->refresh();
}
}
@@ -0,0 +1,57 @@
<?php
namespace Modules\Core\Payment\Drivers;
use Lunar\Exceptions\Carts\CartException;
use Lunar\Exceptions\DisallowMultipleCartOrdersException;
use Lunar\Exceptions\FingerprintMismatchException;
use Lunar\Models\Cart;
use Lunar\Models\Order;
use Modules\Core\Checkout\Contracts\PaymentDriver;
use Modules\Core\Checkout\Services\CheckoutService;
/**
* Shared by every payment type with no real gateway to confirm against —
* cash-in-hand, cash-on-delivery — where the shopper pays at pickup/on
* delivery, not at checkout. confirm() has nothing to wait on, so it places
* the order immediately, same as Lunar's own OfflinePayment would, but
* through CheckoutService::placeOrder() so it goes through the same
* fingerprint check every other driver does. $data is unused: nothing about
* this confirmation depends on gateway-specific payload.
*
* Sets the order status to config("lunar.payments.types.{$type}.authorized")
* afterward, using the type actually confirmed — not a hardcoded key —
* since this one driver is shared across multiple types.
* placeOrder() itself leaves the order at Lunar's configured draft_status,
* same as every driver is responsible for moving it on from.
*/
class OfflinePaymentDriver implements PaymentDriver
{
public function __construct(
private readonly CheckoutService $checkout,
) {}
/**
* Always true — no external dependency to be missing.
*/
public function isConfigured(): bool
{
return true;
}
/**
* @throws FingerprintMismatchException
* @throws CartException
* @throws DisallowMultipleCartOrdersException
*/
public function confirm(Cart $cart, string $type, string $fingerprint, array $data): Order
{
$order = $this->checkout->placeOrder($fingerprint);
$order->update([
'status' => config("lunar.payments.types.{$type}.authorized", $order->status),
]);
return $order->refresh();
}
}
+11 -1
View File
@@ -35,6 +35,16 @@ class StripePaymentDriver implements PaymentDriver
private readonly CheckoutService $checkout,
) {}
/**
* Same key lunarphp/stripe's own StripeManager reads its API key from
* (Stripe::setApiKey(config('services.stripe.key')) in
* StripeManager::__construct()) — no key, no usable driver.
*/
public function isConfigured(): bool
{
return filled(config('services.stripe.key'));
}
/**
* @throws PaymentNotConfirmedException if Stripe hasn't confirmed the
* payment intent (wrong intent id, already processed, order already
@@ -43,7 +53,7 @@ class StripePaymentDriver implements PaymentDriver
* @throws FingerprintMismatchException
* @throws CartException
*/
public function confirm(Cart $cart, string $fingerprint, array $data): Order
public function confirm(Cart $cart, string $type, string $fingerprint, array $data): Order
{
$paymentIntentId = $data['payment_intent'];