OnepageController.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. namespace Webkul\Shop\Http\Controllers\API;
  3. use Illuminate\Http\Resources\Json\JsonResource;
  4. use Illuminate\Http\Response;
  5. use Webkul\Checkout\Facades\Cart;
  6. use Webkul\Customer\Repositories\CustomerRepository;
  7. use Webkul\Payment\Facades\Payment;
  8. use Webkul\Sales\Repositories\OrderRepository;
  9. use Webkul\Sales\Transformers\OrderResource;
  10. use Webkul\Shipping\Facades\Shipping;
  11. use Webkul\Shop\Http\Requests\CartAddressRequest;
  12. use Webkul\Shop\Http\Resources\CartResource;
  13. class OnepageController extends APIController
  14. {
  15. /**
  16. * Create a new controller instance.
  17. *
  18. * @return void
  19. */
  20. public function __construct(
  21. protected OrderRepository $orderRepository,
  22. protected CustomerRepository $customerRepository
  23. ) {}
  24. /**
  25. * Return cart summary.
  26. */
  27. public function summary(): JsonResource
  28. {
  29. $cart = Cart::getCart();
  30. return new CartResource($cart);
  31. }
  32. /**
  33. * Store address.
  34. */
  35. public function storeAddress(CartAddressRequest $cartAddressRequest): JsonResource
  36. {
  37. $params = $cartAddressRequest->all();
  38. if (
  39. ! auth()->guard('customer')->check()
  40. && ! Cart::getCart()->hasGuestCheckoutItems()
  41. ) {
  42. return new JsonResource([
  43. 'redirect' => true,
  44. 'data' => route('shop.customer.session.index'),
  45. ]);
  46. }
  47. if (Cart::hasError()) {
  48. return new JsonResource([
  49. 'redirect' => true,
  50. 'redirect_url' => route('shop.checkout.cart.index'),
  51. ]);
  52. }
  53. Cart::saveAddresses($params);
  54. $cart = Cart::getCart();
  55. Cart::collectTotals();
  56. if ($cart->haveStockableItems()) {
  57. if (! $rates = Shipping::collectRates()) {
  58. return new JsonResource([
  59. 'redirect' => true,
  60. 'redirect_url' => route('shop.checkout.cart.index'),
  61. ]);
  62. }
  63. return new JsonResource([
  64. 'redirect' => false,
  65. 'data' => $rates,
  66. ]);
  67. }
  68. return new JsonResource([
  69. 'redirect' => false,
  70. 'data' => Payment::getSupportedPaymentMethods(),
  71. ]);
  72. }
  73. /**
  74. * Store shipping method.
  75. *
  76. * @return \Illuminate\Http\Response
  77. */
  78. public function storeShippingMethod()
  79. {
  80. $validatedData = $this->validate(request(), [
  81. 'shipping_method' => 'required',
  82. ]);
  83. if (
  84. Cart::hasError()
  85. || ! $validatedData['shipping_method']
  86. || ! Cart::saveShippingMethod($validatedData['shipping_method'])
  87. ) {
  88. return response()->json([
  89. 'redirect_url' => route('shop.checkout.cart.index'),
  90. ], Response::HTTP_FORBIDDEN);
  91. }
  92. Cart::collectTotals();
  93. return response()->json(Payment::getSupportedPaymentMethods());
  94. }
  95. /**
  96. * Store payment method.
  97. *
  98. * @return array
  99. */
  100. public function storePaymentMethod()
  101. {
  102. $validatedData = $this->validate(request(), [
  103. 'payment' => 'required',
  104. ]);
  105. if (
  106. Cart::hasError()
  107. || ! $validatedData['payment']
  108. || ! Cart::savePaymentMethod($validatedData['payment'])
  109. ) {
  110. return response()->json([
  111. 'redirect_url' => route('shop.checkout.cart.index'),
  112. ], Response::HTTP_FORBIDDEN);
  113. }
  114. Cart::collectTotals();
  115. $cart = Cart::getCart();
  116. return [
  117. 'cart' => new CartResource($cart),
  118. ];
  119. }
  120. /**
  121. * Store order
  122. */
  123. public function storeOrder()
  124. {
  125. if (Cart::hasError()) {
  126. return new JsonResource([
  127. 'redirect' => true,
  128. 'redirect_url' => route('shop.checkout.cart.index'),
  129. ]);
  130. }
  131. Cart::collectTotals();
  132. try {
  133. $this->validateOrder();
  134. } catch (\Exception $e) {
  135. return response()->json([
  136. 'message' => $e->getMessage(),
  137. ], 500);
  138. }
  139. $cart = Cart::getCart();
  140. if ($redirectUrl = Payment::getRedirectUrl($cart)) {
  141. return new JsonResource([
  142. 'redirect' => true,
  143. 'redirect_url' => $redirectUrl,
  144. ]);
  145. }
  146. $data = (new OrderResource($cart))->jsonSerialize();
  147. $order = $this->orderRepository->create($data);
  148. Cart::deActivateCart();
  149. session()->flash('order_id', $order->id);
  150. return new JsonResource([
  151. 'redirect' => true,
  152. 'redirect_url' => route('shop.checkout.onepage.success'),
  153. ]);
  154. }
  155. /**
  156. * Validate order before creation.
  157. *
  158. * @return void|\Exception
  159. */
  160. public function validateOrder()
  161. {
  162. $cart = Cart::getCart();
  163. $minimumOrderAmount = core()->getConfigData('sales.order_settings.minimum_order.minimum_order_amount') ?: 0;
  164. if (
  165. auth()->guard('customer')->check()
  166. && auth()->guard('customer')->user()->is_suspended
  167. ) {
  168. throw new \Exception(trans('shop::app.checkout.cart.suspended-account-message'));
  169. }
  170. if (
  171. auth()->guard('customer')->user()
  172. && ! auth()->guard('customer')->user()->status
  173. ) {
  174. throw new \Exception(trans('shop::app.checkout.cart.inactive-account-message'));
  175. }
  176. if (! Cart::haveMinimumOrderAmount()) {
  177. throw new \Exception(trans('shop::app.checkout.cart.minimum-order-message', ['amount' => core()->currency($minimumOrderAmount)]));
  178. }
  179. if ($cart->haveStockableItems() && ! $cart->shipping_address) {
  180. throw new \Exception(trans('shop::app.checkout.onepage.address.check-shipping-address'));
  181. }
  182. if (! $cart->billing_address) {
  183. throw new \Exception(trans('shop::app.checkout.onepage.address.check-billing-address'));
  184. }
  185. if (
  186. $cart->haveStockableItems()
  187. && ! $cart->selected_shipping_rate
  188. ) {
  189. throw new \Exception(trans('shop::app.checkout.cart.specify-shipping-method'));
  190. }
  191. if (! $cart->payment) {
  192. throw new \Exception(trans('shop::app.checkout.cart.specify-payment-method'));
  193. }
  194. if ($cart->giftcard_number) {
  195. $this->validateGiftCard($cart);
  196. }
  197. }
  198. /**
  199. * Validate gift card before order creation.
  200. *
  201. * @param \Webkul\Checkout\Models\Cart $cart
  202. * @return void
  203. * @throws \Exception
  204. */
  205. protected function validateGiftCard($cart)
  206. {
  207. $giftCard = \Longyi\Gift\Models\GiftCards::where('giftcard_number', $cart->giftcard_number)->first();
  208. if (!$giftCard) {
  209. throw new \Exception('The gift card does not exist or has been deleted. Please select a new gift card');
  210. }
  211. if (core()->convertPrice($giftCard->remaining_giftcard_amount) < $cart->giftcard_amount) {
  212. throw new \Exception(
  213. sprintf(
  214. 'The gift card balance is insufficient (current balance: %s, required payment: %s). Please reselect a payment method',
  215. core()->formatPrice($giftCard->remaining_giftcard_amount, $cart->cart_currency_code),
  216. core()->formatPrice($cart->giftcard_amount, $cart->cart_currency_code)
  217. )
  218. );
  219. }
  220. if ($giftCard->expirationdate && $giftCard->expirationdate->isPast()) {
  221. throw new \Exception('The gift card has expired. Please choose another payment method');
  222. }
  223. }
  224. }