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 + + // } +}