Merge pull request #224 from WDI-Ideas/HritikCheers

Hritik cheers
This commit is contained in:
Hritikkk9
2024-07-02 19:22:06 +05:30
committed by GitHub
14 changed files with 825 additions and 308 deletions

View File

@@ -3,9 +3,18 @@
namespace App\Http\Controllers\APIs\Customer_API;
use App\Http\Controllers\Controller;
use App\Models\IamPrincipal;
use App\Models\SubscriptionProducts;
use App\Models\Subscriptions;
use App\Services\APIs\CustomerAPIs\RulesApiServices;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Redirect;
class SubscriptionController extends Controller
{
@@ -17,19 +26,48 @@ class SubscriptionController extends Controller
public function mySubscription(Request $request)
{
try {
// dd($request->header('access-token'));
$token = readHeaderToken();
// dd("acc",$token);
// $token = true;
// dd($token, Session::get('vendorToken'));
if ($token) {
// $user_id = 12;
$user_id = $token['sub'];
$dateTime = now();
$formattedDateTime = $dateTime->format('Y-m-d H:i:s');
$isSubscribedUser = Subscriptions::where('iam_principal_xid', $user_id)
->where('next_payment_date', '>=', $formattedDateTime)
->first();
$userData = IamPrincipal::where('id', $user_id)->first();
// $request['iam_principal_id'] = $user_id;
$products = SubscriptionProducts::where('is_active', '1')->get();
return view('Admin.pages.subscriptions.my-subscription');
if ($isSubscribedUser) {
return view("Admin.pages.subscriptions.my-subscription", compact('user_id', 'userData', 'isSubscribedUser', 'products'));
}
$productList = SubscriptionProducts::where('is_active', 1)->first();
return view('Admin.pages.subscriptions.list-of-products', compact('productList','userData'));
} else {
return jsonResponseWithErrorMessageApi(__('auth.user_deleted'), 409);
}
} catch (\Exception $e) {
Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]);
return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500);
return jsonResponseWithErrorMessage(__('auth.something_went_wrong'));
}
}
//created by; Hritik
//created by; Hritik
//On - 28th June ,2024
//use - to get Data of User in Webview and show list of product
@@ -37,10 +75,9 @@ class SubscriptionController extends Controller
public function listOfProduct(Request $request)
{
try {
$productList = SubscriptionProducts::where('is_active', 1)->first();
return view('Admin.pages.subscriptions.list-of-products');
return view('Admin.pages.subscriptions.list-of-products', compact('productList'));
} catch (\Exception $e) {
Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]);
@@ -51,190 +88,165 @@ class SubscriptionController extends Controller
//created by; Hritik
//On - 18th May ,2024
//use - to get Data of Detailed List Of Product , Monthly & Yearly
public function nextPage(Request $request)
{
//On - 02th July ,2024
//use - to Create Subscription Product & price for Monthly
try {
// $token = readHeaderToken();
$token = true;
// dd($request);
if ($token) {
// $user_id = $token['sub'];
// $validator = $this->validateSubscriptionsForm($request);
// if ($validator->fails()) {
// $validationErrors = $validator->errors()->all();
// Log::error("Razorpay subscriptions plan validation error: " . implode(", ", $validationErrors));
// return jsonResponseWithErrorMessageApi($validationErrors, 203);
// }
// $request['iam_principal_id'] = $user_id;
$productTypeXid = $request->query('selected_product_type_id');
$userId = $request->query('user_id');
$products = Products::with('productType', 'productTier')
->where('product_type_xid', $productTypeXid)
->where('is_active', '1')->get();
foreach ($products as $k => $val) {
$products[$k]['product_image'] = ListingImageUrl('product_image', $val['product_image']);
}
$user = IamPrincipal::where('id', $userId)->where('is_active', 1)->first();
$user_name = $user->user_name;
$user_contact_no = $user->phone_number;
$user_email = $user->email_address;
return view(
'admin-dashboard.pages.razorpay-subscription.subscription-product-detail-pay',
compact(
'products',
'userId',
'user_name',
'user_contact_no',
'user_email',
)
);
} else {
return jsonResponseWithErrorMessageApi(__('auth.user_deleted'), 409);
}
} catch (Exception $e) {
Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]);
return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500);
}
}
//created by :-Hritik
// On - 16th may ,2024
//subscription to a particular project based on plans and returning the subscription id to web to open Subscription screen
public function subscribeToProduct(Request $request)
public function createStripeProduct(Request $request)
{
try {
DB::beginTransaction();
// $token = readHeaderToken();
$iamId = $request->iam_principal_xid;
$razorPayPlanId = $request->razorpay_plan_id;
$productId = $request->product_id;
$stripeSecret = (config('constants.subscription.stripe_secret_key'));
$user = IamPrincipal::where('id', $iamId)->where('is_active', 1)->first();
$id = $user->id;
$phone = $user->phone_number;
$email = $user->email_address;
// $stripeSecret = env('STRIPE_SECRET');
$stripe = new \Stripe\StripeClient($stripeSecret);
// dd($stripeSecret,$stripe,$request->all());
$product = Products::where('razorpay_plan_id', $razorPayPlanId)
->where('is_active', 1)
->first();
$validator = $this->validateSubscriptionsproductForm($request);
if ($product && $product->product_tier_xid == 1) {
//if product tier is monthly then we are setting count to 1200 means 100 years
$total_count = 1200;
} else if ($product && $product->product_tier_xid == 2) {
//if product tier is Yearly then we are setting count to 100 means 100 years
$total_count = 100;
} else {
//if product tier is not found then we are setting to 1
$total_count = 1;
if ($validator->fails()) {
$validationErrors = $validator->errors()->all();
Log::error("Stripe subscriptions plan validation error: " . implode(", ", $validationErrors));
return jsonResponseWithErrorMessageApi($validationErrors, 203);
}
$api = new Api(config('constants.razorpay.key_id'), config('constants.razorpay.key_secret'));
$plan_id = $product->razorpay_plan_id;
// Call the subscription create method with request parameters
$response = $api->subscription->create([
'plan_id' => $plan_id,
'total_count' => $total_count,
'quantity' => '1',
'notes' => [
'product_id' => intval($product->id),
'iam_principal_xid' => intval($iamId)
],
'notify_info' => [
'notify_phone' => $phone,
'notify_email' => $email
],
// 'callback_url' => route('my-subscription-page')
$id = SubscriptionProducts::create([
'product_name' => $request->product_name,
'product_value' => $request->product_value,
'product_details' => $request->product_details,
]);
$notes = $response->notes;
$notesArray = [
'product_id' => $notes->product_id,
'iam_principal_xid' => $notes->iam_principal_xid,
];
$productCreate = $stripe->products->create([
'name' => $request->product_name,
]);
$updateCreatedPlan = SubscriptionProducts::where('id', $id->id)->update([
'stripe_product_id' => $productCreate->id
]);
$totalPrice = $request->product_value;
if ($totalPrice && $totalPrice != 0 && $totalPrice != null) {
$productPrice1 = $stripe->prices->create([
'unit_amount' => $totalPrice * 100,
// amount entered by Admin (in cents)
'currency' => 'usd',
'recurring' => ['interval' => 'month'],
'product' => $productCreate->id,
'nickname' => 'Monthly Price',
]);
$updateCreatedPlan = SubscriptionProducts::where('id', $id->id)->update([
'stripe_price_id' => $productPrice1->id
]);
}
DB::commit();
// return response()->json($response);
return response()->json([
'subId' => $response->id,
'userId' => $iamId,
]);
return jsonResponseWithSuccessMessage(__('success.save_data', $response->short_url));
// return Redirect::away($response->short_url);
} catch (Exception $e) {
return jsonResponseWithSuccessMessage(__('success.save_data'), 200);
} catch (\Exception $ex) {
DB::rollBack();
Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]);
return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500);
Log::error('Favourite Restaurant service failed: ' . $ex->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
}
}
public function validateSubscriptionsForm(Request $request)
public function validateSubscriptionsproductForm(Request $request)
{
return Validator::make(
$request->all(),
[
'plan_id' => 'required',
'product_name' => 'required',
'product_value' => 'required',
'product_details' => 'required',
]
);
}
//created by; Hritik
//On - 02th July ,2024
//use - to Create Subscription
public function subscriptionToPlan(Request $request)
{
// dd($request->all());
try {
$userId = $request->user_id;
$subscriptionProductXid = $request->subscription_product_xid;
$stripeSecret = (config('constants.subscription.stripe_secret_key'));
$stripe = new \Stripe\StripeClient($stripeSecret);
// $taxId = (config('services.stripe.tax_id'));
$userData = IamPrincipal::where('id', $userId)->first();
if ($userData) {
$subscriptionPlan = SubscriptionProducts::where('id', $subscriptionProductXid)->first();
if ($subscriptionPlan && $subscriptionPlan->stripe_price_id && $subscriptionPlan->stripe_price_id != null) {
$checkout = $stripe->checkout->sessions->create([
'customer_email' => $userData->email_address,
'line_items' => [
[
'price' => $subscriptionPlan->stripe_price_id,
'quantity' => 1,
// 'tax_rates'=>[$taxId],
],
],
'mode' => 'subscription',
// 'allow_promotion_codes' => true,
// 'tax_id_collection' => ['enabled' => true],
'metadata' => [
'userId' => $userData->id,
'userEmail' => $userData->email_address,
'subscriptionProductXid' => $subscriptionProductXid
],
'success_url' => "{{route('thankyou')}}",
// 'cancel_url' => "http://localhost/cheerstothe_season_2_o/my-subscription-page",
]);
return Redirect::away($checkout->url);
//note:-for now i am just sending the cveonly=0 and lmacve=1 for reference .'&lmacve=1&cveonly=0'
}else{
return redirect()->back()->with(['error' => "Something went wrong while subscription!" ]);
}
}
} catch (\Exception $e) {
Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]);
return jsonResponseWithErrorMessage(__('auth.something_went_wrong'));
// return redirect()->back()->with(['error' => "Something went wrong while subscription!" . $e->getMessage()]);
}
}
public function thankyou(Request $request)
{
$userId = $request->query('user_xid');
if ($userId) {
//store data in DATABSE
RazorpayWebhookUsers::updateOrCreate(
['iam_principal_xid' => $userId],
['isSuccessPayment' => 1]
);
}
return view('admin-dashboard.pages.razorpay-subscription.thankyou');
return view('Admin.pages.subscriptions.thank-you');
}
public function cancelThankYou(Request $request)
{
$endAt = $request->query('end_date');
if ($endAt) {
$endDate = $endAt;
} else {
$endDate = null;
}
return view('admin-dashboard.pages.razorpay-subscription.cancel-thank-you', compact('endDate'));
}
//created by; Hritik
//On - 28th May ,2024
//use - To cancel the subscription of user on end of subscription end period
@@ -307,7 +319,7 @@ class SubscriptionController extends Controller
// {
// // dd($request->all());
// $razorPayPlanId = $request->razorpay_plan_id;
// $razorPaysubscriptionProductXid = $request->razorpay_plan_id;
// $productTypeId = $request->product_type_xid;
// $productTierId = $request->product_tier_xid;
// $iamId = $request->iam_principal_xid;
@@ -323,7 +335,7 @@ class SubscriptionController extends Controller
// $products = Products::where('product_type_xid', $productTypeId)
// ->where('product_tier_xid', $productTierId)
// ->where('razorpay_plan_id', $razorPayPlanId)
// ->where('razorpay_plan_id', $razorPaysubscriptionProductXid)
// ->where('is_active', '1')->first();
// if (!$products) {

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Http\Controllers;
use App\Helpers\onesignalhelper;
use App\Http\Controllers\Controller;
use App\Models\IamPrincipal;
use App\Models\SubscriptionProducts;
use App\Models\Subscriptions;
use Illuminate\Http\Request;
use App\Models\API\SubscriptionPayModel;
use Stripe\Event;
use Stripe\Stripe;
use App\Models\API\PatientModel;
use App\Models\API\PatientCareGiverLinkModel;
use App\Models\API\CareGiverModel;
use App\Models\API\SubscriptionModel;
// /var/www/html/simplitend/app/Http/Controllers/API/;
use App\Http\Helpers\MyHelper;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
class StripeWebhookController extends Controller
{
//
public function handleWebhook(Request $request)
{
// Verify the webhook signature for security
$secret = config('constant.subscription.webhook_secret'); // Your webhook secret key
$payload = $request->getContent();
$sigHeader = $request->header('Stripe-Signature');
$event = null;
try {
$event = Event::constructFrom(
json_decode($payload, true),
$sigHeader,
config('constant.subscription.webhook_secret')
);
} catch (\UnexpectedValueException $e) {
// Invalid payload
return response()->json(['error' => 'Invalid payload'], 400);
} catch (\Stripe\Exception\SignatureVerificationException $e) {
// Signature verification failed
return response()->json(['error' => 'Signature verification failed'], 400);
}
$stripeSecret = config('services.stripe.key');
$stripe = new \Stripe\StripeClient($stripeSecret);
if ($event->type === 'checkout.session.completed') {
try {
DB::beginTransaction();
// Handle successful subscription payment
// You can access event data like $event->data->object
// Session::flush();
$session = $event->data->object;
$metadata = $session->metadata;
if ($metadata == null || empty($metadata)) {
return response('Webhook Metadata received at null ', 200);
}
$userId = $metadata->userId;
$userEmail = $metadata->userEmail;
$subscriptionProductId = $metadata->subscriptionProductXid;
$subscriptionProductData = SubscriptionProducts::where('id', $subscriptionProductId)->first();
//checkout store in db
$subscriptionData = $stripe->checkout->sessions->retrieve($session->id, []);
$SubscriptionObject = $stripe->subscriptions->retrieve($subscriptionData->subscription, []);
$priceObject = $stripe->prices->retrieve($SubscriptionObject->plan->id, []);
$amountSubtotalDollars = $subscriptionData->amount_total / 100;
// Log::info('Subscription has been started ');
$subscriptionObjectFromInvoice = $stripe->subscriptions->retrieve($subscriptionData->subscription, []);
$upcoming_invoice = $stripe->invoices->upcoming([
'subscription' => $subscriptionData->subscription, // use retrieved id from subscription
]);
$id = Subscriptions::updateOrCreate(
['iam_principal_xid' => $userId, 'subscription_product_xid' => $subscriptionProductId],
[
'subscription_id' => $subscriptionData->subscription,
'amount' => $amountSubtotalDollars,
'stripe_customer_id' => $subscriptionData->customer,
'subscription_status' => $subscriptionObjectFromInvoice->status,
'current_period_start' => date('Y-m-d H:i:s', $SubscriptionObject->current_period_start),
'current_period_end' => date('Y-m-d H:i:s', $SubscriptionObject->current_period_end),
'status' => 'complete',
'next_payment_date' => date('Y-m-d H:i:s', $upcoming_invoice->next_payment_attempt)
]
);
$getUserData = IamPrincipal::where('id', $userId)->first();
$title = "Congratulations you subscription is now active";
$message = $getUserData->first_name . " has subscribed for " . $subscriptionProductData->_name . " subscription";
$content_type = "new_subscription";
onesignalhelper::sendNotificationApi($getUserData->one_signal_player_id, $title, $message, $content_type, $image = null, $id = null);
//Log::info('Subscription Taken Successfully by ' . $getCaregiverData->iamprincipal->user_name);
DB::commit();
} catch (\Exception $e) {
// Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage());
// return response()->json(['error' => __('something_went_wrong')], 500);
//Log::error('Customer Subscription Checkout session function failed: ' . $e->getMessage());
DB::rollBack();
}
//end
}
return response('Webhook received', 200);
}
}

View File

@@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware
* @var array<int, string>
*/
protected $except = [
//
'stripe/webhook',
];
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SubscriptionProducts extends Model
{
use HasFactory;
protected $table = 'subscription_products';
protected $guarded = [];
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Subscriptions extends Model
{
use HasFactory;
protected $table = 'subscriptions';
protected $guarded = [];
}

View File

@@ -17,6 +17,7 @@
"laravel/tinker": "^2.9",
"livewire/livewire": "^3.0",
"maatwebsite/excel": "^3.1",
"stripe/stripe-php": "^15.0",
"tymon/jwt-auth": "^2.1"
},
"require-dev": {

63
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2852b42da6667c169d5788199ec7dd10",
"content-hash": "8d111b180ec2e668fb5132bad051e89a",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -4751,6 +4751,65 @@
},
"time": "2024-02-15T16:41:13+00:00"
},
{
"name": "stripe/stripe-php",
"version": "v15.0.0",
"source": {
"type": "git",
"url": "https://github.com/stripe/stripe-php.git",
"reference": "96f0dbe9c2b5365d716f86d92a27feecca2cbaee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/96f0dbe9c2b5365d716f86d92a27feecca2cbaee",
"reference": "96f0dbe9c2b5365d716f86d92a27feecca2cbaee",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": ">=5.6.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "3.5.0",
"phpstan/phpstan": "^1.2",
"phpunit/phpunit": "^5.7 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"Stripe\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Stripe and contributors",
"homepage": "https://github.com/stripe/stripe-php/contributors"
}
],
"description": "Stripe PHP Library",
"homepage": "https://stripe.com/",
"keywords": [
"api",
"payment processing",
"stripe"
],
"support": {
"issues": "https://github.com/stripe/stripe-php/issues",
"source": "https://github.com/stripe/stripe-php/tree/v15.0.0"
},
"time": "2024-06-24T23:05:11+00:00"
},
{
"name": "symfony/clock",
"version": "v7.1.0",
@@ -9862,5 +9921,5 @@
"php": "^8.2"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.3.0"
}

25
config/constants.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
/*
* created by : Chandan Yadav
* Created On : 03-November-2023
* Uses : To display message on admin panel
*/
return [
'UTF8_ENABLED' => TRUE,
'DIMENTIONS' => [
"THUMBNAIL" => "300*160 pixels (3:2), Max Size 2MB and .jpg format image",
],
'SIZE' => [
"THUMBNAIL" => "7168"
],
'PLATFORM' => ['ios', 'android', 'web'],
'subscription' => [
'stripe_private_key' => env('STRIPE_KEY'),
'stripe_secret_key' => env('STRIPE_SECRET'),
'webhook_secret' => env('STRIPE_WEBHOOK_SECRET'),
],
];

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
//
Schema::create('subscription_products', function (Blueprint $table) {
$table->id();
$table->string('product_name')->nullable();
$table->string('product_value')->nullable();
$table->longText('product_details')->nullable();
$table->string('stripe_product_id')->nullable();
$table->string('stripe_price_id')->nullable();
$table->boolean('is_active')->default(1)->comment('1=Active, 0=Expired');
$table->softDeletes();
$table->integer('created_by')->nullable();
$table->integer('modified_by')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
Schema::dropIfExists('subscription_products');
}
};

View File

@@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('subscriptions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('subscription_product_xid');
$table->unsignedBigInteger('iam_principal_xid');
$table->foreign('subscription_product_xid')->references('id')->on('subscription_products')->onDelete('cascade');
$table->foreign('iam_principal_xid')->references('id')->on('iam_principal')->onDelete('cascade');
$table->string('amount')->nullable();
$table->string('stripe_customer_id')->nullable();
$table->string('payment_intent_id')->nullable();
$table->string('payment_intent_client_secret')->nullable();
$table->string('subscription_id')->nullable();
$table->string('subscription_status')->nullable();
$table->dateTime('current_period_start')->nullable();
$table->dateTime('current_period_end')->nullable();
$table->string('status')->nullable();
$table->dateTime('next_payment_date')->nullable();
$table->boolean('is_cancelled_subscription')->default(0)->comment('1=Cancelled, 0=Not Cancelled');
$table->dateTime('cancelled_at')->nullable();
$table->boolean('is_active')->default(1)->comment('1=Active, 0=Expired');
$table->softDeletes();
$table->integer('created_by')->nullable();
$table->integer('modified_by')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('subscriptions');
}
};

View File

@@ -2,161 +2,206 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="{{ asset('resources/views/Admin/pages/subscriptions/subscription-style.css') }}" />
<title>List Of Products</title>
<title>List Of Products</title>
</head>
<body>
<section class="new-subs-main">
<div class="container">
<h3 class="comm-head mt-3 d-flex gap-2" style="font-size: 20px;">
<a href="#">
{{-- <img src="images/arrow-left.png" alt=""> --}}
<section class="new-subs-main">
<div class="container">
<div class="col-md-12">
@if (session('success'))
<div class="alert alert-success" id="alert-success">
{{ session('success') }}
</div>
@endif
{{-- <img src="{{ asset('resources/views/Admin/pages/subscriptions/images/arrow-left.png') }}" /> --}}
</a>
</h3>
<div class="new-subs-img">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/cheers-logo.png') }}" alt="">
</div>
<p class="text-center mt-3 para-mid">Subscribe to Cheers to the Season app to gain access to free cocktails* at
local
restaurants.
</p>
<p class="text-center mt-3 grey-para">*Free cocktail stipulations vary by state in accordance with local liquor
laws.</p>
<div class="subscription-card">
<h3 class="head">Subscription</h3>
<div class="main-text">
<div>
<p class="comm-head">Monthly Plan</p>
<p class="grey-para">Billed monthly</p>
</div>
<div>
<p class="price">$2.99</p>
</div>
</div>
<hr class="my-5" style="border-top: 2px dashed; color: #042857;">
<div class="input-group mb-5 d-flex align-items-center justify-content-between">
<div class="in-group">
<label class="comm-head" for="">Enter coupon code</label>
</div>
<div class="apply-btn">
<button class="apply" type="button">Apply</button>
</div>
<input type="text" class="form-control coupon-input mt-3" placeholder="Enter coupon code">
</div>
<hr>
<div class="main-text">
<div>
<p class="comm-head">Applied Discount</p>
<p class="grey-para">First Month free </p>
</div>
<div>
<p class="price">$2.99</p>
</div>
</div>
<hr>
<div class="main-text">
<div>
<p class="comm-head">Total Payment</p>
</div>
<div>
<p class="price">$0.00</p>
</div>
</div>
<button class="subscribe-button w-75" type="button" data-bs-toggle="modal"
data-bs-target="#exampleModal">SUBSCRIBE
NOW</button>
<p class="grey-para text-center mt-3">You will be charged $2.99 every month after your free trial period ends.
</p>
<p class="grey-para text-center mt-2">Subscription will be renewed monthly until cancelled.</p>
</div>
</div>
</section>
<section class="mt-3 mb-5">
<h3 class="text-center head my-4">Program/Redemption Rules</h3>
<div class="container">
<div data-ui-tablist class="ui-accordion ui-accordion--outlined" data-ui-transition="collapse-fade">
<div class="ui-accordion-item">
<button data-ui-tablist-tab class="ui-accordion-header ui-active">How to create new account?</button>
<div data-ui-tablist-tabpanel>
<div class="ui-accordion-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
<div class="ui-accordion-item">
<button data-ui-tablist-tab class="ui-accordion-header">How to create new account?</button>
<div data-ui-tablist-tabpanel hidden>
<div class="ui-accordion-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
<div class="col-md-12">
@if (session('error'))
<div class="alert alert-danger" id="alert-danger">
{{ session('error') }}
</div>
@endif
</div>
</div>
</div>
<div class="ui-accordion-item">
<button data-ui-tablist-tab class="ui-accordion-header">How to create new account?</button>
<div data-ui-tablist-tabpanel hidden>
<div class="ui-accordion-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
<h3 class="comm-head mt-3 d-flex gap-2" style="font-size: 20px;">
<a href="#">
{{-- <img src="images/arrow-left.png" alt=""> --}}
{{-- <img src="{{ asset('resources/views/Admin/pages/subscriptions/images/arrow-left.png') }}" /> --}}
</a>
</h3>
<div class="new-subs-img">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/cheers-logo.png') }}"
alt="">
</div>
<p class="text-center mt-3 para-mid">Subscribe to Cheers to the Season app to gain access to free cocktails*
at
local
restaurants.
</p>
<p class="text-center mt-3 grey-para">*Free cocktail stipulations vary by state in accordance with local
liquor
laws.</p>
<div class="subscription-card">
<h3 class="head">Subscription</h3>
<div class="main-text">
<div>
<p class="comm-head">Monthly Plan</p>
<p class="grey-para">Billed monthly</p>
</div>
<div>
<p class="price">${{ $productList->product_value }}</p>
</div>
</div>
<hr class="my-5" style="border-top: 2px dashed; color: #042857;">
<div class="input-group mb-5 d-flex align-items-center justify-content-between">
<div class="in-group">
<label class="comm-head" for="">Enter coupon code</label>
</div>
<div class="apply-btn">
<button class="apply" type="button">Apply</button>
</div>
<input type="text" class="form-control coupon-input mt-3" placeholder="Enter coupon code">
</div>
<hr>
{{-- <div class="main-text">
<div>
<p class="comm-head">Applied Discount</p>
<p class="grey-para">First Month free </p>
</div>
<div>
<p class="price">$2.99</p>
</div>
</div>
<hr> --}}
<form id="subscribe" method="POST" action="{{ route('subscribe-to-plan') }}" autocomplete="off">
@csrf
<input type="hidden" name="user_id" value="{{ $userData->id }}" />
<input type="hidden" name="subscription_product_xid" value="{{ $productList->id }}" />
<div class="main-text">
<div>
<p class="comm-head">Total Payment</p>
</div>
<div>
<p class="price">${{ $productList->product_value }}</p>
</div>
</div>
<button type="submit"class="subscribe-button w-75">SUBSCRIBE NOW</button>
</form>
{{-- <button class="subscribe-button w-75" type="button" data-bs-toggle="modal" data-bs-target="#exampleModal">SUBSCRIBE NOW</button> --}}
<p class="grey-para text-center mt-3">You will be charged ${{ $productList->product_value }} every month
after your free trial period ends.
</p>
<p class="grey-para text-center mt-2">Subscription will be renewed monthly until cancelled.</p>
</div>
</div>
</section>
<section class="mt-3 mb-5">
<h3 class="text-center head my-4">Program/Redemption Rules</h3>
<div class="container">
<div data-ui-tablist class="ui-accordion ui-accordion--outlined" data-ui-transition="collapse-fade">
<div class="ui-accordion-item">
<button data-ui-tablist-tab class="ui-accordion-header ui-active">How to create new
account?</button>
<div data-ui-tablist-tabpanel>
<div class="ui-accordion-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
<div class="ui-accordion-item">
<button data-ui-tablist-tab class="ui-accordion-header">How to create new account?</button>
<div data-ui-tablist-tabpanel hidden>
<div class="ui-accordion-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
<div class="ui-accordion-item">
<button data-ui-tablist-tab class="ui-accordion-header">How to create new account?</button>
<div data-ui-tablist-tabpanel hidden>
<div class="ui-accordion-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Modal start -->
<div class="modal fade bottom-mod" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel"></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/x.svg') }}"
alt="">
</button>
</div>
<div class="modal-body mb-4">
<div class="mod-img d-flex align-items-center justify-content-center mb-3">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/glass.png') }}"
alt="">
</div>
<p class="para-mid text-center">You have successfully subscribed. Cheers!</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Modal start -->
<div class="modal fade bottom-mod" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel"></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/x.svg') }}" alt="">
</button>
</div>
<div class="modal-body mb-4">
<div class="mod-img d-flex align-items-center justify-content-center mb-3">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/glass.png') }}" alt="">
</div>
<p class="para-mid text-center">You have successfully subscribed. Cheers!</p>
</div>
</div>
</div>
</div>
<!-- Modal end -->
<!-- Modal end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
<script type="module">
import {
Tablist
} from "https://cdn.jsdelivr.net/npm/jolty@0.6.2/dist/jolty.esm.min.js";
document.addEventListener('DOMContentLoaded', () => {
Tablist.initAll();
});
</script>
<script type="module">
import { Tablist } from "https://cdn.jsdelivr.net/npm/jolty@0.6.2/dist/jolty.esm.min.js";
document.addEventListener('DOMContentLoaded', () => {
Tablist.initAll();
});
</script>
<script>
$(document).ready(function() {
// Hide the alert after 3 seconds (3000 milliseconds)
setTimeout(function() {
$('#alert-success').fadeOut('slow');
}, 3000);
setTimeout(function() {
$('#alert-danger').fadeOut('slow');
}, 3000);
});
</script>
</body>
</html>
</html>

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="{{ asset('resources/views/Admin/pages/subscriptions/subscription-style.css') }}" />
<title>List Of Products</title>
</head>
<body>
<!-- Modal start -->
{{-- <div class="modal fade bottom-mod" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" --}}
{{-- aria-hidden="true"> --}}
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel"></h1>
{{-- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/x.svg') }}"
alt="">
</button> --}}
</div>
<div class="modal-body mb-4">
<div class="mod-img d-flex align-items-center justify-content-center mb-3">
<img src="{{ asset('resources/views/Admin/pages/subscriptions/images/glass.png') }}"
alt="">
</div>
<p class="para-mid text-center">You have successfully subscribed. Cheers!</p>
</div>
</div>
</div>
{{-- </div> --}}
<!-- Modal end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous">
</script>
<script type="module">
import {
Tablist
} from "https://cdn.jsdelivr.net/npm/jolty@0.6.2/dist/jolty.esm.min.js";
document.addEventListener('DOMContentLoaded', () => {
Tablist.initAll();
});
</script>
<script>
$(document).ready(function() {
// Hide the alert after 3 seconds (3000 milliseconds)
setTimeout(function() {
$('#alert-success').fadeOut('slow');
}, 3000);
setTimeout(function() {
$('#alert-danger').fadeOut('slow');
}, 3000);
});
</script>
</body>
</html>

View File

@@ -8,6 +8,7 @@ use App\Http\Controllers\APIs\Customer_API\FeedbackApiController;
use App\Http\Controllers\APIs\Customer_API\NotificationController;
use App\Http\Controllers\APIs\Customer_API\RestaurantControllerApi;
use App\Http\Controllers\APIs\Customer_API\RulesControllerAPI;
use App\Http\Controllers\APIs\Customer_API\SubscriptionController;
use App\Http\Controllers\ReferralCodeController;
use Illuminate\Support\Facades\Route;
@@ -16,6 +17,11 @@ use Illuminate\Support\Facades\Route;
Route::middleware(['customerApiBasicAuth'])->group(function () {
Route::post('/v1/create-subscription-plans', [SubscriptionController::class, 'createStripeProduct']);
Route::post('/v1/check-age', [AuthController::class, 'checkAge']);
Route::get('/v1/list-states', [AuthController::class, 'viewstates']);
Route::post('/v1/register', [AuthController::class, 'register']);
@@ -80,4 +86,6 @@ Route::middleware(['customerApiBasicAuth'])->group(function () {
//*******************************************************Rules ********************************************************
Route::get('/v1/voucher-rules', [RulesControllerAPI::class, 'getVoucherRules']);
});
});

View File

@@ -1,6 +1,7 @@
<?php
use App\Http\Controllers\APIs\Customer_API\SubscriptionController;
use App\Http\Controllers\StripeWebhookController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\ManageProfileController;
use App\Http\Controllers\Admin\ManageCustomerController;
@@ -25,6 +26,17 @@ use App\Http\Controllers\Admin\RestaurantAppController;
use App\Http\Controllers\Admin\ManageLocationController;
use App\Http\Controllers\Admin\ManageRulesController;
//webhook
Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']);
//stripe webhook end
Route::get('/', [LoginController::class, 'index'])->name('login');
Route::post('/check_login', [LoginController::class, 'login_check']);
Route::get('/forgot_password', [LoginController::class, 'forgot_password']);
@@ -36,6 +48,8 @@ Route::post('/password_update', [LoginController::class, 'updatePassword']);
Route::get('/logout', [LoginController::class, 'logout'])->name('logout');
Route::group(['middleware' => ['checkStatus']], function () {
@@ -197,19 +211,24 @@ Route::group(['middleware' => ['checkStatus']], function () {
//subscription ROutes
// Route::group(['middleware' => ['vendor.jwt.verify']], function () {
Route::group(['middleware' => ['customer.jwt.verify']], function () {
Route::get('my-subscription-page', [SubscriptionController::class, 'mySubscription'])->name('my-subscription-page');
// });
});
// Route::middleware(['checkToken'])->group(function () {
Route::get('list-of-plans', [SubscriptionController::class, 'listOfProduct'])->name('next.page.route');
// });
Route::get('list-of-plans', [SubscriptionController::class, 'listOfProduct'])->name('list-of-products');
// });
Route::post('subscribe-to-plan', [SubscriptionController::class, 'subscriptionToPlan'])->name('subscribe-to-plan');
Route::get('thank-you', [SubscriptionController::class, 'thankyou'])->name('thankyou');
// Route::post('subscribe-to-product', [SubscriptionController::class, 'subscribeToProduct'])->name('subscribe-to-product');
// Route::post('cancel-subscription', [SubscriptionController::class, 'cancelSubscription'])->name('cancel-subscription');
// Route::get('thank-you', [SubscriptionController::class, 'thankyou'])->name('thankyou');
// Route::get('cancel-thank-you', [SubscriptionController::class, 'cancelThankYou'])->name('cancel-thank-you');
// Route::post('subscription-upgrade', [SubscriptionController::class, 'subscriptionUpgrade'])->name('subscription-upgrade');