Created
August 17, 2017 20:13
-
-
Save krisskerr/55a332115fe9bc91d3c473f2324cf8dd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Http\Controllers; | |
| use Illuminate\Http\Request; | |
| use App\Http\Requests; | |
| use \Cart; | |
| use \Auth; | |
| use App\Http\Requests\CheckoutDetailsRequest; | |
| class CheckoutController extends Controller | |
| { | |
| public function details() | |
| { | |
| //Prevent access if user has already provided details... | |
| if(Auth::user()->first_name) return redirect('checkout/address'); | |
| $data['title'] = 'Complete Your Details | '.env('BUSINESS_NAME'); | |
| //$data['sidebar'] = 0; | |
| return view('checkout.details', $data); | |
| } | |
| public function postDetails(CheckoutDetailsRequest $request) | |
| { | |
| //Find current user... | |
| $user = \Auth::user(); | |
| $geocode = false; | |
| //$geocode = \Geocode::make()->address(sprintf('%s, %s, %s', $request->line_one, $request->line_two, $request->post_code)); | |
| //Add address... | |
| $address = $user->addresses()->create([ | |
| 'line_one' => $request->input('line_one'), | |
| 'line_two' => $request->input('line_two'), | |
| 'city' => $request->input('city'), | |
| 'county' => $request->input('county'), | |
| 'post_code' => strtoupper($request->input('postcode')), | |
| 'card_registered' => '1' | |
| ]); | |
| if($geocode): | |
| $address->latitude = $geocode->latitude(); | |
| $address->longitude = $geocode->longitude(); | |
| $address->save(); | |
| endif; | |
| if($request->has('email')): | |
| $user->email = $request->input('email'); | |
| endif; | |
| //Basics... | |
| $user->first_name = $request->input('first_name'); | |
| $user->last_name = $request->input('last_name'); | |
| $user->dob = $request->input('dob'); | |
| //Telephone numbers... | |
| $user->landline = $request->input('landline'); | |
| $user->mobile = $request->input('mobile'); | |
| $user->portfolio = $request->input('online_work'); | |
| $user->source = $request->input('source'); | |
| //Need an invoice address ID... | |
| //Company name... | |
| if($request->has('company_name')): | |
| $user->company_name = $request->input('company_name'); | |
| endif; | |
| //Company number... | |
| if($request->has('company_number')): | |
| $user->company_number = $request->input('company_number'); | |
| endif; | |
| //Twitter... | |
| if($request->has('twitter_username')): | |
| $user->twitter_username = $request->input('twitter_username'); | |
| endif; | |
| //Save user details to DB... | |
| $user->save(); | |
| //Redirect user to address selection page with success... | |
| return redirect('checkout/address')->with('success', 'Thanks! Your details have been saved.'); | |
| } | |
| public function address() | |
| { | |
| $data['title'] = 'Address Selection | '.env('BUSINESS_NAME'); | |
| $data['addresses'] = \Auth::user()->addresses; | |
| //dd($data['addresses']); | |
| return view('checkout.address', $data); | |
| } | |
| public function postAddress(Request $request) | |
| { | |
| //Remove any previous selections... | |
| $request->session()->forget('checkout.address'); | |
| //Store selected delivery address into session... | |
| $deliveryAddress = \App\Models\Address::find($request->delivery_addr_id); | |
| $request->session()->put('checkout.address.delivery_addr', $deliveryAddress); | |
| //Do we have a collection address also? | |
| if($request->has('collection_addr_id')): | |
| $collectionAddress = \App\Models\Address::find($request->collection_addr_id); | |
| $request->session()->put('checkout.address.collection_addr', $collectionAddress); | |
| endif; | |
| return redirect('checkout/payment'); | |
| } | |
| public function payment() | |
| { | |
| $data['title'] = 'Payment | '.env('BUSINESS_NAME'); | |
| //Generate Order... | |
| session()->put('checkout.ref', $this->generateOrder()); | |
| return view('checkout.payment', $data); | |
| } | |
| public function postPayment(Request $request) | |
| { | |
| $order = \App\Models\Order::where('ref', session('checkout.ref'))->first(); | |
| //dd($order); | |
| if(totalPayable() > 0): | |
| //Set API key for Stripe... | |
| if(\App::environment('local')): | |
| \Stripe\Stripe::setApiKey(env('STRIPE_TEST_SECRET')); | |
| else: | |
| \Stripe\Stripe::setApiKey(env('STRIPE_LIVE_SECRET')); | |
| endif; | |
| try { | |
| $charge = \Stripe\Charge::create([ | |
| 'amount' => ((totalPayable()) * 100), | |
| 'currency' => 'gbp', | |
| 'source' => $request->stripeToken, | |
| 'description' => sprintf('Lens Rental [%s]', $order->ref), | |
| 'receipt_email' => $request->user()->email | |
| ]); | |
| } catch(\Stripe\Error\Card $e) { | |
| return redirect()->back()->with('issue', 'There was a problem with payment - please get in touch'); | |
| } | |
| $order->transaction_id = $charge->id; | |
| $order->last4 = $charge->source->last4; | |
| //If payment failed or is pending, inform user... | |
| if($charge->status == 'failed' OR $charge->status == 'pending'): | |
| return redirect()->back()->with('issue', 'There was a problem with payment - please get in touch'); | |
| endif; | |
| endif; | |
| //Finalise order... | |
| $this->finaliseOrder($order); | |
| //Redirect user... | |
| return redirect('dashboard')->with('success', 'Thanks! Your order is now placed'); | |
| } | |
| public function getExpressCheckout() | |
| { | |
| //dd(session('checkout')); | |
| $provider = \PayPal::setProvider('express_checkout'); | |
| $data = $this->getCheckoutData(); | |
| $options = [ | |
| 'EMAIL' => Auth::user()->email, | |
| 'SOLUTIONTYPE' => 'Sole', | |
| 'LOGOIMG' => 'https://www.lensboi.com/assets/images/paypal-icon.gif', | |
| ]; | |
| $response = $provider->addOptions($options)->setExpressCheckout($data, false); | |
| try { | |
| $response = $provider->setExpressCheckout($data); | |
| return redirect($response['paypal_link']); | |
| } catch(\Exception $e) { | |
| return redirect()->back()->with('issue', 'There was a problem with payment - please get in touch'); | |
| } | |
| } | |
| public function getExpressCheckoutSuccess(Request $request) | |
| { | |
| $token = $request->get('token'); | |
| $payerID = $request->get('PayerID'); | |
| $data = $this->getCheckoutData(); | |
| $provider = \PayPal::setProvider('express_checkout'); | |
| //Verify Express Checkout token... | |
| $response = $provider->getExpressCheckoutDetails($token); | |
| if(in_array(strtoupper($response['ACK']), ['SUCCESS', 'SUCCESSWITHWARNING'])): | |
| //Perform transaction on PayPal... | |
| $payment = $provider->doExpressCheckoutPayment($data, $token, $payerID); | |
| $status = $payment['PAYMENTINFO_0_PAYMENTSTATUS']; | |
| //Has payment been successful?? | |
| if(!strcasecmp($status, 'Completed') OR ! strcasecmp($status, 'Processed')): | |
| $order = \App\Models\Order::where('ref', session('checkout.ref'))->first(); | |
| $order->transaction_id = $payment['PAYMENTINFO_0_TRANSACTIONID']; | |
| //Finalise order... | |
| $this->finaliseOrder($order); | |
| //Redirect user... | |
| return redirect('dashboard')->with('success', 'Thanks! Your order is now placed'); | |
| endif; | |
| endif; | |
| return redirect()->back()->with('issue', 'There was a problem with payment - please get in touch'); | |
| } | |
| protected function getCheckoutData() | |
| { | |
| //Add items... | |
| $data['items'][] = [ | |
| 'name' => 'LensBoi Rental [#'.session('checkout.ref').']', | |
| 'price' => totalPayable(), | |
| 'qty' => 1 | |
| ]; | |
| $data['total'] = totalPayable(); | |
| $data['invoice_description'] = 'Your Order #'.session('checkout.ref'); | |
| $data['invoice_id'] = session('checkout.ref'); | |
| $data['return_url'] = route('paypal-success'); | |
| $data['cancel_url'] = url('/checkout/payment'); | |
| return $data; | |
| } | |
| protected function generateOrder() | |
| { | |
| $orderRef = strtoupper(str_random(6)); | |
| $user = Auth::user(); | |
| //Save order into DB... | |
| $order = new \App\Models\Order; | |
| $order->ref = $orderRef; | |
| $order->account_id = $user->id; | |
| //Order Dates... | |
| $shipmentDates = calculateDates(session('checkout.arrival'), session('checkout.return')); | |
| //Save calculated shipment dates to DB... | |
| $order->post_on = $shipmentDates['post_on']; | |
| $order->arrival_on = $shipmentDates['arrival_on']; | |
| $order->return_on = $shipmentDates['return_on']; | |
| $order->home_on = $shipmentDates['home_on']; | |
| $order->shipment_id = session('checkout.shipment.id'); | |
| $order->delivery_addr_id = session('checkout.address.delivery_addr.id'); | |
| $order->invoice_addr_id = session('checkout.address.delivery_addr.id'); | |
| if(session()->has('checkout.address.collection_addr')): | |
| $order->collection_addr_id = session('checkout.address.collection_addr.id'); | |
| endif; | |
| $order->total_paid = (totalPayable() > 0) ? number_format((totalPayable()), 2) : 0.00; | |
| //Save order to DB... | |
| $order->save(); | |
| //Save basket items into DB... | |
| $this->generateOrderItems($order); | |
| return $order->ref; | |
| } | |
| protected function generateOrderItems($order) | |
| { | |
| //Store cart products into DB... | |
| foreach(\Cart::contents() as $product): | |
| $orderProduct = new \App\Models\OrderProducts([ | |
| 'product_id' => $product->id, | |
| 'total' => number_format($product->price, 2), | |
| 'quantity' => $product->quantity, | |
| 'row_total' => number_format(($product->price * $product->quantity), 2) | |
| ]); | |
| $order->products()->save($orderProduct); | |
| endforeach; | |
| } | |
| protected function finaliseOrder($order) | |
| { | |
| $user = Auth::user(); | |
| //Handle discount or loyalty if required... | |
| if(session()->get('checkout.discount')): | |
| $this->discount($order); | |
| else: | |
| $this->loyalty($order); | |
| endif; | |
| //Send confirmation email to user... | |
| $user->notify(new \App\Notifications\PaymentSuccess($order)); | |
| //Do we require ID? First-time orders only... | |
| if($user->id_status == 0 AND $user->orders()->count() == 1): | |
| $user->notify(new \App\Notifications\IDUploadRequired); | |
| endif; | |
| $order->paid = 1; | |
| $order->save(); | |
| //Clear basket contents and session variables... | |
| \Cart::destroy(); | |
| session()->forget('checkout'); | |
| } | |
| protected function loyalty($order) | |
| { | |
| //If no discount is present, and user is enroled... | |
| if(!session()->get('checkout.discount') AND Auth::user()->loyalty_enrolled == 1): | |
| //Redeem loyalty... | |
| if($loyalty = session()->get('checkout.loyalty')): | |
| $redeemed = ($loyalty <= totalPayable() ? $loyalty : totalPayable(false)); | |
| $loyaltyRecord = \App\Models\Loyalty::redeem($redeemed, $order->ref); | |
| else: | |
| //Add loyalty points to order... | |
| $loyaltyAmount = percentageCalculator(\Cart::total()); | |
| $loyaltyRecord = \App\Models\Loyalty::add($loyaltyAmount, 5, $order->ref); | |
| endif; | |
| //Add loyalty ID to order... | |
| $order->loyalty_id = $loyaltyRecord->id; | |
| endif; | |
| } | |
| protected function discount($request, $order) | |
| { | |
| $voucher = $request->session()->get('checkout.discount'); | |
| //Discount code present, add to order... | |
| $order->discount_id = $voucher->id; | |
| $order->discount_total = calculateDiscount(); | |
| //Redeem discount voucher... | |
| if($voucher->unredeemable == 0): | |
| $voucher->redeemed = 1; | |
| $voucher->save(); | |
| endif; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment