checkout complete

Cette révision appartient à :
mojahidjouel 2023-12-11 11:40:51 +06:00
Parent c6253016e0
révision c90e85eef5
9 fichiers modifiés avec 274 ajouts et 79 suppressions

Voir le fichier

@ -4,6 +4,7 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Course; use App\Models\Course;
use App\Models\Coupon;
use App\Models\CourseCategory; use App\Models\CourseCategory;
class CartController extends Controller class CartController extends Controller
@ -27,7 +28,9 @@ public function addToCart($id)
$cart = session()->get('cart', []); $cart = session()->get('cart', []);
if (isset($cart[$id])) { if (isset($cart[$id])) {
$cart[$id]['quantity']++; $message="You have already added this course in your cart.";
return redirect()->back()->with('warning', $message);
//$cart[$id]['quantity']++;
} else { } else {
$cart[$id] = [ $cart[$id] = [
"title_en" => $course->title_en, "title_en" => $course->title_en,
@ -38,10 +41,11 @@ public function addToCart($id)
"difficulty" => $course->difficulty, "difficulty" => $course->difficulty,
"instructor" => $course->instructor ? $course->instructor->name_en : 'Unknown Instructor', "instructor" => $course->instructor ? $course->instructor->name_en : 'Unknown Instructor',
]; ];
session()->put('cart', $cart);
$this->cart_total();
$message="Product added to cart successfully!";
return redirect()->back()->with('success', $message);
} }
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
} }
public function remove(Request $request) public function remove(Request $request)
@ -52,7 +56,61 @@ public function remove(Request $request)
unset($cart[$request->id]); unset($cart[$request->id]);
session()->put('cart', $cart); session()->put('cart', $cart);
} }
$this->cart_total();
session()->flash('success', 'Product removed successfully'); session()->flash('success', 'Product removed successfully');
} }
} }
public function cart_total(){
$total = 0;
if (session('cart')){
foreach (session('cart') as $id => $details){
$total += $details['price'] * $details['quantity'];
}
}
if(isset(session('cart_details')['coupon_code'])){
$cart_total=$total;
$discount=($cart_total*(session('cart_details')['discount']/100));
$tax=(($cart_total-$discount)*0.15);
$total_amount=(($cart_total+$tax)-$discount);
$coupondata=array(
'cart_total'=>$cart_total,
'coupon_code'=>session('cart_details')['coupon_code'],
'discount'=>session('cart_details')['discount'],
'discount_amount'=>$discount,
'tax'=>$tax,
'total_amount'=>$total_amount
);
session()->put('cart_details', $coupondata);
}else{
$cart_data=array('cart_total'=>$total,'tax'=>($total*0.15),'total_amount'=>($total + ($total*0.15)));
session()->put('cart_details', $cart_data);
}
}
public function coupon_check(Request $request){
$coupon = Coupon::where('code',$request->coupon)
->where('valid_from','<=',date('Y-m-d'))
->where('valid_until','>=',date('Y-m-d'))
->pluck('discount')->toArray();
if(!empty($coupon)){
$cart_total=session('cart_details')['cart_total'];
$discount=($cart_total*($coupon[0]/100));
$tax=(($cart_total-$discount)*0.15);
$total_amount=(($cart_total+$tax)-$discount);
$coupondata=array(
'cart_total'=>$cart_total,
'coupon_code'=>$request->coupon,
'discount'=>$coupon[0],
'discount_amount'=>$discount,
'tax'=>$tax,
'total_amount'=>$total_amount
);
session()->put('cart_details', $coupondata);
}
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
} }

Voir le fichier

@ -0,0 +1,170 @@
<?php
namespace App\Http\Controllers\Students;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Student;
use App\Models\Payment;
use App\Models\Enrollment;
use App\Models\Checkout;
use Illuminate\Support\Facades\Session;
class sslController extends Controller
{
public function store(Request $request){
$user = Student::findOrFail(currentUserId());
$txnid = "SSLCZ_TXN_".uniqid();
$item_amount = session('cart_details')['total_amount'];
//$settings = Generalsetting::findOrFail(1);
$cart_details=array('cart'=>session('cart'),'cart_details'=>session('cart_details'));
$check = new Checkout;
$check->cart_data = base64_encode(json_encode($cart_details));
$check->student_id = $user->id;
$check->txnid = $txnid;
$check->status = 0;
$check->save();
$deposit = new Payment;
$deposit->student_id = $user->id;
$deposit->currency = "BDT";
$deposit->currency_code = "BDT";
$deposit->amount = session('cart_details')['total_amount'];
$deposit->currency_value = 1;
$deposit->method = 'SSLCommerz';
$deposit->txnid = $txnid;
$deposit->save();
$post_data = array();
$post_data['store_id'] = 'geniu5e1b00621f81e';//$settings->ssl_store_id;
$post_data['store_passwd'] = 'geniu5e1b00621f81e@ssl';//$settings->ssl_store_password;
$post_data['total_amount'] = $item_amount;
$post_data['currency'] = "BDT";
$post_data['tran_id'] = $txnid;
$post_data['success_url'] =action([sslController::class, 'notify']);//action ('User\DsslController@notify');
$post_data['fail_url'] = action([sslController::class, 'cancel']);//action('User\DsslController@cancle');
$post_data['cancel_url'] = action([sslController::class, 'cancel']);//action('User\DsslController@cancle');
# $post_data['multi_card_name'] = "mastercard,visacard,amexcard"; # DISABLE TO DISPLAY ALL AVAILABLE
# CUSTOMER INFORMATION
$post_data['cus_name'] = $user->name_en;
$post_data['cus_email'] = $user->email;
$post_data['cus_add1'] = "2no Gate";
$post_data['cus_city'] = "Chattogram";
$post_data['cus_state'] = "Chattogram";
$post_data['cus_postcode'] = "4100";
$post_data['cus_country'] = "Bangladesh";
$post_data['cus_phone'] = $user->contact_en;
$post_data['cus_fax'] = $user->contact_en;
# REQUEST SEND TO SSLCOMMERZ
//if($settings->ssl_sandbox_check == 1){
$direct_api_url = "https://sandbox.sslcommerz.com/gwprocess/v3/api.php";
//}
//else{
//$direct_api_url = "https://securepay.sslcommerz.com/gwprocess/v3/api.php";
// }
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $direct_api_url );
curl_setopt($handle, CURLOPT_TIMEOUT, 30);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($handle, CURLOPT_POST, 1 );
curl_setopt($handle, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE); # KEEP IT FALSE IF YOU RUN FROM LOCAL PC
$content = curl_exec($handle );
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($code == 200 && !( curl_errno($handle))) {
curl_close( $handle);
$sslcommerzResponse = $content;
} else {
curl_close( $handle);
return redirect()->back()->with('unsuccess',"FAILED TO CONNECT WITH SSLCOMMERZ API");
exit;
}
# PARSE THE JSON RESPONSE
$sslcz = json_decode($sslcommerzResponse, true );
if(isset($sslcz['GatewayPageURL']) && $sslcz['GatewayPageURL']!="" ) {
# THERE ARE MANY WAYS TO REDIRECT - Javascript, Meta Tag or Php Header Redirect or Other
# echo "<script>window.location.href = '". $sslcz['GatewayPageURL'] ."';</script>";
echo "<meta http-equiv='refresh' content='0;url=".$sslcz['GatewayPageURL']."'>";
# header("Location: ". $sslcz['GatewayPageURL']);
exit;
} else {
return redirect()->back()->with('unsuccess',"JSON Data parsing error!");
}
}
public function cancel(Request $request){
$input = $request->all();
$deposit = Payment::where('txnid','=',$input['tran_id'])->orderBy('created_at','desc')->first();
$student = Student::findOrFail($deposit->student_id);
$this->setSession($student);
return redirect()->route('studentdashboard')->with('danger', 'Payment Cancelled.');
}
public function notify(Request $request){
$cancel_url = action([sslController::class, 'cancel']);
$input = $request->all();
if($input['status'] == 'VALID'){
$deposit = Payment::where('txnid','=',$input['tran_id'])->orderBy('created_at','desc')->first();
$check = Checkout::where('txnid','=',$input['tran_id'])->orderBy('created_at','desc')->first();
$check->status = 1;
$check->save();
$student = Student::findOrFail($deposit->student_id);
$this->setSession($student);
$deposit->status = 1;
$deposit->save();
// store in transaction table
if ($deposit->status == 1) {
foreach(json_decode(base64_decode($check->cart_data))->cart as $key=>$course){
$enrole=new Enrollment;
$enrole->student_id=$check->student_id;
$enrole->course_id=$key;
$enrole->enrollment_date=date('Y-m-d');
$enrole->save();
}
}
return redirect()->route('studentdashboard')->with('success', 'Payment done!');
}
else {
return redirect()->route('studentdashboard')->with('danger', 'Please try Again!');
}
}
public function setSession($student){
return request()->session()->put(
[
'userId' => encryptor('encrypt', $student->id),
'userName' => encryptor('encrypt', $student->name_en),
'emailAddress' => encryptor('encrypt', $student->email),
'studentLogin' => 1,
'image' => $student->image ?? 'No Image Found'
]
);
}
}

Voir le fichier

@ -12,6 +12,7 @@ class VerifyCsrfToken extends Middleware
* @var array<int, string> * @var array<int, string>
*/ */
protected $except = [ protected $except = [
// 'payment/ssl/notify',
'payment/ssl/cancel',
]; ];
} }

Voir le fichier

@ -13,18 +13,16 @@ public function up(): void
{ {
Schema::create('payments', function (Blueprint $table) { Schema::create('payments', function (Blueprint $table) {
$table->id(); $table->id();
$table->unsignedBigInteger('student_id')->index(); $table->bigInteger('student_id')->nullable();
$table->unsignedBigInteger('course_id')->index(); $table->string('currency')->nullable();
$table->decimal('amount', 10, 2)->nullable(false); $table->string('currency_code')->nullable();
$table->timestamp('payment_date')->useCurrent(); $table->decimal('amount',10,2)->nullable();
$table->string('payment_method'); $table->decimal('currency_value',10,2)->nullable();
$table->string('transaction_id'); $table->string('method')->nullable();
$table->enum('status', ['success', 'pending', 'failed'])->default('pending'); $table->string('txnid')->nullable();
$table->integer('status')->default(0)->comment('0 pending, 1 successfull, 2 fail');
$table->timestamps(); $table->timestamps();
$table->softDeletes(); $table->softDeletes();
$table->foreign('student_id')->references('id')->on('students')->onDelete('cascade');
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
}); });
} }

Voir le fichier

@ -15,8 +15,8 @@ public function up(): void
$table->id(); $table->id();
$table->string('code')->unique(); $table->string('code')->unique();
$table->decimal('discount', 8, 2); $table->decimal('discount', 8, 2);
$table->timestamp('valid_from')->nullable(); $table->date('valid_from')->nullable();
$table->timestamp('valid_until')->nullable(); $table->date('valid_until')->nullable();
$table->timestamps(); $table->timestamps();
$table->softDeletes(); $table->softDeletes();
}); });

Voir le fichier

@ -13,9 +13,9 @@ public function up(): void
{ {
Schema::create('checkouts', function (Blueprint $table) { Schema::create('checkouts', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('cart_data'); $table->longText('cart_data');
$table->string('payer_name'); $table->bigInteger('student_id');
$table->enum('payment_option', ['one_time', 'subscription'])->default('one_time'); $table->string('txnid')->nullable();
$table->boolean('status')->default(1)->comment('1 active, 0 inactive'); $table->boolean('status')->default(1)->comment('1 active, 0 inactive');
$table->timestamps(); $table->timestamps();
$table->softDeletes(); $table->softDeletes();

Voir le fichier

@ -36,7 +36,7 @@
</h6> </h6>
<p>By <a href="#">{{$details['instructor']}}</a></p> <p>By <a href="#">{{$details['instructor']}}</a></p>
<div class="bottom-wizard d-flex justify-content-between align-items-center"> <div class="bottom-wizard d-flex justify-content-between align-items-center">
<p> <p> {{$details['quantity']}}
{{$details['price'] ? '$' . $details['price'] : 'Free'}} {{$details['price'] ? '$' . $details['price'] : 'Free'}}
<span><del>{{$details['old_price'] ? '$' . $details['old_price'] : ''}}</del></span> <span><del>{{$details['old_price'] ? '$' . $details['old_price'] : ''}}</del></span>
</p> </p>
@ -56,26 +56,27 @@
<div class="summery-wizard"> <div class="summery-wizard">
<div class="summery-wizard-text pt-0"> <div class="summery-wizard-text pt-0">
<h6>Subtotal</h6> <h6>Subtotal</h6>
<p>{{'$' . number_format((float) $total, 2)}}</p> <p> {{'$' . number_format((float) session('cart_details')['cart_total'] , 2)}}</p>
</div> </div>
<div class="summery-wizard-text"> <div class="summery-wizard-text">
<h6>Coupon Discount</h6> <h6>Coupon Discount ({{session('cart_details')['discount'] ?? 0.00}}%)</h6>
<p>0.00%</p> <p>{{'$' . number_format((float) isset(session('cart_details')['discount_amount']) ? session('cart_details')['discount_amount']: 0.00 , 2)}}</p>
</div> </div>
<div class="summery-wizard-text"> <div class="summery-wizard-text">
<h6>Taxes</h6> <h6>Taxes</h6>
<p>0.00</p> <p> {{'$' . number_format((float) session('cart_details')['tax'] , 2)}}</p>
</div> </div>
<div class="total-wizard"> <div class="total-wizard">
<h6 class="font-title--card">Total:</h6> <h6 class="font-title--card">Total:</h6>
<p class="font-title--card">{{'$' . number_format((float) $total, 2)}}</p> <p class="font-title--card">{{'$' . number_format((float) session('cart_details')['total_amount'] , 2)}}</p>
</div> </div>
<form action="#"> <form action="{{route('coupon_check')}}" method="post">
@csrf
<a href="{{route('checkout')}}" <a href="{{route('checkout')}}"
class="button button-lg button--primary form-control mb-lg-3">Checkout</a> class="button button-lg button--primary form-control mb-lg-3">Checkout</a>
<label for="coupon">Apply Coupon</label> <label for="coupon">Apply Coupon</label>
<div class="cart-input"> <div class="cart-input">
<input type="text" class="form-control" placeholder="Coupon Code" id="coupon" /> <input type="text" name="coupon" class="form-control" placeholder="Coupon Code" id="coupon" />
<button type="submit" class="sm-button">Apply</button> <button type="submit" class="sm-button">Apply</button>
</div> </div>
</form> </form>

Voir le fichier

@ -20,7 +20,7 @@
<section class="section checkout-area"> <section class="section checkout-area">
<div class="container"> <div class="container">
@if(request()->session()->get('studentLogin')) @if(request()->session()->get('studentLogin'))
<?php print_r(base64_encode(json_encode(session('cart')))) ?>
<div class="row"> <div class="row">
<div class="col-lg-6 checkout-area-checkout"> <div class="col-lg-6 checkout-area-checkout">
<h6 class="checkout-area__label">Checkout</h6> <h6 class="checkout-area__label">Checkout</h6>
@ -28,44 +28,12 @@
<div class="tab-content" id="pills-tabContent"> <div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-checkout" role="tabpanel" <div class="tab-pane fade show active" id="pills-checkout" role="tabpanel"
aria-labelledby="pills-checkout-tab"> aria-labelledby="pills-checkout-tab">
<form action="#"> <form action="{{route('payment.ssl.submit')}}" method="post">
<div class="mb-3"> @csrf
<label for="payer_name">Name on Card</label>
<input type="text" class="form-control" name="payer_name" placeholder="Type here" />
</div>
<div class="mb-3">
<div class="row">
<div class="col-md-6 mb-3 mb-lg-0">
<label for="payment_option">Payment Options</label>
<div class="form-check d-flex align-items-center ps-0">
<input type="checkbox" id="one_time" />
<label class="form-check-label ms-2 mb-0" for="one_time">
One Time
</label>
</div>
<div class="form-check d-flex align-items-center ps-0">
<input type="checkbox" id="subscription" />
<label class="form-check-label ms-2 mb-0" for="subscription">
Subscription
</label>
</div>
</div>
<div class="col-md-6">
<label for="status">Status</label>
<select class="form-control" name="status">
<option value="1" class="form-control" @if(old('status')==1) selected
@endif>Active</option>
<option value="0" class="form-control" @if(old('status')==0) selected
@endif>Inactive</option>
</select>
</div>
</div>
</div>
<div class="mb-4"> <div class="mb-4">
<div class="form-check d-flex align-items-center ps-0"> <div class="form-check d-flex align-items-center ps-0">
<input type="checkbox" id="flexCheckIndeterminate-one" />
<label class="form-check-label ms-2 mb-0" for="flexCheckIndeterminate-one"> <label class="form-check-label ms-2 mb-0" for="flexCheckIndeterminate-one">
Save my information for a faster checkout Please check your product before payment
</label> </label>
</div> </div>
</div> </div>
@ -115,20 +83,19 @@
<ul> <ul>
<li> <li>
<p>Subtotal</p> <p>Subtotal</p>
<p>{{'$' . number_format((float) $total, 2)}}</p> <p>{{'$' . number_format((float) session('cart_details')['cart_total'] , 2)}}</p>
</li> </li>
<li> <li>
<p>Coupon Discount</p> <p>Coupon Discount ({{session('cart_details')['discount'] ?? 0.00}}%)</p>
<p>0%</p> <p>{{'$' . number_format((float) isset(session('cart_details')['discount_amount']) ? session('cart_details')['discount_amount']: 0.00 , 2)}}</p>
</li> </li>
<li> <li>
<p>taxes</p> <p>taxes</p>
<p>$0.00</p> <p>{{'$' . number_format((float) session('cart_details')['tax'] , 2)}}</p>
</li> </li>
<li> <li>
<p class="font-title--card">Total:</p> <p class="font-title--card">Total:</p>
<p class="total-price font-title--card">{{'$' . number_format((float) $total, 2)}} <p class="total-price font-title--card">{{'$' . number_format((float) session('cart_details')['total_amount'] , 2)}}</p>
</p>
</li> </li>
</ul> </ul>
</div> </div>

Voir le fichier

@ -27,6 +27,7 @@
use App\Http\Controllers\Students\AuthController as sauth; use App\Http\Controllers\Students\AuthController as sauth;
use App\Http\Controllers\Students\DashboardController as studashboard; use App\Http\Controllers\Students\DashboardController as studashboard;
use App\Http\Controllers\Students\ProfileController as stu_profile; use App\Http\Controllers\Students\ProfileController as stu_profile;
use App\Http\Controllers\Students\sslController as sslcz;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Web Routes | Web Routes
@ -77,6 +78,9 @@
Route::get('/student/login', [sauth::class, 'signInForm'])->name('studentLogin'); Route::get('/student/login', [sauth::class, 'signInForm'])->name('studentLogin');
Route::post('/student/login/{back_route}', [sauth::class, 'signInCheck'])->name('studentLogin.check'); Route::post('/student/login/{back_route}', [sauth::class, 'signInCheck'])->name('studentLogin.check');
Route::get('/student/logout', [sauth::class, 'signOut'])->name('studentlogOut'); Route::get('/student/logout', [sauth::class, 'signOut'])->name('studentlogOut');
/* ssl payment */
Route::post('/payment/ssl/notify', [sslcz::class,'notify'])->name('payment.ssl.notify');
Route::post('/payment/ssl/cancel', [sslcz::class,'cancel'])->name('payment.ssl.cancel');
Route::middleware(['checkstudent'])->prefix('students')->group(function () { Route::middleware(['checkstudent'])->prefix('students')->group(function () {
Route::get('/dashboard', [studashboard::class, 'index'])->name('studentdashboard'); Route::get('/dashboard', [studashboard::class, 'index'])->name('studentdashboard');
@ -84,6 +88,8 @@
Route::post('/profile/save', [stu_profile::class, 'save_profile'])->name('student_save_profile'); Route::post('/profile/save', [stu_profile::class, 'save_profile'])->name('student_save_profile');
Route::post('/change-image', [stu_profile::class, 'changeImage'])->name('change_image'); Route::post('/change-image', [stu_profile::class, 'changeImage'])->name('change_image');
// ssl Routes
Route::post('/payment/ssl/submit', [sslcz::class,'store'])->name('payment.ssl.submit');
Route::get('/watchCourse', function () { Route::get('/watchCourse', function () {
return view('frontend.watchCourse'); return view('frontend.watchCourse');
@ -97,14 +103,6 @@
Route::get('home', [HomeController::class, 'index'])->name('home'); Route::get('home', [HomeController::class, 'index'])->name('home');
Route::get('/', [HomeController::class, 'index'])->name('home'); Route::get('/', [HomeController::class, 'index'])->name('home');
// Route::get('/', function () {
// return view('frontend.home');
// });
// Route::get('/home', function () {
// return view('frontend.home');
// })->name('home');
Route::get('searchCourse', [course::class, 'frontIndex'])->name('searchCourse'); Route::get('searchCourse', [course::class, 'frontIndex'])->name('searchCourse');
Route::get('courseDetails/{id}', [course::class, 'frontShow'])->name('courseDetails'); Route::get('courseDetails/{id}', [course::class, 'frontShow'])->name('courseDetails');
@ -136,8 +134,10 @@
// Cart // Cart
Route::get('/', [CartController::class, 'index']); Route::get('/cart_page', [CartController::class, 'index']);
Route::get('cart', [CartController::class, 'cart'])->name('cart'); Route::get('cart', [CartController::class, 'cart'])->name('cart');
Route::get('add-to-cart/{id}', [CartController::class, 'addToCart'])->name('add.to.cart'); Route::get('add-to-cart/{id}', [CartController::class, 'addToCart'])->name('add.to.cart');
Route::patch('update-cart', [CartController::class, 'update'])->name('update.cart'); Route::patch('update-cart', [CartController::class, 'update'])->name('update.cart');
Route::delete('remove-from-cart', [CartController::class, 'remove'])->name('remove.from.cart'); Route::delete('remove-from-cart', [CartController::class, 'remove'])->name('remove.from.cart');
Route::post('coupon_check', [CartController::class, 'coupon_check'])->name('coupon_check');