Skip to content

Commit 3a264e5

Browse files
committed
feat: checkout page multiple gateway with manual cod option updated & checkout module optimized and updated for multiple payment gateways
1 parent ca6aad1 commit 3a264e5

File tree

5 files changed

+248
-113
lines changed

5 files changed

+248
-113
lines changed

app/Http/Controllers/Frontend/CheckoutController.php

Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@
77
use App\Models\Transaction;
88
use Illuminate\Http\Request;
99
use App\Http\Controllers\Controller;
10+
use App\Services\CheckoutService;
1011
use App\Services\PaymentGatewayService;
1112
use Illuminate\Support\Str;
1213
use Illuminate\Support\Facades\Log;
1314
use Exception;
1415

1516
class CheckoutController extends Controller
1617
{
18+
protected CheckoutService $service;
19+
20+
public function __construct(CheckoutService $service){
21+
$this->service = $service;
22+
}
1723
// public function createOrder(Request $request)
1824
// {
1925
// try {
@@ -60,6 +66,13 @@ class CheckoutController extends Controller
6066
// }
6167
// }
6268

69+
/**
70+
* Create a Stripe PaymentIntent for the order.
71+
* This method remains the same and is specifically for Stripe payments.
72+
*
73+
* @param Request $request
74+
* @return \Illuminate\Http\JsonResponse
75+
*/
6376
public function createStripeIntent(Request $request)
6477
{
6578
try {
@@ -72,16 +85,7 @@ public function createStripeIntent(Request $request)
7285
'shipping' => json_encode($request->shipping),
7386
]);
7487

75-
$transaction = Transaction::create([
76-
'user_id' => auth()->id(),
77-
'type' => 'payment',
78-
'transaction_id' => $charge['transaction_id'] ?? null,
79-
'amount' => $charge['amount'],
80-
'currency' => $charge['currency'],
81-
'status' => 'pending',
82-
'gateway' => 'stripe',
83-
'meta' => json_encode($charge['meta'] ?? []),
84-
]);
88+
$transaction = $this->service->createTransactionFromStripeCharge($charge);
8589

8690
return response()->json([
8791
'client_secret' => $charge['client_secret'],
@@ -93,55 +97,27 @@ public function createStripeIntent(Request $request)
9397
}
9498
}
9599

100+
/**
101+
* Confirms the payment and creates the order, handling both Stripe and Cash on Delivery.
102+
* The payment confirmation logic has been updated to be more flexible and optimized.
103+
*
104+
* @param Request $request
105+
* @return \Illuminate\Http\JsonResponse
106+
*/
96107
public function confirmPayment(Request $request)
97108
{
98109
try {
99-
$transaction = Transaction::where('transaction_id', $request->transaction_id)
100-
->where('status', 'pending')
101-
->firstOrFail();
102-
103-
$meta = json_decode($transaction->meta, true);
104110
$cart = session()->get('cart');
105111

112+
// Check for empty cart once
106113
if (!$cart || empty($cart['items'])) {
107114
return response()->json(['error' => 'Cart is empty.'], 400);
108115
}
109116

110-
$order = Order::create([
111-
'user_id' => $transaction->user_id,
112-
'order_number' => 'ORD-' . strtoupper(Str::random(10)),
113-
'status' => 'processing',
114-
'payment_status' => 'paid',
115-
'subtotal' => $cart['subtotal'] ?? $cart['total'],
116-
'discount' => $cart['discount'] ?? 0,
117-
'tax' => $cart['tax'] ?? 0,
118-
'shipping_cost' => $cart['shipping_cost'] ?? 0,
119-
'total' => $cart['total'],
120-
'currency' => $transaction->currency,
121-
'payment_gateway' => 'stripe',
122-
'shipping_address' => json_encode($meta['shipping'] ?? []),
123-
'billing_address' => json_encode($meta['billing'] ?? null),
124-
]);
125-
126-
foreach ($cart['items'] as $item) {
127-
OrderItem::create([
128-
'order_id' => $order->id,
129-
'product_id' => $item['product_id'],
130-
'name' => $item['title'],
131-
'quantity' => $item['quantity'],
132-
'price' => $item['price'],
133-
'total' => $item['price'] * $item['quantity'],
134-
'meta' => json_encode($item['meta'] ?? null),
135-
]);
136-
}
117+
$this->service->handlePaymentConfirmation($request, $cart);
137118

138-
$transaction->update([
139-
'order_id' => $order->id,
140-
'status' => 'paid',
141-
]);
119+
// Clear the cart session after a successful order creation
142120
session()->forget('cart');
143-
144-
145121
return response()->json(['success' => true]);
146122
} catch (\Exception $e) {
147123
Log::error('Payment confirmation failed', ['error' => $e->getMessage()]);

app/Http/Controllers/Frontend/ProductController.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,16 @@ public function show($slug)
4343
->get();
4444

4545
$product->load('variants.attributeValues');
46-
$product->variants->transform(function ($variant) {
47-
$variant->attribute_value_ids = $variant->attributeValues->pluck('id')->sort()->values()->all();
48-
return $variant;
49-
});
50-
51-
$variants = $product->variants->map(function($v) {
46+
$product->variants->transform(function ($v) {
5247
return [
5348
'id' => $v->id,
5449
'price' => $v->price,
5550
'sku' => $v->sku,
5651
'image' => Storage::disk('public')->url($v->image),
5752
'attribute_value_ids' => $v->attributeValues->pluck('id')->sort()->values()->all(),
5853
];
59-
})->toArray();
60-
return view('frontend.products.show', compact('product', 'attributes','variants'));
54+
});
55+
56+
return view('frontend.products.show', compact('product', 'attributes'));
6157
}
6258
}

app/Services/CheckoutService.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
namespace App\Services;
4+
5+
use App\Models\Crud;
6+
use App\Models\Order;
7+
use App\Models\OrderItem;
8+
use App\Models\Transaction;
9+
use Illuminate\Support\Str;
10+
11+
class CheckoutService
12+
{
13+
public function handlePaymentConfirmation($request, $cart)
14+
{
15+
$orderNumber = 'ORD-' . strtoupper(Str::random(10));
16+
$transaction = null;
17+
18+
// Variables for order creation, initialized with defaults
19+
$orderStatus = 'pending';
20+
$paymentStatus = 'pending';
21+
$paymentGateway = $request->payment_method;
22+
$shippingAddress = json_encode($request->shipping ?? []);
23+
$billingAddress = json_encode($request->billing ?? null);
24+
$totalAmount = $cart['total'];
25+
$currency = 'usd';
26+
27+
// Handle payment-specific logic
28+
if ($request->payment_method === 'stripe') {
29+
$transaction = Transaction::where('transaction_id', $request->transaction_id)
30+
->where('status', 'pending')
31+
->firstOrFail();
32+
33+
$meta = json_decode($transaction->meta, true);
34+
35+
// Update variables for Stripe
36+
$orderStatus = 'processing';
37+
$paymentStatus = 'paid';
38+
$shippingAddress = json_encode($meta['shipping'] ?? []);
39+
$billingAddress = json_encode($meta['billing'] ?? null);
40+
$currency = $transaction->currency;
41+
} else if ($request->payment_method === 'cod') {
42+
// Create a transaction for COD
43+
$transaction = Transaction::create([
44+
'user_id' => auth()->id(),
45+
'type' => 'payment',
46+
'transaction_id' => $request->transaction_id,
47+
'amount' => $totalAmount,
48+
'currency' => $currency,
49+
'status' => 'pending',
50+
'gateway' => 'cod',
51+
'meta' => json_encode(['shipping' => $request->shipping, 'total' => $totalAmount]),
52+
]);
53+
} else {
54+
return response()->json(['error' => 'Invalid payment method.'], 400);
55+
}
56+
57+
// Create the order using the determined variables
58+
$order = Order::create([
59+
'user_id' => auth()->id(),
60+
'order_number' => $orderNumber,
61+
'status' => $orderStatus,
62+
'payment_status' => $paymentStatus,
63+
'subtotal' => $cart['subtotal'] ?? $totalAmount,
64+
'total' => $totalAmount,
65+
'currency' => $currency,
66+
'payment_gateway' => $paymentGateway,
67+
'shipping_address' => $shippingAddress,
68+
'billing_address' => $billingAddress,
69+
'discount' => $cart['discount'] ?? 0,
70+
'tax' => $cart['tax'] ?? 0,
71+
'shipping_cost' => $cart['shipping_cost'] ?? 0,
72+
]);
73+
74+
// If a transaction was created/found, update it with the order ID
75+
if ($transaction) {
76+
$transaction->update(['order_id' => $order->id]);
77+
}
78+
79+
// Create order items (common logic for all payment methods)
80+
foreach ($cart['items'] as $item) {
81+
OrderItem::create([
82+
'order_id' => $order->id,
83+
'product_id' => $item['product_id'],
84+
'name' => $item['title'],
85+
'quantity' => $item['quantity'],
86+
'price' => $item['price'],
87+
'total' => $item['price'] * $item['quantity'],
88+
'meta' => json_encode($item['meta'] ?? null),
89+
]);
90+
}
91+
}
92+
93+
public function createTransactionFromStripeCharge($charge){
94+
return Transaction::create([
95+
'user_id' => auth()->id(),
96+
'type' => 'payment',
97+
'transaction_id' => $charge['transaction_id'] ?? null,
98+
'amount' => $charge['amount'],
99+
'currency' => $charge['currency'],
100+
'status' => 'pending',
101+
'gateway' => 'stripe',
102+
'meta' => json_encode($charge['meta'] ?? []),
103+
]);
104+
}
105+
}

0 commit comments

Comments
 (0)