where('is_active', true)->get()->map(function ($q) { if ($q->is_free) { if (auth()->user()->subscribePlans()->first() !== null) { return null; } } return [ 'id' => $q->id, 'name' => $q->name, 'price' => $q->price, 'expired_day' => $q->expired_day, 'is_free' => $q->is_free == 1 ? true : false, 'type' => $q->type, 'transaction' => $q->transaction ]; })->filter(function ($q) { return $q != null; }); return $this->success(array_values($subscribePlans->toArray()), 'Subscribe Plan', 'Subscribe Plan List'); } public function subscribe(Request $request) { $request->validate([ 'subscribe_plan_id' => 'required|exists:subscribe_plans,id', ]); $subscribePlan = SubscribePlan::findOrFail($request->subscribe_plan_id); $user = auth()->user(); $activeSubscription = $user->userSubscribers() ->where('expired_at', '>', now()) ->first(); if ($activeSubscription && !$activeSubscription?->subscribe?->is_free && !$subscribePlan->is_free) { return $this->failed(null, ['title' => 'Subscribe Plan', 'message' => 'You already have an active subscription. Please wait until it expires.']); } if ($subscribePlan->is_free) { $hasUsedFreePlan = $user->userSubscribers() ->whereHas('subscribe', function ($query) { $query->where('is_free', true); })->exists(); if ($hasUsedFreePlan) { return $this->failed(null, ['title' => 'Subscribe Plan', 'message' => 'You have already used the free plan.']); } $expiredAt = now()->addDays($subscribePlan->expired_day + 1); $user->userSubscribers()->create([ 'subscribe_plan_id' => $subscribePlan->id, 'expired_at' => $expiredAt, ]); return $this->success(null, 'Subscribe Plan', 'Free Subscribe Plan Successfully Activated'); } try { $invoice = (new Invoice)->amount($subscribePlan->price); $callback = 'https://ghaafapp.ir'; $payment = Payment::callbackUrl($callback) ->purchase($invoice, function ($driver, $transaction_id) use ($subscribePlan) { PaymentTransaction::create([ 'user_id' => auth()->user()->id, 'subscribe_plan_id' => $subscribePlan->id, 'transaction_id' => $transaction_id, 'amount' => $subscribePlan->price, 'status' => 'pending', ]); }) ->pay(); return $this->success(['url' => $payment]); } catch (\Exception $e) { Log::error('Payment initiation failed: ' . $e->getMessage()); return $this->failed(null, 'درگاه پرداخت در دسترس نیست'); } } public function subscribe_new(Request $request) { $package_name_bazzar = 'com.razzaghi.lawbook.android'; $request->validate([ 'subscribe_plan_id' => 'required|exists:subscribe_plans,id', 'subscription_id' => 'nullable', 'purchase_token' => 'nullable' ]); $subscribePlan = SubscribePlan::findOrFail($request->subscribe_plan_id); $user = auth()->user(); $activeSubscription = $user->userSubscribers() ->where('expired_at', '>', now()) ->latest('expired_at') ->first(); if ($subscribePlan->is_free) { $hasUsedFreePlan = $user->userSubscribers() ->whereHas('subscribe', function ($query) { $query->where('is_free', true); }) ->exists(); if ($hasUsedFreePlan) { return $this->failed(null, ['title' => 'Subscribe Plan', 'message' => 'You have already used the free plan.']); } $expiredAt = $activeSubscription ? $activeSubscription->expired_at->addDays($subscribePlan->expired_day) : now()->addDays($subscribePlan->expired_day); $user->userSubscribers()->create([ 'subscribe_plan_id' => $subscribePlan->id, 'expired_at' => $expiredAt, 'is_free' => true ]); return $this->success(null, 'Subscribe Plan', 'Free Subscribe Plan Successfully Activated'); } $subscription_id = $request->input('subscription_id'); $purchase_token = $request->input('purchase_token'); if (!$subscription_id || !$purchase_token) { return $this->failed(null, ['title' => 'Subscribe Plan', 'message' => 'Invalid subscription details.']); } $url = "https://pardakht.cafebazaar.ir/devapi/v2/api/applications/$package_name_bazzar/subscriptions/$subscription_id/purchases/$purchase_token"; $client = new \GuzzleHttp\Client(); try { $response = $client->get($url, [ 'headers' => [ 'CAFEBAZAAR-PISHKHAN-API-SECRET' => 'eyJhbGciOiJIUzI1NiIsImtpZCI6ImFuY2llbnQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJuYXNoZXItcGlzaGtoYW4tYXBpIiwiaWF0IjoxNzQwMjQ3NTMzLCJleHAiOjQ4OTM4NDc1MzMsImFwaV9hZ2VudF9pZCI6MzQ2NX0.UCrr3IHxCqn77ckxfnaubrsyCfrhPm18gJgyg1qNqwA', ] ]); $data = json_decode($response->getBody(), true); if (!isset($data['validUntilTimestampMsec']) || $data['validUntilTimestampMsec'] < now()->timestamp * 1000) { return $this->failed(null, ['title' => 'Subscribe Plan', 'message' => 'Invalid or expired subscription.']); } $bazaarExpiredAt = Carbon::createFromTimestampMs($data['validUntilTimestampMsec']); $expiredAt = $activeSubscription ? $activeSubscription->expired_at->addDays($subscribePlan->expired_day) : $bazaarExpiredAt; $user->userSubscribers()->whereHas('subscribe', function ($query) { $query->where('is_free', true); }) ->update(['expired_at' => now()]); $user->userSubscribers()->create([ 'subscribe_plan_id' => $subscribePlan->id, 'expired_at' => $expiredAt, 'subscription_id' => $subscription_id, 'purchase_token' => $purchase_token, 'is_free' => false ]); return $this->success(null, 'Subscribe Plan', 'Subscription successfully activated.'); } catch (\Exception $e) { Log::error('Error in subscription', ['Error' => $e->getMessage()]); return $this->failed(null, ['title' => 'Subscribe Plan', 'message' => 'Failed to verify subscription.']); } } public function paymentCallback(Request $request) { try { $url = 'http://bitpay.ir/payment/gateway-result-second'; $api = '066fd-d622e-690a9-be618-ddf02bc6059bbbd67c317bb340d1'; $trans_id = $request->input('trans_id'); $id_get = $request->input('id_get'); $result = $this->get($url, $api, $trans_id, $id_get); $parseDecode = json_decode($result); if ($parseDecode->status == 1) { $transaction = PaymentTransaction::where('transaction_id', $id_get)->firstOrFail(); $transaction->update([ 'status' => 'success', ]); $expiredAt = now()->addDays($transaction->subscribePlan->expired_day); UserSubscriber::where('user_id', $transaction->user_id)->delete(); $transaction->user->userSubscribers()->create([ 'subscribe_plan_id' => $transaction->subscribe_plan_id, 'expired_at' => $expiredAt, ]); return $this->success([], 'Payment Successful', 'Subscription successfully activated.'); } return $this->failed([], ['title' => 'Payment Failed', 'message' => 'Payment verification failed.']); } catch (\Exception $e) { return $this->failed([], ['title' => 'Payment Failed', 'message' => 'Payment verification failed.']); } } public function current() { $user = auth()->user(); $subscribePlans = UserSubscriber::where('user_id', $user->id) ->where('expired_at', '>', now()) ->orderBy('expired_at', 'desc') ->get(); if ($subscribePlans->isNotEmpty()) { $totalExpiredDays = $subscribePlans->sum('expired_day'); $latestPlan = $subscribePlans->first(); $subscribePlanData = [ 'id' => $latestPlan->id, 'name' => $latestPlan->subscribe->name, 'price' => $latestPlan->subscribe->price, 'expired_day' => $totalExpiredDays, 'is_free' => $latestPlan->subscribe->is_free == 1, 'expired_at' => Carbon::now()->addDays($totalExpiredDays)->format('Y-m-d'), ]; return $this->success($subscribePlanData, 'Subscribe Plan', 'Current Subscribe Plan'); } return $this->success(null, 'Subscribe Plan', 'No Subscribe Plan'); } private function send($url, $api, $amount, $redirect, $factorId, $name, $email, $description) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, "api=$api&amount=$amount&redirect=$redirect&factorId=$factorId&name=$name&email=$email&description=$description"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); curl_close($ch); return $res; } private function get($url, $api, $trans_id, $id_get) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, "api=$api&id_get=$id_get&trans_id=$trans_id&json=1"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); curl_close($ch); return $res; } }