From c90e85eef5fa8598ada5b0f7dd2b8f4cba5a6573 Mon Sep 17 00:00:00 2001 From: mojahidjouel Date: Mon, 11 Dec 2023 11:40:51 +0600 Subject: [PATCH] checkout complete --- app/Http/Controllers/CartController.php | 66 ++++++- .../Controllers/Students/sslController.php | 170 ++++++++++++++++++ app/Http/Middleware/VerifyCsrfToken.php | 3 +- ...023_11_26_153754_create_payments_table.php | 18 +- ...2023_12_09_135359_create_coupons_table.php | 4 +- ...23_12_09_170943_create_checkouts_table.php | 6 +- resources/views/frontend/cart.blade.php | 17 +- resources/views/frontend/checkout.blade.php | 51 +----- routes/web.php | 18 +- 9 files changed, 274 insertions(+), 79 deletions(-) create mode 100644 app/Http/Controllers/Students/sslController.php diff --git a/app/Http/Controllers/CartController.php b/app/Http/Controllers/CartController.php index ceab4df..9e38cdd 100644 --- a/app/Http/Controllers/CartController.php +++ b/app/Http/Controllers/CartController.php @@ -4,6 +4,7 @@ use Illuminate\Http\Request; use App\Models\Course; +use App\Models\Coupon; use App\Models\CourseCategory; class CartController extends Controller @@ -27,7 +28,9 @@ public function addToCart($id) $cart = session()->get('cart', []); 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 { $cart[$id] = [ "title_en" => $course->title_en, @@ -38,10 +41,11 @@ public function addToCart($id) "difficulty" => $course->difficulty, "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) @@ -52,7 +56,61 @@ public function remove(Request $request) unset($cart[$request->id]); session()->put('cart', $cart); } + $this->cart_total(); 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!'); + } } diff --git a/app/Http/Controllers/Students/sslController.php b/app/Http/Controllers/Students/sslController.php new file mode 100644 index 0000000..9e323cf --- /dev/null +++ b/app/Http/Controllers/Students/sslController.php @@ -0,0 +1,170 @@ +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 ""; + echo ""; + # 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' + ] + ); + } +} \ No newline at end of file diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 9e86521..810fa5f 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,7 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - // + 'payment/ssl/notify', + 'payment/ssl/cancel', ]; } diff --git a/database/migrations/2023_11_26_153754_create_payments_table.php b/database/migrations/2023_11_26_153754_create_payments_table.php index bdd7a28..e4edebe 100644 --- a/database/migrations/2023_11_26_153754_create_payments_table.php +++ b/database/migrations/2023_11_26_153754_create_payments_table.php @@ -13,18 +13,16 @@ public function up(): void { Schema::create('payments', function (Blueprint $table) { $table->id(); - $table->unsignedBigInteger('student_id')->index(); - $table->unsignedBigInteger('course_id')->index(); - $table->decimal('amount', 10, 2)->nullable(false); - $table->timestamp('payment_date')->useCurrent(); - $table->string('payment_method'); - $table->string('transaction_id'); - $table->enum('status', ['success', 'pending', 'failed'])->default('pending'); + $table->bigInteger('student_id')->nullable(); + $table->string('currency')->nullable(); + $table->string('currency_code')->nullable(); + $table->decimal('amount',10,2)->nullable(); + $table->decimal('currency_value',10,2)->nullable(); + $table->string('method')->nullable(); + $table->string('txnid')->nullable(); + $table->integer('status')->default(0)->comment('0 pending, 1 successfull, 2 fail'); $table->timestamps(); $table->softDeletes(); - - $table->foreign('student_id')->references('id')->on('students')->onDelete('cascade'); - $table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade'); }); } diff --git a/database/migrations/2023_12_09_135359_create_coupons_table.php b/database/migrations/2023_12_09_135359_create_coupons_table.php index f65b741..0c16df5 100644 --- a/database/migrations/2023_12_09_135359_create_coupons_table.php +++ b/database/migrations/2023_12_09_135359_create_coupons_table.php @@ -15,8 +15,8 @@ public function up(): void $table->id(); $table->string('code')->unique(); $table->decimal('discount', 8, 2); - $table->timestamp('valid_from')->nullable(); - $table->timestamp('valid_until')->nullable(); + $table->date('valid_from')->nullable(); + $table->date('valid_until')->nullable(); $table->timestamps(); $table->softDeletes(); }); diff --git a/database/migrations/2023_12_09_170943_create_checkouts_table.php b/database/migrations/2023_12_09_170943_create_checkouts_table.php index eb89300..ac281c6 100644 --- a/database/migrations/2023_12_09_170943_create_checkouts_table.php +++ b/database/migrations/2023_12_09_170943_create_checkouts_table.php @@ -13,9 +13,9 @@ public function up(): void { Schema::create('checkouts', function (Blueprint $table) { $table->id(); - $table->string('cart_data'); - $table->string('payer_name'); - $table->enum('payment_option', ['one_time', 'subscription'])->default('one_time'); + $table->longText('cart_data'); + $table->bigInteger('student_id'); + $table->string('txnid')->nullable(); $table->boolean('status')->default(1)->comment('1 active, 0 inactive'); $table->timestamps(); $table->softDeletes(); diff --git a/resources/views/frontend/cart.blade.php b/resources/views/frontend/cart.blade.php index 2223da7..b3b80de 100644 --- a/resources/views/frontend/cart.blade.php +++ b/resources/views/frontend/cart.blade.php @@ -36,7 +36,7 @@

By {{$details['instructor']}}

-

+

{{$details['quantity']}} {{$details['price'] ? '$' . $details['price'] : 'Free'}} {{$details['old_price'] ? '$' . $details['old_price'] : ''}}

@@ -56,26 +56,27 @@
Subtotal
-

{{'$' . number_format((float) $total, 2)}}

+

{{'$' . number_format((float) session('cart_details')['cart_total'] , 2)}}

-
Coupon Discount
-

0.00%

+
Coupon Discount ({{session('cart_details')['discount'] ?? 0.00}}%)
+

{{'$' . number_format((float) isset(session('cart_details')['discount_amount']) ? session('cart_details')['discount_amount']: 0.00 , 2)}}

Taxes
-

0.00

+

{{'$' . number_format((float) session('cart_details')['tax'] , 2)}}

Total:
-

{{'$' . number_format((float) $total, 2)}}

+

{{'$' . number_format((float) session('cart_details')['total_amount'] , 2)}}

-
+ + @csrf Checkout
- +
diff --git a/resources/views/frontend/checkout.blade.php b/resources/views/frontend/checkout.blade.php index 6bbd87b..582e395 100644 --- a/resources/views/frontend/checkout.blade.php +++ b/resources/views/frontend/checkout.blade.php @@ -20,7 +20,7 @@
@if(request()->session()->get('studentLogin')) - +
Checkout
@@ -28,44 +28,12 @@
-
-
- - -
-
-
-
- -
- - -
-
- - -
-
-
- - -
-
-
+ + @csrf
-
@@ -115,20 +83,19 @@
  • Subtotal

    -

    {{'$' . number_format((float) $total, 2)}}

    +

    {{'$' . number_format((float) session('cart_details')['cart_total'] , 2)}}

  • -

    Coupon Discount

    -

    0%

    +

    Coupon Discount ({{session('cart_details')['discount'] ?? 0.00}}%)

    +

    {{'$' . number_format((float) isset(session('cart_details')['discount_amount']) ? session('cart_details')['discount_amount']: 0.00 , 2)}}

  • taxes

    -

    $0.00

    +

    {{'$' . number_format((float) session('cart_details')['tax'] , 2)}}

  • Total:

    -

    {{'$' . number_format((float) $total, 2)}} -

    +

    {{'$' . number_format((float) session('cart_details')['total_amount'] , 2)}}

diff --git a/routes/web.php b/routes/web.php index 8486b03..1d9e264 100644 --- a/routes/web.php +++ b/routes/web.php @@ -27,6 +27,7 @@ use App\Http\Controllers\Students\AuthController as sauth; use App\Http\Controllers\Students\DashboardController as studashboard; use App\Http\Controllers\Students\ProfileController as stu_profile; +use App\Http\Controllers\Students\sslController as sslcz; /* |-------------------------------------------------------------------------- | Web Routes @@ -77,6 +78,9 @@ Route::get('/student/login', [sauth::class, 'signInForm'])->name('studentLogin'); Route::post('/student/login/{back_route}', [sauth::class, 'signInCheck'])->name('studentLogin.check'); 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::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('/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 () { return view('frontend.watchCourse'); @@ -97,14 +103,6 @@ Route::get('home', [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('courseDetails/{id}', [course::class, 'frontShow'])->name('courseDetails'); @@ -136,8 +134,10 @@ // Cart -Route::get('/', [CartController::class, 'index']); +Route::get('/cart_page', [CartController::class, 'index']); Route::get('cart', [CartController::class, 'cart'])->name('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::delete('remove-from-cart', [CartController::class, 'remove'])->name('remove.from.cart'); + +Route::post('coupon_check', [CartController::class, 'coupon_check'])->name('coupon_check'); \ No newline at end of file