Skip to content

Instantly share code, notes, and snippets.

@krisskerr
Created August 17, 2017 20:13
Show Gist options
  • Select an option

  • Save krisskerr/55a332115fe9bc91d3c473f2324cf8dd to your computer and use it in GitHub Desktop.

Select an option

Save krisskerr/55a332115fe9bc91d3c473f2324cf8dd to your computer and use it in GitHub Desktop.
<?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