Hello Guys i've been following this Laravel/livewire E-Commerce series and i ecountered this frustrating error. Everything seems to be oky with the code but each time i click on the place order button from my checkout page, it raises a "trying to access array offset on value of type null ['subtotal']". i really dont know what to do. i am kinda a newbie. will really appreciate if someone helps me out. thanks.
My Checkoutcomponent.php file is here,
<?php
namespace App\Http\Livewire;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Shipping;
use App\Models\Transaction;
use Cart;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use Stripe;
class CheckoutComponent extends Component
{
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;
public $card_no;
public $exp_month;
public $exp_year;
public $cvc;
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'
]);
}
if($this->paymentmode == 'card')
{
$this->validateonly($fields,[
'card_no'=>'required|numeric',
'exp_month'=>'required|numeric',
'exp_year'=>'required|numeric',
'cvc'=>'required|numeric'
]);
}
}
public function placeOder()
{
$this->validate([
'firstname'=>'required',
'lastname' =>'required',
'email' =>'required|email',
'mobile' =>'required|numeric',
'line1' =>'required',
'city' =>'required',
'province' =>'required',
'country' =>'required',
'zipcode' =>'required',
'paymentmode'=>'required'
]);
if($this->paymentmode == 'card')
{
$this->validate([
'card_no'=>'required|numeric',
'exp_month'=>'required|numeric',
'exp_year'=>'required|numeric',
'cvc'=>'required|numeric'
]);
}
$order = new Order();
$order->user_id = Auth::user()->id;
$order->subtotal = session()->get('checkout')['subtotal']
$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();
}
else if($this->paymentmode == 'card')
{
$stripe = Stripe::make(env('STRIPE_KEY'));
try{
$token = $stripe->tokens()->create([
'card'=>[
'number'=>$this->card_no,
'exp_month'=>$this->exp_month,
'exp_year'=>$this->exp_year,
'cvc'=> $this->cvc
]
]);
if(!isset($token['id']))
{
session()->flash('stripe_error','The stripe token was not generated correctly!');
$this->thankyou = 0;
}
$customer = $stripe->customers()->create([
'name' => $this->firstname . ' ' . $this->lastname,
'email' => $this-> email,
'phone' => $this->mobile,
'address' => [
'line1' => $this->line1,
'postal_code' => $this->zipcode,
'city' => $this->city,
'state' => $this->province,
'country' => $this->country
],
'shipping' => [
'name' => $this->firstname . ' ' . $this->lastname,
'address' => [
'line1' => $this->line1,
'postal_code' => $this->zipcode,
'city' => $this->city,
'state' => $this->province,
'country' => $this->country
],
],
'source' => $token['id']
]);
$charge = $stripe->charges()->create([
'customer' => $customer['id'],
'currency' => 'USD',
'amount' => session()->get('checkout')['total'],
'description' => 'payment for order no' . $order->id
]);
if($charge['status'] == 'succeeded')
{
$this->makeTransaction($order->id,'approved');
$this->resetCart();
}
else{
session()->flash('stripe_error','Error in Transaction!');
$this->thankyou = 0;
}
}catch(Exception $e){
session()->flash('stripe_error',$e->getMessage());
$this->thankyou = 0;
}
}
}
public function resetCart()
{
$this->thankyou = 1;
Cart::instance('cart')->destroy();
session()->forget('checkout');
}
public function makeTransaction($order_id,$status)
{
$transaction = new Transaction();
$transaction->user_id = Auth::user()->id;
$transaction->order_id = $order_id;
$transaction->mode = $this -> paymentmode;
$transaction->status= $status;
$transaction->save();
}
public function verifyForCheckout()
{
if(!Auth::check())
{
return redirect()->route('login');
}
else if($this->thankyou)
{
return redirect()->route('thankyou');
}
}
public function render()
{
$this->verifyForCheckout();
return view('livewire.checkout-component')->layout('layouts.base');
}
}
My Checkoutcomponent blade 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="placeOder">
<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 with Cash 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">Make the payment with your Credit/Debit card</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 card </span>
<span class="payment-desc">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
<button type="submit"class="btn btn-medium">Place order now</button>
</div>
</div>
</form>
</div><!--end main content area-->
</div><!--end container-->
</main>