|
Server : Apache/2.4.41 (Ubuntu) System : Linux vmi1525618.contaboserver.net 5.4.0-105-generic #119-Ubuntu SMP Mon Mar 7 18:49:24 UTC 2022 x86_64 User : www-data ( 33) PHP Version : 8.2.12 Disable Function : NONE Directory : /var/www/lecturebazaar.com/app/Http/Controllers/Web/ |
Upload File : |
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Mixins\Cashback\CashbackAccounting;
use App\Models\Accounting;
use App\Models\BecomeInstructor;
use App\Models\Cart;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\PaymentChannel;
use App\Models\Product;
use App\Models\ProductOrder;
use App\Models\ReserveMeeting;
use App\Models\Reward;
use App\Models\RewardAccounting;
use App\Models\Sale;
use App\Models\TicketUser;
use App\PaymentChannels\ChannelManager;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
class PaymentController extends Controller
{
protected $order_session_key = 'payment.order_id';
public function paymentRequest(Request $request)
{
$this->validate($request, [
'gateway' => 'required'
]);
$user = auth()->user();
$gateway = $request->input('gateway');
$orderId = $request->input('order_id');
$order = Order::where('id', $orderId)
->where('user_id', $user->id)
->first();
if ($order->type === Order::$meeting) {
$orderItem = OrderItem::where('order_id', $order->id)->first();
$reserveMeeting = ReserveMeeting::where('id', $orderItem->reserve_meeting_id)->first();
$reserveMeeting->update(['locked_at' => time()]);
}
if ($gateway === 'credit') {
if ($user->getAccountingCharge() < $order->total_amount) {
$order->update(['status' => Order::$fail]);
session()->put($this->order_session_key, $order->id);
return redirect('/payments/status');
}
$order->update([
'payment_method' => Order::$credit
]);
$this->setPaymentAccounting($order, 'credit');
$order->update([
'status' => Order::$paid
]);
session()->put($this->order_session_key, $order->id);
return redirect('/payments/status');
}
$paymentChannel = PaymentChannel::where('id', $gateway)
->where('status', 'active')
->first();
if (!$paymentChannel) {
$toastData = [
'title' => trans('cart.fail_purchase'),
'msg' => trans('public.channel_payment_disabled'),
'status' => 'error'
];
return back()->with(['toast' => $toastData]);
}
$order->payment_method = Order::$paymentChannel;
$order->save();
try {
$channelManager = ChannelManager::makeChannel($paymentChannel);
$redirect_url = $channelManager->paymentRequest($order);
// dd($redirect_url);
// dd($order);
if (in_array($paymentChannel->class_name, PaymentChannel::$gatewayIgnoreRedirect)) {
return $redirect_url;
}
return Redirect::away($redirect_url);
} catch (\Exception $exception) {
$toastData = [
'title' => trans('cart.fail_purchase'),
'msg' => trans('cart.gateway_error'),
'status' => 'error'
];
return back()->with(['toast' => $toastData]);
}
}
public function paymentVerify(Request $request, $gateway)
{
$paymentChannel = PaymentChannel::where('class_name', $gateway)
->where('status', 'active')
->first();
// dd($paymentChannel);
try {
$channelManager = ChannelManager::makeChannel($paymentChannel);
$order = $channelManager->verify($request);
return $this->paymentOrderAfterVerify($order);
} catch (\Exception $exception) {
$toastData = [
'title' => trans('cart.fail_purchase'),
'msg' => trans('cart.gateway_error'),
'status' => 'error'
];
return redirect('cart')->with(['toast' => $toastData]);
}
}
/*
* | this methode only run for payku.result
* */
public function paykuPaymentVerify(Request $request, $id)
{
$paymentChannel = PaymentChannel::where('class_name', PaymentChannel::$payku)
->where('status', 'active')
->first();
try {
$channelManager = ChannelManager::makeChannel($paymentChannel);
$request->request->add(['transaction_id' => $id]);
$order = $channelManager->verify($request);
return $this->paymentOrderAfterVerify($order);
} catch (\Exception $exception) {
$toastData = [
'title' => trans('cart.fail_purchase'),
'msg' => trans('cart.gateway_error'),
'status' => 'error'
];
return redirect('cart')->with(['toast' => $toastData]);
}
}
private function paymentOrderAfterVerify($order)
{
if (!empty($order)) {
if ($order->status == Order::$paying) {
$this->setPaymentAccounting($order);
$order->update(['status' => Order::$paid]);
} else {
if ($order->type === Order::$meeting) {
$orderItem = OrderItem::where('order_id', $order->id)->first();
if ($orderItem && $orderItem->reserve_meeting_id) {
$reserveMeeting = ReserveMeeting::where('id', $orderItem->reserve_meeting_id)->first();
if ($reserveMeeting) {
$reserveMeeting->update(['locked_at' => null]);
}
}
}
}
session()->put($this->order_session_key, $order->id);
return redirect('/payments/status');
} else {
$toastData = [
'title' => trans('cart.fail_purchase'),
'msg' => trans('cart.gateway_error'),
'status' => 'error'
];
return redirect('cart')->with($toastData);
}
}
public function setPaymentAccounting($order, $type = null)
{
$cashbackAccounting = new CashbackAccounting();
if ($order->is_charge_account) {
Accounting::charge($order);
$cashbackAccounting->rechargeWallet($order);
} else {
foreach ($order->orderItems as $orderItem) {
$sale = Sale::createSales($orderItem, $order->payment_method);
if (!empty($orderItem->reserve_meeting_id)) {
$reserveMeeting = ReserveMeeting::where('id', $orderItem->reserve_meeting_id)->first();
$reserveMeeting->update([
'sale_id' => $sale->id,
'reserved_at' => time()
]);
$reserver = $reserveMeeting->user;
if ($reserver) {
$this->handleMeetingReserveReward($reserver);
}
}
if (!empty($orderItem->gift_id)) {
$gift = $orderItem->gift;
$gift->update([
'status' => 'active'
]);
$gift->sendNotificationsWhenActivated($orderItem->total_amount);
}
if (!empty($orderItem->subscribe_id)) {
Accounting::createAccountingForSubscribe($orderItem, $type);
} elseif (!empty($orderItem->promotion_id)) {
Accounting::createAccountingForPromotion($orderItem, $type);
} elseif (!empty($orderItem->registration_package_id)) {
Accounting::createAccountingForRegistrationPackage($orderItem, $type);
if (!empty($orderItem->become_instructor_id)) {
BecomeInstructor::where('id', $orderItem->become_instructor_id)
->update([
'package_id' => $orderItem->registration_package_id
]);
}
} elseif (!empty($orderItem->installment_payment_id)) {
Accounting::createAccountingForInstallmentPayment($orderItem, $type);
$this->updateInstallmentOrder($orderItem, $sale);
} else {
// webinar and meeting and product and bundle
Accounting::createAccounting($orderItem, $type);
TicketUser::useTicket($orderItem);
if (!empty($orderItem->product_id)) {
$this->updateProductOrder($sale, $orderItem);
}
}
}
// Set Cashback Accounting For All Order Items
$cashbackAccounting->setAccountingForOrderItems($order->orderItems);
}
Cart::emptyCart($order->user_id);
}
public function payStatus(Request $request)
{
$orderId = $request->get('order_id', null);
if (!empty(session()->get($this->order_session_key, null))) {
$orderId = session()->get($this->order_session_key, null);
session()->forget($this->order_session_key);
}
$order = Order::where('id', $orderId)
->where('user_id', auth()->id())
->first();
if (!empty($order)) {
$data = [
'pageTitle' => trans('public.cart_page_title'),
'order' => $order,
];
return view('web.default.cart.status_pay', $data);
}
return redirect('/panel');
}
private function handleMeetingReserveReward($user)
{
if ($user->isUser()) {
$type = Reward::STUDENT_MEETING_RESERVE;
} else {
$type = Reward::INSTRUCTOR_MEETING_RESERVE;
}
$meetingReserveReward = RewardAccounting::calculateScore($type);
RewardAccounting::makeRewardAccounting($user->id, $meetingReserveReward, $type);
}
private function updateProductOrder($sale, $orderItem)
{
$product = $orderItem->product;
$status = ProductOrder::$waitingDelivery;
if ($product and $product->isVirtual()) {
$status = ProductOrder::$success;
}
ProductOrder::where('product_id', $orderItem->product_id)
->where(function ($query) use ($orderItem) {
$query->where(function ($query) use ($orderItem) {
$query->whereNotNull('buyer_id');
$query->where('buyer_id', $orderItem->user_id);
});
$query->orWhere(function ($query) use ($orderItem) {
$query->whereNotNull('gift_id');
$query->where('gift_id', $orderItem->gift_id);
});
})
->update([
'sale_id' => $sale->id,
'status' => $status,
]);
if ($product and $product->getAvailability() < 1) {
$notifyOptions = [
'[p.title]' => $product->title,
];
sendNotification('product_out_of_stock', $notifyOptions, $product->creator_id);
}
}
private function updateInstallmentOrder($orderItem, $sale)
{
$installmentPayment = $orderItem->installmentPayment;
if (!empty($installmentPayment)) {
$installmentOrder = $installmentPayment->installmentOrder;
$installmentPayment->update([
'sale_id' => $sale->id,
'status' => 'paid',
]);
/* Notification Options */
$notifyOptions = [
'[u.name]' => $installmentOrder->user->full_name,
'[installment_title]' => $installmentOrder->installment->main_title,
'[time.date]' => dateTimeFormat(time(), 'j M Y - H:i'),
'[amount]' => handlePrice($installmentPayment->amount),
];
if ($installmentOrder and $installmentOrder->status == 'paying' and $installmentPayment->type == 'upfront') {
$installment = $installmentOrder->installment;
if ($installment) {
if ($installment->needToVerify()) {
$status = 'pending_verification';
sendNotification("installment_verification_request_sent", $notifyOptions, $installmentOrder->user_id);
sendNotification("admin_installment_verification_request_sent", $notifyOptions, 1); // Admin
} else {
$status = 'open';
sendNotification("paid_installment_upfront", $notifyOptions, $installmentOrder->user_id);
}
$installmentOrder->update([
'status' => $status
]);
if ($status == 'open' and !empty($installmentOrder->product_id) and !empty($installmentOrder->product_order_id)) {
$productOrder = ProductOrder::query()->where('installment_order_id', $installmentOrder->id)
->where('id', $installmentOrder->product_order_id)
->first();
$product = Product::query()->where('id', $installmentOrder->product_id)->first();
if (!empty($product) and !empty($productOrder)) {
$productOrderStatus = ProductOrder::$waitingDelivery;
if ($product->isVirtual()) {
$productOrderStatus = ProductOrder::$success;
}
$productOrder->update([
'status' => $productOrderStatus
]);
}
}
}
}
if ($installmentPayment->type == 'step') {
sendNotification("paid_installment_step", $notifyOptions, $installmentOrder->user_id);
sendNotification("paid_installment_step_for_admin", $notifyOptions, 1); // For Admin
}
}
}
}