the browser-facing portion of osu!
at master 3.3 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace App\Http\Controllers\Store; 7 8use App\Libraries\OrderCheckout; 9use App\Libraries\Payments\PaymentCompleted; 10use App\Models\Store\Order; 11use App\Traits\CheckoutErrorSettable; 12use Auth; 13use DB; 14 15class CheckoutController extends Controller 16{ 17 use CheckoutErrorSettable; 18 19 protected $layout = 'master'; 20 21 public function __construct() 22 { 23 $this->middleware('auth'); 24 if (!$this->isAllowRestrictedUsers()) { 25 $this->middleware('check-user-restricted'); 26 } 27 $this->middleware('verify-user'); 28 29 parent::__construct(); 30 } 31 32 public function show($id) 33 { 34 $order = $this->orderForCheckout($id); 35 if ($order === null || $order->isEmpty() || $order->isShouldShopify()) { 36 return ujs_redirect(route('store.cart.show')); 37 } 38 39 // TODO: should be able to notify user that items were changed due to stock/price changes. 40 $order->refreshCost(); 41 $checkout = new OrderCheckout($order); 42 43 // using $errors will conflict with laravel's default magic MessageBag/ViewErrorBag that doesn't act like 44 // an array and will cause issues in shared views. 45 $validationErrors = session('checkout.error.errors') ?? $checkout->validate(); 46 47 return ext_view('store.checkout.show', compact('order', 'checkout', 'validationErrors')); 48 } 49 50 public function store() 51 { 52 $params = get_params(request()->all(), null, [ 53 'hide_from_activity:bool', 54 'orderId:int', 55 'provider', 56 'shopifyCheckoutId', 57 ], ['null_missing' => true]); 58 59 $order = $this->orderForCheckout($params['orderId']); 60 61 if ($order === null || $order->isEmpty()) { 62 return ujs_redirect(route('store.cart.show')); 63 } 64 65 if ($params['hide_from_activity'] !== null) { 66 $order->setGiftsHidden($params['hide_from_activity']); 67 } 68 69 $checkout = new OrderCheckout($order, $params['provider'], $params['shopifyCheckoutId']); 70 71 $validationErrors = $checkout->validate(); 72 if (!empty($validationErrors)) { 73 return $this->setAndRedirectCheckoutError( 74 $order, 75 osu_trans('store.checkout.cart_problems'), 76 $validationErrors 77 ); 78 } 79 80 $checkout->beginCheckout(); 81 82 if ((float) $order->getTotal() === 0.0) { 83 return $this->freeCheckout($checkout); 84 } 85 86 return 'ok'; 87 } 88 89 private function freeCheckout($checkout) 90 { 91 $order = DB::connection('mysql-store')->transaction(function () use ($checkout) { 92 $order = $checkout->getOrder(); 93 $checkout->completeCheckout(); 94 95 (new PaymentCompleted($order, null))->handle(); 96 97 return $order; 98 }); 99 100 return ujs_redirect(route('store.invoice.show', ['invoice' => $order->order_id, 'thanks' => 1])); 101 } 102 103 private function orderForCheckout($id): ?Order 104 { 105 return Auth::user() 106 ->orders() 107 ->whereCanCheckout() 108 ->with('items.product') 109 ->find($id); 110 } 111}