Laravel 8 E-Commerce - Checkout With Cash On Delivery
In this video, we are going to learn about Checkout With Cash On Delivery.
So, let's see how we can implement the Checkout With Cash On Delivery option.
On the checkout page, let's add a Shipping Address form.
When the checkbox is selected, the shipping address form should be displayed.
We will also change the payment method to include:
- Cash On Delivery
- Credit/Debit Card
- PayPal
Additionally, we will display the total price.
To achieve this, write the following code in the checkout-component.blade.php view file:
<main id="main" class="main-site">
<style>
.summary-item .row-in-form input[type="password"], .summary-item .row-in-form input[type="text"], .summary-item .row-in-form input[type="tel"] {
font-size: 13px;
line-height: 19px;
display: inline-block;
height: 43px;
padding: 2px 20px;
max-width: 300px;
width: 100%;
border: 1px solid #e6e6e6;
}
</style>
<div class="container">
<div class="wrap-breadcrumb">
<ul>
<li class="item-link"><a href="/" class="link">home</a></li>
<li class="item-link"><span>Checkout</span></li>
</ul>
</div>
<div class=" main-content-area">
<form wire:submit.prevent="placeOrder" onsubmit="$('#processing').show();">
<div class="row">
<div class="col-md-12">
<div class="wrap-address-billing">
<h3 class="box-title">Billing Address</h3>
<div class="billing-address">
<p class="row-in-form">
<label for="fname">first name<span>*</span></label>
<input type="text" name="fname" value="" placeholder="Your name" wire:model="firstname">
@error('firstname') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="lname">last name<span>*</span></label>
<input type="text" name="lname" value="" placeholder="Your last name" wire:model="lastname">
@error('lastname') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="email">Email Addreess:</label>
<input type="email" name="email" value="" placeholder="Type your email" wire:model="email">
@error('email') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="phone">Phone number<span>*</span></label>
<input type="number" name="phone" value="" placeholder="10 digits format" wire:model="mobile">
@error('mobile') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="add">Line1:</label>
<input type="text" name="add" value="" placeholder="Street at apartment number" wire:model="line1">
@error('line1') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="add">Line2:</label>
<input type="text" name="add" value="" placeholder="Street at apartment number" wire:model="line2">
</p>
<p class="row-in-form">
<label for="country">Country<span>*</span></label>
<input type="text" name="country" value="" placeholder="United States" wire:model="country">
@error('country') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="city">Province<span>*</span></label>
<input type="text" name="province" value="" placeholder="Province" wire:model="province">
@error('province') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="city">Town / City<span>*</span></label>
<input type="text" name="city" value="" placeholder="City name" wire:model="city">
@error('city') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="zip-code">Postcode / ZIP:</label>
<input type="number" name="zip-code" value="" placeholder="Your postal code" wire:model="zipcode">
@error('zipcode') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form fill-wife">
<label class="checkbox-field">
<input name="different-add" id="different-add" value="1" type="checkbox" wire:model="ship_to_different">
<span>Ship to a different address?</span>
</label>
</p>
</div>
</div>
</div>
@if($ship_to_different)
<div class="col-md-12">
<div class="wrap-address-billing">
<h3 class="box-title">Shipping Address</h3>
<div class="billing-address">
<p class="row-in-form">
<label for="fname">first name<span>*</span></label>
<input type="text" name="fname" value="" placeholder="Your name" wire:model="s_firstname">
@error('s_firstname') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="lname">last name<span>*</span></label>
<input type="text" name="lname" value="" placeholder="Your last name" wire:model="s_lastname">
@error('s_lastname') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="email">Email Addreess:</label>
<input type="email" name="email" value="" placeholder="Type your email" wire:model="s_email">
@error('s_email') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="phone">Phone number<span>*</span></label>
<input type="number" name="phone" value="" placeholder="10 digits format" wire:model="s_mobile">
@error('s_mobile') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="add">Line1:</label>
<input type="text" name="add" value="" placeholder="Street at apartment number" wire:model="s_line1">
@error('s_line1') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="add">Line2:</label>
<input type="text" name="add" value="" placeholder="Street at apartment number" wire:model="s_line2">
</p>
<p class="row-in-form">
<label for="country">Country<span>*</span></label>
<input type="text" name="country" value="" placeholder="United States" wire:model="s_country">
@error('s_country') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="city">Province<span>*</span></label>
<input type="text" name="province" value="" placeholder="Province" wire:model="s_province">
@error('s_province') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="city">Town / City<span>*</span></label>
<input type="text" name="city" value="" placeholder="City name" wire:model="s_city">
@error('s_city') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="zip-code">Postcode / ZIP:</label>
<input type="number" name="zip-code" value="" placeholder="Your postal code" wire:model="s_zipcode">
@error('s_zipcode') <span class="text-danger">{{$message}}</span> @enderror
</p>
</div>
</div>
</div>
@endif
</div>
<div class="summary summary-checkout">
<div class="summary-item payment-method">
<h4 class="title-box">Payment Method</h4>
@if($paymentmode == 'card')
<div class="wrap-address-billing">
@if(Session::has('stripe_error'))
<div class="alert alert-danger" role="alert">{{Session::get('stripe_error')}}</div>
@endif
<p class="row-in-form">
<label for="card-no">Card Number:</label>
<input type="text" name="card-no" value="" placeholder="Card Number" wire:model="card_no">
@error('card_no') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="exp-month">Expiry Month:</label>
<input type="text" name="exp-month" value="" placeholder="MM" wire:model="exp_month">
@error('exp_month') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="exp-year">Expiry Year:</label>
<input type="text" name="exp-year" value="" placeholder="YYYY" wire:model="exp_year">
@error('exp_year') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="row-in-form">
<label for="cvc">CVC:</label>
<input type="password" name="cvc" value="" placeholder="CVC" wire:model="cvc">
@error('cvc') <span class="text-danger">{{$message}}</span> @enderror
</p>
</div>
@endif
<div class="choose-payment-methods">
<label class="payment-method">
<input name="payment-method" id="payment-method-bank" value="cod" type="radio" wire:model="paymentmode">
<span>Cash On Delivery</span>
<span class="payment-desc">Order Now Pay on Delivery</span>
</label>
<label class="payment-method">
<input name="payment-method" id="payment-method-visa" value="card" type="radio" wire:model="paymentmode">
<span>Debit / Credit Card</span>
<span class="payment-desc">There are many variations of passages of Lorem Ipsum available</span>
</label>
<label class="payment-method">
<input name="payment-method" id="payment-method-paypal" value="paypal" type="radio" wire:model="paymentmode">
<span>Paypal</span>
<span class="payment-desc">You can pay with your credit</span>
<span class="payment-desc">card if you don't have a paypal account</span>
</label>
@error('paymentmode') <span class="text-danger">{{$message}}</span> @enderror
</div>
@if(Session::has('checkout'))
<p class="summary-info grand-total"><span>Grand Total</span> <span class="grand-total-price">${{Session::get('checkout')['total']}}</span></p>
@endif
@if($errors->isEmpty())
<div wire:ignore id="processing" style="font-size:22px; margin-bottom:20px;padding-left:37px;color:green;display:none;">
<i class="fa fa-spinner fa-pulse fa-fw"></i>
<span>Processing...</span>
</div>
@endif
<button type="submit" class="btn btn-medium">Place order now </button>
</div>
<div class="summary-item shipping-method">
<h4 class="title-box f-title">Shipping method</h4>
<p class="summary-info"><span class="title">Flat Rate</span></p>
<p class="summary-info"><span class="title">Fixed $0</span></p>
</div>
</div>
</form>
</div><!--end main content area-->
</div><!--end container-->
</main>
Next, go to the CheckoutComponent.php class file and create the following properties:
public $ship_to_different;
public $firstname;
public $lastname;
public $email;
public $mobile;
public $line1;
public $line2;
public $city;
public $province;
public $country;
public $zipcode;
public $s_firstname;
public $s_lastname;
public $s_email;
public $s_mobile;
public $s_line1;
public $s_line2;
public $s_city;
public $s_province;
public $s_country;
public $s_zipcode;
public $paymentmode;
public $thankyou;
Now, create a function for placing an order and update the lifecycle hook method with the following code:
public function updated($fields)
{
$this->validateOnly($fields,[
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email',
'mobile' => 'required|numeric',
'line1' => 'required',
'city' => 'required',
'province' => 'required',
'country' => 'required',
'zipcode' => 'required',
'paymentmode' => 'required'
]);
if($this->ship_to_different)
{
$this->validateOnly($fields,[
's_firstname' => 'required',
's_lastname' => 'required',
's_email' => 'required|email',
's_mobile' => 'required|numeric',
's_line1' => 'required',
's_city' => 'required',
's_province' => 'required',
's_country' => 'required',
's_zipcode' => 'required'
]);
}
}
public function placeOrder()
{
$this->validate([
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email',
'mobile' => 'required|numeric',
'line1' => 'required',
'city' => 'required',
'province' => 'required',
'country' => 'required',
'zipcode' => 'required',
'paymentmode' => 'required'
]);
$order = new Order();
$order->user_id = Auth::user()->id;
$order->subtotal = session()->get('checkout')['subtotal'];
$order->discount = session()->get('checkout')['discount'];
$order->tax = session()->get('checkout')['tax'];
$order->total = session()->get('checkout')['total'];
$order->firstname = $this->firstname;
$order->lastname = $this->lastname;
$order->email = $this->email;
$order->mobile = $this->mobile;
$order->line1 = $this->line1;
$order->line2 = $this->line2;
$order->city = $this->city;
$order->province = $this->province;
$order->country = $this->country;
$order->zipcode = $this->zipcode;
$order->status = 'ordered';
$order->is_shipping_different = $this->ship_to_different ? 1:0;
$order->save();
foreach(Cart::instance('cart')->content() as $item)
{
$orderItem = new OrderItem();
$orderItem->product_id = $item->id;
$orderItem->order_id = $order->id;
$orderItem->price = $item->price;
$orderItem->quantity = $item->qty;
$orderItem->save();
}
if($this->ship_to_different)
{
$this->validate([
's_firstname' => 'required',
's_lastname' => 'required',
's_email' => 'required|email',
's_mobile' => 'required|numeric',
's_line1' => 'required',
's_city' => 'required',
's_province' => 'required',
's_country' => 'required',
's_zipcode' => 'required'
]);
$shipping = new Shipping();
$shipping->order_id = $order->id;
$shipping->firstname = $this->s_firstname;
$shipping->lastname = $this->s_lastname;
$shipping->email = $this->s_email;
$shipping->mobile = $this->s_mobile;
$shipping->line1 = $this->s_line1;
$shipping->line2 = $this->s_line2;
$shipping->city = $this->s_city;
$shipping->province = $this->s_province;
$shipping->country = $this->s_country;
$shipping->zipcode = $this->s_zipcode;
$shipping->save();
}
if($this->paymentmode == 'cod')
{
$this->makeTransaction($order->id,'pending');
$this->resetCart();
}
$this->sendOrderConfirmationMail($order);
}
public function resetCart()
{
$this->thankyou = 1;
Cart::instance('cart')->destroy();
session()->forget('checkout');
}
Let's create a new Livewire component.
Switch to the command prompt and run the following command:
php artisan make:livewire ThankyouComponnent
Now, switch to the project and create a route for this component.
Go to the web.php file and create a route:
Route::get('/thank-you',ThankyouComponent::class)->name('thankyou');
Open the ThankyouComponent.php class file and write the following code:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class ThankyouComponent extends Component
{
public function render()
{
return view('livewire.thankyou-component')->layout('layouts.base');
}
}
Next, open the thankyou-component.blade.php file and write the following code:
<div>
<main id="main" class="main-site">
<div class="container">
<div class="wrap-breadcrumb">
<ul>
<li class="item-link"><a href="/" class="link">home</a></li>
<li class="item-link"><span>Thank You</span></li>
</ul>
</div>
</div>
<div class="container pb-60">
<div class="row">
<div class="col-md-12 text-center">
<h2>Thank you for your order</h2>
<p>A confirmation email was sent.</p>
<a href="/shop" class="btn btn-submit btn-submitx">Continue Shopping</a>
</div>
</div>
</div>
</main>
</div>
All done! Let's test it out.
Switch to the browser and refresh the page.
Add some products to the cart and click on checkout.
Now, you can see the total amount.
Fill in the billing details.
If the shipping address is different, check the checkbox and fill in the shipping details.
Click on submit.
You should now see the thank you page.
Let's check if the order has been submitted successfully.
Open the database and go to phpMyAdmin.
Select the database and browse the order table.
You should see the order record.
Now, browse the order items table.
You should see all the items.
Next, browse the shipping table.
You should see the shipping record.
Finally, browse the transaction table.
You should see the transaction record with the mode, status, and order ID.
And that's it!
In this way, you can implement Checkout With Cash On Delivery.