From 6f6e1ead22a88b222faacfab1df5ec04ce7b3a98 Mon Sep 17 00:00:00 2001 From: Hritikkk9 Date: Wed, 3 Jul 2024 16:44:29 +0530 Subject: [PATCH 1/5] webhhhookk kernalssj --- routes/web.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/routes/web.php b/routes/web.php index b01900c..8594391 100644 --- a/routes/web.php +++ b/routes/web.php @@ -35,10 +35,10 @@ Route::post('/stripe-webhook', [StripeWebhookController::class, 'handleWebhook'] Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']); // Route::post('/stripe-webhooks', [StripeWebhookController::class, 'getWebhook']); -Route::middleware('webhook')->group(function () { - Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']); - Route::post('/stripe-webhooks', [StripeWebhookController::class, 'getWebhook']); -}); +// Route::middleware('webhook')->group(function () { +// Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']); +// Route::post('/stripe-webhooks', [StripeWebhookController::class, 'getWebhook']); +// }); //stripe webhook end From 0ac4cb21184feab3b3cb0398aa23d12d771b7594 Mon Sep 17 00:00:00 2001 From: Hritikkk9 Date: Wed, 3 Jul 2024 17:16:07 +0530 Subject: [PATCH 2/5] webhhhookk ke --- routes/web.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index 8594391..12ec4c9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -32,7 +32,9 @@ use App\Http\Controllers\Admin\ManageRulesController; //webhook Route::post('/stripe-webhook', [StripeWebhookController::class, 'handleWebhook']); -Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']); +Route::post('/stripe/webhook', [StripeWebhookController::class, 'getWebhook']); + + // Route::post('/stripe-webhooks', [StripeWebhookController::class, 'getWebhook']); // Route::middleware('webhook')->group(function () { From 76a6ba8dfa8a9b66d4da4155b09a444589be64e7 Mon Sep 17 00:00:00 2001 From: Hritikkk9 Date: Wed, 3 Jul 2024 17:53:03 +0530 Subject: [PATCH 3/5] customer api updated --- .../APIs/Customer_API/StripeWebhookController.php | 1 + .../APIs/Customer_API/SubscriptionController.php | 2 ++ app/Http/Kernel.php | 2 +- routes/customer_api.php | 7 +++++++ routes/web.php | 8 ++------ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php b/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php index 2e0e385..7f8a5fc 100644 --- a/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php +++ b/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php @@ -17,6 +17,7 @@ class StripeWebhookController extends Controller // public function getWebhook(Request $request){ + // dd("ssssss",$request); Log::info('Stripe Webhook Received= in getWebhook '); Log::info('Stripe Webhook Received: ' . $request->getContent()); } diff --git a/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php b/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php index 1c6442e..542648e 100644 --- a/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php +++ b/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php @@ -96,6 +96,8 @@ class SubscriptionController extends Controller public function createStripeProduct(Request $request) { + + try { DB::beginTransaction(); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 569dc4b..b5c64f6 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -34,7 +34,7 @@ class Kernel extends HttpKernel \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \App\Http\Middleware\VerifyCsrfToken::class, + // \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], diff --git a/routes/customer_api.php b/routes/customer_api.php index 92e4685..07393af 100644 --- a/routes/customer_api.php +++ b/routes/customer_api.php @@ -9,9 +9,16 @@ 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\Admin\ReferralCodeController; +use App\Http\Controllers\APIs\Customer_API\StripeWebhookController; use App\Http\Controllers\APIs\Customer_API\SubscriptionController; use Illuminate\Support\Facades\Route; +// Route::post('/v1/stripe/webhook', [StripeWebhookController::class, 'getWebhook']); + + +Route::post('/v1/stripe-webhook', [StripeWebhookController::class, 'handleWebhook']); +Route::post('/v1/stripe/webhook', [StripeWebhookController::class, 'getWebhook']); + Route::middleware(['customerApiBasicAuth'])->group(function () { diff --git a/routes/web.php b/routes/web.php index 12ec4c9..aace9cb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -31,10 +31,8 @@ use App\Http\Controllers\Admin\ManageRulesController; //webhook -Route::post('/stripe-webhook', [StripeWebhookController::class, 'handleWebhook']); -Route::post('/stripe/webhook', [StripeWebhookController::class, 'getWebhook']); - - +// Route::post('/stripe-webhook', [StripeWebhookController::class, 'handleWebhook']); +// Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']); // Route::post('/stripe-webhooks', [StripeWebhookController::class, 'getWebhook']); // Route::middleware('webhook')->group(function () { @@ -174,8 +172,6 @@ Route::group(['middleware' => ['checkStatus']], function () { //*******************************************************manage reports******************************************************** Route::get('/manage-reports', [ManageReportsController::class, 'index'])->name('manage.reports'); - Route::post('/export-reports', [ManageReportsController::class, 'exportReports'])->name('export.reports'); - //*******************************************************manage feedback******************************************************** Route::get('/manage-feedback', [ManageFeedbackController::class, 'index'])->name('manage.feedback'); Route::post('/delete_feedback/{id}', [ManageFeedbackController::class, 'delete_feedback'])->name('delete.feedback'); From d9a28bfff2711345b470c1238acaa4dbc7fc43a9 Mon Sep 17 00:00:00 2001 From: Hritikkk9 Date: Wed, 3 Jul 2024 17:59:03 +0530 Subject: [PATCH 4/5] webhook logic updated --- .../Customer_API/SubscriptionController.php | 442 +++++------------- 1 file changed, 117 insertions(+), 325 deletions(-) diff --git a/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php b/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php index 542648e..6289dba 100644 --- a/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php +++ b/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php @@ -2,356 +2,148 @@ namespace App\Http\Controllers\APIs\Customer_API; +use App\Helpers\onesignalhelper; 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 Stripe\Event; +use Stripe\Stripe; + + +use Illuminate\Support\Facades\Session; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\DB; - -use Illuminate\Support\Facades\Validator; - -use Illuminate\Support\Facades\Redirect; - -class SubscriptionController extends Controller +class StripeWebhookController extends Controller { + // - - //created by; Hritik - //On - 28th June ,2024 - //use - to get Data of User in Webview and show list of product - - 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(); - - 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')); - } - } - - - - - //created by; Hritik - //On - 28th June ,2024 - //use - to get Data of User in Webview and show list of product - - - public function listOfProduct(Request $request) - { - try { - $productList = SubscriptionProducts::where('is_active', 1)->first(); - - return view('Admin.pages.subscriptions.list-of-products', compact('productList')); - - } 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 - 02th July ,2024 - //use - to Create Subscription Product & price for Monthly - - public function createStripeProduct(Request $request) - { - + + public function getWebhook(Request $request){ + // dd("ssssss",$request); + Log::info(' Received= in getWebhook '); + } + public function handleWebhook(Request $request) + { + Log::info("webhook At line 1"); + + // Verify the webhook signature for security + $secret = config('constants.subscription.webhook_secret'); // Your webhook secret key + + $payload = $request->getContent(); + $sigHeader = $request->header('Stripe-Signature'); + $event = null; + + try { - - DB::beginTransaction(); - - $stripeSecret = (config('constants.subscription.stripe_secret_key')); + $event = Event::constructFrom( + json_decode($payload, true), + $sigHeader, + config('constants.subscription.webhook_secret') + ); - // $stripeSecret = env('STRIPE_SECRET'); - $stripe = new \Stripe\StripeClient($stripeSecret); - // dd($stripeSecret,$stripe,$request->all()); - - $validator = $this->validateSubscriptionsproductForm($request); - - if ($validator->fails()) { - $validationErrors = $validator->errors()->all(); - Log::error("Stripe subscriptions plan validation error: " . implode(", ", $validationErrors)); - return jsonResponseWithErrorMessageApi($validationErrors, 203); - } - - $id = SubscriptionProducts::create([ - 'product_name' => $request->product_name, - 'product_value' => $request->product_value, - 'product_details' => $request->product_details, - ]); - - $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 jsonResponseWithSuccessMessage(__('success.save_data'), 200); - } catch (\Exception $ex) { - DB::rollBack(); - Log::error('Favourite Restaurant service failed: ' . $ex->getMessage()); - return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500); + } 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'); + + $stripeSecret = (config('constants.subscription.stripe_secret_key')); - } + Log::info("webhook called"); + $stripe = new \Stripe\StripeClient($stripeSecret); - public function validateSubscriptionsproductForm(Request $request) - { - return Validator::make( - $request->all(), - [ + if ($event->type === 'checkout.session.completed') { + try { - 'product_name' => 'required', - 'product_value' => 'required', - 'product_details' => 'required', - ] - ); - } + DB::beginTransaction(); + // Handle successful subscription payment + // You can access event data like $event->data->object + // Session::flush(); + $session = $event->data->object; - - //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!"]); - + $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 '); + 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(); + } - - - } 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()]); - + //end } + + + + + + return response('Webhook received', 200); } - - - - public function thankyou(Request $request) - { - - return view('Admin.pages.subscriptions.thank-you'); - } - - //created by; Hritik - //On - 28th May ,2024 - //use - To cancel the subscription of user on end of subscription end period - - public function cancelSubscription(Request $request) - { - try { - Log::info("Razorpay Cancel subscriptions Begin: "); - DB::beginTransaction(); - - $validator = $this->validateCancelSubscriptionForm($request); - - if ($validator->fails()) { - $validationErrors = $validator->errors()->all(); - Log::error("Razorpay Cancel subscriptions validation error: " . implode(", ", $validationErrors)); - return jsonResponseWithErrorMessageApi($validationErrors, 203); - } - - $iamPrincipalId = $request->iam_principal_xid; - $razorpaySubscriptionId = $request->subscription_id; - $subscriptionXid = $request->subscription_xid; - - $getSubscriptionData = RazorpaySubscriptions::where(['id' => $subscriptionXid, 'iam_principal_xid' => $iamPrincipalId, 'subscription_id' => $razorpaySubscriptionId, 'isCancelledSubscription' => 0])->first(); - - - if (!$getSubscriptionData) { - return response()->json(['status' => 502, 'message' => 'Something went wrong while cancelling Subscription']); - } - - $api = new Api(config('constants.razorpay.key_id'), config('constants.razorpay.key_secret')); - - $options = ['cancel_at_cycle_end' => 1]; - // Call the subscription create method with request parameters - $response = $api->subscription->fetch($razorpaySubscriptionId)->cancel($options); - - $endAt = date('Y-m-d H:i:s', $response->end_at); - $dateTime = now(); - $currentDateTime = $dateTime->format('Y-m-d H:i:s'); - $getSubscriptionData->isCancelledSubscription = 1; - $getSubscriptionData->cancelled_at = $currentDateTime; - $getSubscriptionData->save(); - - DB::commit(); - Log::info("Razorpay Cancel subscriptions end: "); - - return response()->json(['status' => 200, 'end_date' => $endAt]); - // return response()->json(['status' => 200, 'message' => 'Your Subscription has been cancelled Sucessfully']); - - - } catch (Exception $e) { - DB::rollBack(); - Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]); - return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500); - } - } - public function validateCancelSubscriptionForm(Request $request) - { - return Validator::make( - $request->all(), - [ - 'iam_principal_xid' => 'required', - 'subscription_id' => 'required', - 'subscription_xid' => 'required', - ] - ); - } - - - // public function subscriptionUpgrade(Request $request) - // { - // // dd($request->all()); - - // $razorPaysubscriptionProductXid = $request->razorpay_plan_id; - // $productTypeId = $request->product_type_xid; - // $productTierId = $request->product_tier_xid; - // $iamId = $request->iam_principal_xid; - - // $user_id = 12; // Change this to dynamic user ID - - // // Retrieve the current monthly subscription - // $currentSubscription = RazorpaySubscriptions::where('iam_principal_xid', $user_id)->first(); - - // if (!$currentSubscription) { - // return response()->json(['status' => 502, 'message' => 'Something went wrong current user Subscription not found']); - // } - - // $products = Products::where('product_type_xid', $productTypeId) - // ->where('product_tier_xid', $productTierId) - // ->where('razorpay_plan_id', $razorPaysubscriptionProductXid) - // ->where('is_active', '1')->first(); - - // if (!$products) { - // return response()->json(['status' => 502, 'message' => 'Something went wrong current product not found']); - // } - - // $api = new Api(config('constants.razorpay.key_id'), config('constants.razorpay.key_secret')); - // $plan_id = $products->razorpay_plan_id; - - // // Call the subscription create method with request parameters - - // } -} +} \ No newline at end of file From 4072c658b6c27484c53f792bcc4d71f6c520e84d Mon Sep 17 00:00:00 2001 From: Hritikkk9 Date: Wed, 3 Jul 2024 18:01:09 +0530 Subject: [PATCH 5/5] webhook logic upd --- .../Customer_API/StripeWebhookController.php | 113 ++++- .../Customer_API/SubscriptionController.php | 436 +++++++++++++----- 2 files changed, 421 insertions(+), 128 deletions(-) diff --git a/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php b/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php index 7f8a5fc..8258df1 100644 --- a/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php +++ b/app/Http/Controllers/APIs/Customer_API/StripeWebhookController.php @@ -2,13 +2,17 @@ namespace App\Http\Controllers\APIs\Customer_API; +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 Stripe\Event; use Stripe\Stripe; +use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\DB; @@ -16,25 +20,32 @@ class StripeWebhookController extends Controller { // + public function getWebhook(Request $request){ // dd("ssssss",$request); Log::info('Stripe Webhook Received= in getWebhook '); Log::info('Stripe Webhook Received: ' . $request->getContent()); } - - public function handleWebhook(Request $request) { - Log::info('Stripe Webhook Received: ' . $request->getContent()); + Log::info("webhook At line 1"); + + // Verify the webhook signature for security + $secret = config('constants.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) + json_decode($payload, true), + $sigHeader, + config('constants.subscription.webhook_secret') ); + + } catch (\UnexpectedValueException $e) { // Invalid payload return response()->json(['error' => 'Invalid payload'], 400); @@ -42,23 +53,97 @@ class StripeWebhookController extends Controller // Signature verification failed return response()->json(['error' => 'Signature verification failed'], 400); } + // $stripeSecret = config('services.stripe.key'); + + $stripeSecret = (config('constants.subscription.stripe_secret_key')); + + + + + Log::info("webhook called"); + $stripe = new \Stripe\StripeClient($stripeSecret); if ($event->type === 'checkout.session.completed') { - $session = $event->data->object; - $metadata = $session->metadata; - Log::info('Meta data ' . json_encode($metadata)); + 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 '); - $stripeSecret = (config('constants.subscription.stripe_secret_key')); - // $stripe = new StripeClient($stripeSecret); - $stripe = new \Stripe\StripeClient($stripeSecret); + $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 '); + 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()->json(['status' => 'Webhook received']); + + + + + + return response('Webhook received', 200); } - - } \ No newline at end of file diff --git a/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php b/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php index 6289dba..542648e 100644 --- a/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php +++ b/app/Http/Controllers/APIs/Customer_API/SubscriptionController.php @@ -2,148 +2,356 @@ namespace App\Http\Controllers\APIs\Customer_API; -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 Stripe\Event; -use Stripe\Stripe; - - -use Illuminate\Support\Facades\Session; +use App\Services\APIs\CustomerAPIs\RulesApiServices; use Illuminate\Support\Facades\Log; +use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; -class StripeWebhookController extends Controller + +use Illuminate\Support\Facades\Validator; + +use Illuminate\Support\Facades\Redirect; + +class SubscriptionController extends Controller { - // - - public function getWebhook(Request $request){ - // dd("ssssss",$request); - Log::info(' Received= in getWebhook '); - - } - public function handleWebhook(Request $request) + + //created by; Hritik + //On - 28th June ,2024 + //use - to get Data of User in Webview and show list of product + + public function mySubscription(Request $request) { - Log::info("webhook At line 1"); - - // Verify the webhook signature for security - $secret = config('constants.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('constants.subscription.webhook_secret') - ); + // 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; - } 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'); + $products = SubscriptionProducts::where('is_active', '1')->get(); - $stripeSecret = (config('constants.subscription.stripe_secret_key')); + if ($isSubscribedUser) { - - - - Log::info("webhook called"); - $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); + return view("Admin.pages.subscriptions.my-subscription", compact('user_id', 'userData', 'isSubscribedUser', 'products')); } - $userId = $metadata->userId; - $userEmail = $metadata->userEmail; - $subscriptionProductId = $metadata->subscriptionProductXid; + $productList = SubscriptionProducts::where('is_active', 1)->first(); - $subscriptionProductData = SubscriptionProducts::where('id', $subscriptionProductId)->first(); + return view('Admin.pages.subscriptions.list-of-products', compact('productList', 'userData')); + } else { + return jsonResponseWithErrorMessageApi(__('auth.user_deleted'), 409); + } - //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 '); + } catch (\Exception $e) { + Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]); + return jsonResponseWithErrorMessage(__('auth.something_went_wrong')); + } + } - $subscriptionObjectFromInvoice = $stripe->subscriptions->retrieve($subscriptionData->subscription, []); - $upcoming_invoice = $stripe->invoices->upcoming([ - 'subscription' => $subscriptionData->subscription, // use retrieved id from subscription + //created by; Hritik + //On - 28th June ,2024 + //use - to get Data of User in Webview and show list of product + + + public function listOfProduct(Request $request) + { + try { + $productList = SubscriptionProducts::where('is_active', 1)->first(); + + return view('Admin.pages.subscriptions.list-of-products', compact('productList')); + + } 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 - 02th July ,2024 + //use - to Create Subscription Product & price for Monthly + + public function createStripeProduct(Request $request) + { + + + try { + + DB::beginTransaction(); + + $stripeSecret = (config('constants.subscription.stripe_secret_key')); + + + // $stripeSecret = env('STRIPE_SECRET'); + $stripe = new \Stripe\StripeClient($stripeSecret); + // dd($stripeSecret,$stripe,$request->all()); + + $validator = $this->validateSubscriptionsproductForm($request); + + if ($validator->fails()) { + $validationErrors = $validator->errors()->all(); + Log::error("Stripe subscriptions plan validation error: " . implode(", ", $validationErrors)); + return jsonResponseWithErrorMessageApi($validationErrors, 203); + } + + $id = SubscriptionProducts::create([ + 'product_name' => $request->product_name, + 'product_value' => $request->product_value, + 'product_details' => $request->product_details, + ]); + + $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', + ]); - $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 '); - 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(); - - + $updateCreatedPlan = SubscriptionProducts::where('id', $id->id)->update([ + 'stripe_price_id' => $productPrice1->id + ]); } - //end + + DB::commit(); + return jsonResponseWithSuccessMessage(__('success.save_data'), 200); + } catch (\Exception $ex) { + DB::rollBack(); + Log::error('Favourite Restaurant service failed: ' . $ex->getMessage()); + return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500); } - - - return response('Webhook received', 200); } -} \ No newline at end of file + + public function validateSubscriptionsproductForm(Request $request) + { + return Validator::make( + $request->all(), + [ + + '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) + { + + return view('Admin.pages.subscriptions.thank-you'); + } + + //created by; Hritik + //On - 28th May ,2024 + //use - To cancel the subscription of user on end of subscription end period + + public function cancelSubscription(Request $request) + { + try { + Log::info("Razorpay Cancel subscriptions Begin: "); + DB::beginTransaction(); + + $validator = $this->validateCancelSubscriptionForm($request); + + if ($validator->fails()) { + $validationErrors = $validator->errors()->all(); + Log::error("Razorpay Cancel subscriptions validation error: " . implode(", ", $validationErrors)); + return jsonResponseWithErrorMessageApi($validationErrors, 203); + } + + $iamPrincipalId = $request->iam_principal_xid; + $razorpaySubscriptionId = $request->subscription_id; + $subscriptionXid = $request->subscription_xid; + + $getSubscriptionData = RazorpaySubscriptions::where(['id' => $subscriptionXid, 'iam_principal_xid' => $iamPrincipalId, 'subscription_id' => $razorpaySubscriptionId, 'isCancelledSubscription' => 0])->first(); + + + if (!$getSubscriptionData) { + return response()->json(['status' => 502, 'message' => 'Something went wrong while cancelling Subscription']); + } + + $api = new Api(config('constants.razorpay.key_id'), config('constants.razorpay.key_secret')); + + $options = ['cancel_at_cycle_end' => 1]; + // Call the subscription create method with request parameters + $response = $api->subscription->fetch($razorpaySubscriptionId)->cancel($options); + + $endAt = date('Y-m-d H:i:s', $response->end_at); + $dateTime = now(); + $currentDateTime = $dateTime->format('Y-m-d H:i:s'); + $getSubscriptionData->isCancelledSubscription = 1; + $getSubscriptionData->cancelled_at = $currentDateTime; + $getSubscriptionData->save(); + + DB::commit(); + Log::info("Razorpay Cancel subscriptions end: "); + + return response()->json(['status' => 200, 'end_date' => $endAt]); + // return response()->json(['status' => 200, 'message' => 'Your Subscription has been cancelled Sucessfully']); + + + } catch (Exception $e) { + DB::rollBack(); + Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage(), ['exception' => $e]); + return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500); + } + } + public function validateCancelSubscriptionForm(Request $request) + { + return Validator::make( + $request->all(), + [ + 'iam_principal_xid' => 'required', + 'subscription_id' => 'required', + 'subscription_xid' => 'required', + ] + ); + } + + + // public function subscriptionUpgrade(Request $request) + // { + // // dd($request->all()); + + // $razorPaysubscriptionProductXid = $request->razorpay_plan_id; + // $productTypeId = $request->product_type_xid; + // $productTierId = $request->product_tier_xid; + // $iamId = $request->iam_principal_xid; + + // $user_id = 12; // Change this to dynamic user ID + + // // Retrieve the current monthly subscription + // $currentSubscription = RazorpaySubscriptions::where('iam_principal_xid', $user_id)->first(); + + // if (!$currentSubscription) { + // return response()->json(['status' => 502, 'message' => 'Something went wrong current user Subscription not found']); + // } + + // $products = Products::where('product_type_xid', $productTypeId) + // ->where('product_tier_xid', $productTierId) + // ->where('razorpay_plan_id', $razorPaysubscriptionProductXid) + // ->where('is_active', '1')->first(); + + // if (!$products) { + // return response()->json(['status' => 502, 'message' => 'Something went wrong current product not found']); + // } + + // $api = new Api(config('constants.razorpay.key_id'), config('constants.razorpay.key_secret')); + // $plan_id = $products->razorpay_plan_id; + + // // Call the subscription create method with request parameters + + // } +}