@extends("front/layout.master") @section('title', __('staticwords.Checkout') . ' | ') @section('body') @php \Session::forget('from-order-review-page'); \Session::forget('from-pay-page'); \Session::forget('re-verify'); \Session::forget('indiantax'); $count = $cart_table->count(); $cartSubtotal = 0; foreach ($cart_table as $row) { $cartSubtotal += ($row->semi_total ?? $row->price_total ?? 0); } $shipping = $shippingcharge ?? 0; // $handling_charge arrives as either a numeric scalar (from getBillingView) or a HandlingCharge // Collection (from orderReview). Normalize so the `@if($handling > 0)` check below never tries // to coerce a Collection to int. $handling_raw = $handling_charge ?? 0; if (is_numeric($handling_raw)) { $handling = (float) $handling_raw; } elseif ($handling_raw instanceof \Illuminate\Support\Collection) { $handling = (float) ($genrals_settings->handlingcharge ?? \App\Genral::first()->handlingcharge ?? 0); } else { $handling = 0; } // Prefer the applied cart coupon (passed from the controller); fall back to the free-shipping coupon. $couponDisc = (isset($couponDiscount) && $couponDiscount > 0) ? (float) $couponDiscount : (($shipping_coupan_status ?? 0) ? ($shipping_coupan_per_price ?? 0) : 0); $grandTotal = $ctotal ?? ($cartSubtotal + $shipping + $handling - $couponDisc); $defaultAddress = collect($addresses)->firstWhere('defaddress', 1) ?? collect($addresses)->first(); $selectedAddrId = session()->get('address') ?? ($defaultAddress->id ?? null); // ------------------------------------------------------------------------- // Gateway dispatch variables — ported from the working OLD checkout view at // C:\xampp\htdocs\e-mart\resources\views\front\checkout.blade.php so each // payment method below can hand off to its own controller exactly as before. // ------------------------------------------------------------------------- $config = \App\Config::first(); $Api_settings = $config; // many old templates referenced both names $Api_settings = isset($Api_settings) ? $Api_settings : $config; $genrals = \App\Genral::first(); $front_logo = $genrals->logo ?? ''; $title = $genrals->name ?? config('app.name', 'Emart'); // The gateway controllers verify `$request->actualtotal` against `getcarttotal() * conversion_rate` // — i.e. the CART SUBTOTAL only, NOT the grand total. Shipping/handling are added later inside // `Crypt::decrypt($secure_amount)` for the gateway popup. Mismatching them gives a misleading // "Payment has been modifed !" rejection from PayViaRazorPayController et al. $rawCartTotal = function_exists('getcarttotal') ? (float) getcarttotal() : 0; $cartLocalTotal = sprintf("%.2f", $rawCartTotal * $conversion_rate); $un_sec = $cartLocalTotal; // sent as `actualtotal` for verification // payamount = full grand total in the SELECTED currency. PlaceOrderController::placeorder() // does $neworder->order_total = Session::get('payamount') - $hc — so this must already be in // user currency (not base currency). $grandTotal from the controller is in base; multiply. $payAmountLocal = sprintf("%.2f", ((float) $grandTotal) * $conversion_rate); $unsecAmount = $payAmountLocal; // shown to user / used as popup amount $secure_amount = \Crypt::encrypt($unsecAmount); // encrypted grand total displayed in popup // PlaceOrderController::placeorder() requires: // $hc = decrypt(Session::get('handlingcharge')); // must be a Crypt::encrypt'd value // Session::get('payamount') // must be a numeric string in user currency // The OLD view set both inline as it rendered. The new view never did, so placeorder() blew up // with "The payload is invalid." (decrypt of null) on every Razorpay/Stripe/etc. callback. $handlingChargeLocal = (float) $handling * $conversion_rate; \Session::put('payamount', $payAmountLocal); \Session::put('handlingcharge', \Crypt::encrypt($handlingChargeLocal)); // Snapshot what we're rendering so it can be compared against the controller's expectation // when "Payment has been modifed !" fires. Only log when actually viewing the page (auth user). if (auth()->check()) { \Illuminate\Support\Facades\Log::info('[checkout/view] amount snapshot', [ 'user_id' => auth()->id(), 'route' => request()->path(), 'getcarttotal' => $rawCartTotal, 'conversion_rate' => $conversion_rate, 'cart_local_total'=> $cartLocalTotal, 'un_sec' => $un_sec, 'grand_total' => $grandTotal, 'unsec_amount' => $unsecAmount, 'shipping' => $shipping, 'handling' => $handling, 'currency' => session()->get('currency')['id'] ?? null, ]); } // Pre-generate an order id so Razorpay/Stripe/PayPal callbacks can call // PlaceOrderController::placeorder(... session('order_id') ...). if (!session()->get('order_id')) { session()->put('order_id', uniqid('ord_')); } $current_order_id = session()->get('order_id'); // selectedaddress is only injected by orderReview(); on the initial /checkout render // (getBillingView) it's not in scope, so use isset() to avoid "Undefined variable". $address_for_pay = (isset($selectedaddress) ? $selectedaddress : null) ?? $defaultAddress ?? null; $wallet_balance = auth()->check() && auth()->user()->wallet ? (float) auth()->user()->wallet->balance : 0; // Legacy variables that gateway module includes (Modules\AuthorizeNet, Modules\Bkash, …) and // some inline gateway markup expect to be in scope. Defining them here so every @include of a // module's front.tab / front.list partial works exactly like in the old checkout view. $checkoutsetting_check = \App\AutoDetectGeo::first(); $listcheckOutCurrency = \App\CurrencyCheckout::where('currency', '=', session()->get('currency')['id'] ?? '')->first(); $handlingcharge = (float) ($genrals->handlingcharge ?? 0); // Some module partials reference $address (singular). Provide an alias so they don't break. $address = $address_for_pay; // Currency-aware gateway whitelist — mirrors the old view's // strstr($listcheckOutCurrency->payment_method, 'gateway') check. // - checkout-currency restriction OFF (or AutoDetectGeo missing) → allow every gateway // - no CurrencyCheckout row for the current currency → allow every gateway (admin hasn't // configured a per-currency whitelist yet, don't silently hide everything) // - row exists but `payment_method` is empty → allow every gateway (treat as unrestricted) // - row exists with a list → only methods named in that list are allowed (case-insensitive) $gwAllowedFor = function ($needle) use ($listcheckOutCurrency, $checkoutsetting_check) { if (!$checkoutsetting_check || $checkoutsetting_check->checkout_currency != 1) { return true; } if (!$listcheckOutCurrency || empty($listcheckOutCurrency->payment_method)) { return true; } return stripos((string) $listcheckOutCurrency->payment_method, $needle) !== false; }; @endphp
{{ Auth::user()->name }}
{{ Auth::user()->email }}
{{ __('No saved addresses. Add one to continue.') }}