diff --git a/frontend/src/app/api/create-payment-intent/route.ts b/frontend/src/app/api/create-payment-intent/route.ts
new file mode 100644
index 0000000..642f7fa
--- /dev/null
+++ b/frontend/src/app/api/create-payment-intent/route.ts
@@ -0,0 +1,33 @@
+import { NextResponse } from 'next/server';
+import Stripe from 'stripe';
+
+const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
+ apiVersion: '2024-11-20.acacia'
+});
+
+export async function POST(req: Request) {
+ try {
+ const body = await req.json();
+ const { items } = body;
+
+ const paymentIntent = await stripe.paymentIntents.create({
+ amount: Math.round(items.reduce((sum: number, item: any) =>
+ sum + (item.price * item.quantity), 0) * 100),
+ currency: 'usd',
+ payment_method_types: ['card', 'paypal', 'apple_pay', 'google_pay'],
+ automatic_payment_methods: {
+ enabled: false
+ },
+ });
+
+ return NextResponse.json({
+ clientSecret: paymentIntent.client_secret
+ });
+ } catch (error) {
+ console.error('Stripe error:', error);
+ return NextResponse.json(
+ { error: 'Error creating payment intent' },
+ { status: 500 }
+ );
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/app/checkout/page.tsx b/frontend/src/app/checkout/page.tsx
new file mode 100644
index 0000000..2b41d2d
--- /dev/null
+++ b/frontend/src/app/checkout/page.tsx
@@ -0,0 +1,12 @@
+'use client';
+
+import StripeCheckout from '@/lib/stripe/checkout';
+
+export default function CheckoutPage() {
+ return (
+
+
Checkout
+
+
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/routes/cart/page.tsx b/frontend/src/app/routes/cart/page.tsx
deleted file mode 100644
index b921ab0..0000000
--- a/frontend/src/app/routes/cart/page.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-// src/app/(routes)/cart/page.tsx
-'use client';
-
-import { useCartStore } from '@/lib/store/cart-store';
-import StripeCheckout from '@/lib/stripe/checkout';
-
-export default function CartPage() {
- const { items, getTotalPrice } = useCartStore();
-
- return (
-
-
Your Cart
- {items.map(item => (
-
- {item.title} - ${item.price} x {item.quantity}
-
- ))}
-
-
- );
-}
\ No newline at end of file
diff --git a/frontend/src/app/routes/checkout/page.tsx b/frontend/src/app/routes/checkout/page.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/frontend/src/app/routes/payment-confirmation/page.tsx b/frontend/src/app/routes/payment-confirmation/page.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/frontend/src/components/CartTab/CartSidebar.tsx b/frontend/src/components/CartTab/CartSidebar.tsx
index f8887a9..b0a6d00 100644
--- a/frontend/src/components/CartTab/CartSidebar.tsx
+++ b/frontend/src/components/CartTab/CartSidebar.tsx
@@ -2,6 +2,7 @@ import React from 'react';
import { motion } from 'framer-motion';
import type { CartItem } from '@/lib/store/cart-store';
import Image from 'next/image';
+import { useRouter } from 'next/navigation';
interface CartSidebarProps {
items: CartItem[];
@@ -18,6 +19,8 @@ const CartSidebar: React.FC = ({
updateQuantity,
removeItem,
}) => {
+ const router = useRouter();
+
// Count occurrences of each item ID
const itemCounts = items.reduce((acc, item) => {
acc[item.id] = (acc[item.id] || 0) + 1;
@@ -43,6 +46,32 @@ const CartSidebar: React.FC = ({
removeItem(itemId);
}
+ const handleCheckout = async () => {
+ try {
+ // Create payment intent
+ const response = await fetch('/api/create-payment-intent', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ items: uniqueItems }),
+ });
+
+ if (!response.ok) {
+ throw new Error('Network response was not ok');
+ }
+
+ // Close the cart sidebar
+ onClose();
+
+ // Redirect to checkout page
+ router.push('/checkout');
+ } catch (error) {
+ console.error('Error initiating checkout:', error);
+ // You might want to show an error message to the user here
+ }
+ };
+
return (
<>
{/* Overlay */}
@@ -140,7 +169,9 @@ const CartSidebar: React.FC = ({
${total.toFixed(2)}
diff --git a/frontend/src/lib/stripe/checkout-form.tsx b/frontend/src/lib/stripe/checkout-form.tsx
index fe9eb1c..4514548 100644
--- a/frontend/src/lib/stripe/checkout-form.tsx
+++ b/frontend/src/lib/stripe/checkout-form.tsx
@@ -4,10 +4,12 @@ import React, { useState, FormEvent } from 'react';
import {
PaymentElement,
useStripe,
- useElements
+ useElements,
+ AddressElement
} from '@stripe/react-stripe-js';
import { StripePaymentElementOptions } from '@stripe/stripe-js';
import { useCartStore } from '@/lib/store/cart-store';
+import Image from 'next/image';
export default function CheckoutForm() {
const stripe = useStripe();
@@ -15,7 +17,7 @@ export default function CheckoutForm() {
const [isProcessing, setIsProcessing] = useState(false);
const [message, setMessage] = useState(null);
- const { clearCart } = useCartStore();
+ const { clearCart, items, getTotalPrice } = useCartStore();
const handleSubmit = async (event: FormEvent) => {
event.preventDefault();
@@ -50,24 +52,139 @@ export default function CheckoutForm() {
};
const paymentElementOptions: StripePaymentElementOptions = {
- layout: 'tabs',
+ layout: {
+ type: 'tabs',
+ defaultCollapsed: false,
+ radios: false,
+ spacedAccordionItems: false
+ },
+ paymentMethodOrder: [ 'card', 'apple_pay', 'google_pay', 'paypal', 'amazon_pay']
};
+ const total = getTotalPrice({ items });
+ const shipping = 5.99;
+ const taxRate = 0.0825;
+ const subtotal = total;
+ const tax = subtotal * taxRate;
+ const finalTotal = subtotal + shipping + tax;
+
return (
-