I cart methods

This commit is contained in:
Fabian @ Blax Software 2025-12-18 15:33:47 +01:00
parent e687836024
commit 7a26c9a965
2 changed files with 47 additions and 52 deletions

View File

@ -221,11 +221,15 @@ class Cart extends Model
$this->validateDateAvailability($from, $until); $this->validateDateAvailability($from, $until);
} }
// Update cart with from/until
$this->update([ $this->update([
'from_date' => $from, 'from_date' => $from,
'until_date' => $until, 'until_date' => $until,
]); ]);
// Update cart items with from/until
$this->applyDatesToItems($validateAvailability);
return $this->fresh(); return $this->fresh();
} }
@ -792,14 +796,18 @@ class Cart extends Model
* *
* @throws \Exception * @throws \Exception
*/ */
public function validateForCheckout(): void public function validateForCheckout(bool $throws = true): bool
{ {
$items = $this->items() $items = $this->items()
->with('purchasable') ->with('purchasable')
->get(); ->get();
if ($items->isEmpty()) { if ($items->isEmpty()) {
throw new \Exception("Cart is empty"); if ($throws) {
throw new \Exception("Cart is empty");
} else {
return false;
}
} }
// Validate that all items have required information before checkout // Validate that all items have required information before checkout
@ -809,9 +817,16 @@ class Cart extends Model
$product = $item->purchasable; $product = $item->purchasable;
$productName = $product ? $product->name : 'Unknown Product'; $productName = $product ? $product->name : 'Unknown Product';
$missingFields = implode(', ', array_keys($adjustments)); $missingFields = implode(', ', array_keys($adjustments));
throw new \Exception("Cart item '{$productName}' is missing required information: {$missingFields}");
if ($throws) {
throw new \Exception("Cart item '{$productName}' is missing required information: {$missingFields}");
} else {
return false;
}
} }
} }
return true;
} }
public function checkout(): static public function checkout(): static
@ -926,10 +941,12 @@ class Cart extends Model
* - Returns the Stripe checkout session * - Returns the Stripe checkout session
* *
* @param array $options Optional session parameters (success_url, cancel_url, etc.) * @param array $options Optional session parameters (success_url, cancel_url, etc.)
* @param string|null $url Optional fullPath URL for success and cancel URLs
*
* @return mixed Stripe\Checkout\Session instance * @return mixed Stripe\Checkout\Session instance
* @throws \Exception * @throws \Exception
*/ */
public function checkoutSession(array $options = []) public function checkoutSession(array $options = [], ?string $url = null)
{ {
if (!config('shop.stripe.enabled')) { if (!config('shop.stripe.enabled')) {
throw new \Exception('Stripe is not enabled'); throw new \Exception('Stripe is not enabled');
@ -974,13 +991,24 @@ class Cart extends Model
$lineItems[] = $lineItem; $lineItems[] = $lineItem;
} }
$success_url = $url ?? $options['success_url'] ?? route('shop.stripe.success');
$cancel_url = $url ?? $options['cancel_url'] ?? route('shop.stripe.cancel');
$success_url = (strpos($success_url, '?'))
? $success_url . '&session_id={CHECKOUT_SESSION_ID}&cart_id=' . $this->id
: $success_url . '?session_id={CHECKOUT_SESSION_ID}&cart_id=' . $this->id;
$cancel_url = (strpos($cancel_url, '?'))
? $cancel_url . '&cart_id=' . $this->id
: $cancel_url . '?cart_id=' . $this->id;
// Prepare session parameters // Prepare session parameters
$sessionParams = [ $sessionParams = [
'payment_method_types' => ['card'], 'payment_method_types' => ['card'],
'line_items' => $lineItems, 'line_items' => $lineItems,
'mode' => 'payment', 'mode' => 'payment',
'success_url' => $options['success_url'] ?? route('shop.stripe.success') . '?session_id={CHECKOUT_SESSION_ID}&cart_id=' . $this->id, 'success_url' => $success_url,
'cancel_url' => $options['cancel_url'] ?? route('shop.stripe.cancel') . '?cart_id=' . $this->id, 'cancel_url' => $cancel_url,
'client_reference_id' => $this->id, 'client_reference_id' => $this->id,
'metadata' => array_merge([ 'metadata' => array_merge([
'cart_id' => $this->id, 'cart_id' => $this->id,
@ -1038,56 +1066,25 @@ class Cart extends Model
* *
* @return string|null|false * @return string|null|false
*/ */
public function checkoutSessionLink(): string|null|false public function checkoutSessionLink(array $option = [], ?string $url = null): string|null|false
{ {
// Check if Stripe is enabled if (! @$this->validateForCheckout(false)) {
if (!config('shop.stripe.enabled')) {
return null; return null;
} }
// Check if cart has a stored session ID in meta $checkoutSession = $this->checkoutSession($option, $url);
$meta = $this->meta;
if (is_array($meta)) {
$meta = (object)$meta;
}
if (!isset($meta->stripe_session_id)) { if ($checkoutSession) {
return null; if (
} isset($checkoutSession->url)
&& !empty($checkoutSession->url)
$sessionId = $meta->stripe_session_id; ) {
return $checkoutSession->url;
try {
// Ensure Stripe is initialized
\Stripe\Stripe::setApiKey(config('services.stripe.secret'));
// Retrieve the session from Stripe
$session = \Stripe\Checkout\Session::retrieve($sessionId);
// Check if session is still valid (not expired)
// Stripe sessions expire after 24 hours
if (isset($session->expires_at) && $session->expires_at < time()) {
return null;
} }
// Return the session URL
return $session->url ?? null;
} catch (\Stripe\Exception\InvalidRequestException $e) {
// Session not found or invalid
\Illuminate\Support\Facades\Log::warning('Stripe session not found', [
'cart_id' => $this->id,
'session_id' => $sessionId,
'error' => $e->getMessage(),
]);
return null;
} catch (\Exception $e) {
// Other errors
\Illuminate\Support\Facades\Log::error('Error retrieving Stripe checkout session', [
'cart_id' => $this->id,
'session_id' => $sessionId,
'error' => $e->getMessage(),
]);
return false; return false;
} }
return null;
} }
} }

View File

@ -234,15 +234,13 @@ class CartTest extends TestCase
} }
/** @test */ /** @test */
public function checkout_session_link_returns_null_when_stripe_disabled() public function checkout_session_link_is_null_when_stripe_disabled()
{ {
config(['shop.stripe.enabled' => false]); config(['shop.stripe.enabled' => false]);
$cart = Cart::create(); $cart = Cart::create();
$link = $cart->checkoutSessionLink(); $this->assertNull($cart->checkoutSessionLink());
$this->assertNull($link);
} }
/** @test */ /** @test */