Feat: Creating PaymentMethods, Setting Fees, Availabilities

This commit is contained in:
2026-08-31 13:54:20 +03:00
parent d873cb4931
commit 2db1e1331f
12 changed files with 359 additions and 1 deletions
+62
View File
@@ -12,11 +12,14 @@ use Lunar\Facades\ShippingManifest;
use Lunar\Models\Cart;
use Lunar\Models\Order;
use Modules\Core\Cart\Services\CartService;
use Modules\Core\Checkout\Contracts\PaymentDriver;
use Modules\Core\Checkout\Events\BillingAddressSet;
use Modules\Core\Checkout\Events\OrderPlaced;
use Modules\Core\Checkout\Events\PaymentMethodSelected;
use Modules\Core\Checkout\Events\ShippingAddressSet;
use Modules\Core\Checkout\Events\ShippingOptionSelected;
use Modules\Core\Checkout\Exceptions\InvalidShippingOptionException;
use Modules\Core\Checkout\Exceptions\UnknownPaymentTypeException;
/**
* Storefront-facing checkout operations, mirroring
@@ -123,4 +126,63 @@ class CheckoutService
return $order;
}
/**
* Records which payment type the shopper picked (Cart::meta
* ['payment_method']) — read by e.g. Modules\Core\Payment\Pipelines\
* Cart\ApplyCashOnDeliveryFee to add that type's own cart-total
* adjustments before the shopper reaches placeOrder()/confirmPayment().
* Does not itself call a PaymentDriver — selecting a method and
* confirming payment against it are deliberately separate steps, same
* as selecting a shipping option happens before placing the order.
*
* @throws UnknownPaymentTypeException if $type has no registered
* PaymentDriver (config('lunar.payments.types.<type>.payment_driver'))
*/
public function selectPaymentMethod(string $type): Cart
{
$this->paymentDriverFor($type);
$cart = $this->cart->currentOrCreate();
$cart->meta = [...$cart->meta->toArray(), 'payment_method' => $type];
$cart->save();
Event::dispatch(new PaymentMethodSelected($cart, $type));
return $cart;
}
/**
* Resolves $type's registered PaymentDriver and calls confirm() —
* the driver decides whether/when the order actually gets placed (see
* Modules\Core\Checkout\Contracts\PaymentDriver's docblock). $data
* carries whatever that driver needs (Stripe's payment_intent id, a
* future redirect-based provider's callback payload).
*
* @param array<string, mixed> $data
*
* @throws UnknownPaymentTypeException if $type has no registered driver
* @throws \Lunar\Exceptions\FingerprintMismatchException
* @throws \Lunar\Exceptions\Carts\CartException
*/
public function confirmPayment(string $type, string $fingerprint, array $data = []): Order
{
$driver = $this->paymentDriverFor($type);
return $driver->confirm($this->cart->currentOrCreate(), $fingerprint, $data);
}
/**
* @throws UnknownPaymentTypeException
*/
private function paymentDriverFor(string $type): PaymentDriver
{
$driverClass = config("lunar.payments.types.{$type}.payment_driver");
if (! $driverClass) {
throw new UnknownPaymentTypeException($type);
}
return app($driverClass);
}
}