cart->current(); $lines = $cart ? $this->cart->activeLines($cart) : collect(); $shippingAddress = $cart?->shippingAddress; $billingAddress = $cart?->billingAddress; // Rate quoting needs a shipping address to resolve against (postcode/ // country for ACS/BoxNow live rates, table-rate-shipping's zones) — // nothing to offer yet on a cart with no address saved. $shippingOptions = $shippingAddress ? $this->checkout->getShippingOptions() : collect(); return view('checkout::page', [ 'cart' => $cart, 'lines' => $lines, 'billingAddress' => $billingAddress, 'shippingAddress' => $shippingAddress, 'shippingOptions' => $shippingOptions, 'countries' => Country::orderBy('name')->get(['id', 'name']), ]); } /** * One form, two CheckoutService calls — billing and shipping are always * both set together here. When "same as billing" is checked the shipping * fields are disabled client-side (so the browser never submits them) and * the billing values are reused for shipping too, plus delivery * instructions. */ public function saveAddress(string $locale, Request $request): RedirectResponse { $sameAsBilling = $request->boolean('same_as_billing'); $rules = [ 'contact_email' => ['required', 'email'], 'billing_first_name' => ['required', 'string', 'max:255'], 'billing_last_name' => ['required', 'string', 'max:255'], 'billing_company_name' => ['nullable', 'string', 'max:255'], 'billing_tax_identifier' => ['nullable', 'string', 'max:255'], 'billing_line_one' => ['required', 'string', 'max:255'], 'billing_line_two' => ['nullable', 'string', 'max:255'], 'billing_city' => ['required', 'string', 'max:255'], 'billing_state' => ['nullable', 'string', 'max:255'], 'billing_postcode' => ['required', 'string', 'max:20'], 'billing_country_id' => ['required', 'integer', 'exists:'.(new Country)->getTable().',id'], 'billing_contact_phone' => ['nullable', 'string', 'max:50'], 'shipping_delivery_instructions' => ['nullable', 'string', 'max:1000'], ]; if (! $sameAsBilling) { $rules += [ 'shipping_first_name' => ['required', 'string', 'max:255'], 'shipping_last_name' => ['required', 'string', 'max:255'], 'shipping_company_name' => ['nullable', 'string', 'max:255'], 'shipping_line_one' => ['required', 'string', 'max:255'], 'shipping_line_two' => ['nullable', 'string', 'max:255'], 'shipping_city' => ['required', 'string', 'max:255'], 'shipping_state' => ['nullable', 'string', 'max:255'], 'shipping_postcode' => ['required', 'string', 'max:20'], 'shipping_country_id' => ['required', 'integer', 'exists:'.(new Country)->getTable().',id'], 'shipping_contact_phone' => ['nullable', 'string', 'max:50'], ]; } $data = $request->validate($rules); $billing = [ 'first_name' => $data['billing_first_name'], 'last_name' => $data['billing_last_name'], 'company_name' => $data['billing_company_name'] ?? null, 'tax_identifier' => $data['billing_tax_identifier'] ?? null, 'line_one' => $data['billing_line_one'], 'line_two' => $data['billing_line_two'] ?? null, 'city' => $data['billing_city'], 'state' => $data['billing_state'] ?? null, 'postcode' => $data['billing_postcode'], 'country_id' => $data['billing_country_id'], 'contact_email' => $data['contact_email'], 'contact_phone' => $data['billing_contact_phone'] ?? null, ]; $shipping = $sameAsBilling ? [...$billing, 'delivery_instructions' => $data['shipping_delivery_instructions'] ?? null] : [ 'first_name' => $data['shipping_first_name'], 'last_name' => $data['shipping_last_name'], 'company_name' => $data['shipping_company_name'] ?? null, 'line_one' => $data['shipping_line_one'], 'line_two' => $data['shipping_line_two'] ?? null, 'city' => $data['shipping_city'], 'state' => $data['shipping_state'] ?? null, 'postcode' => $data['shipping_postcode'], 'country_id' => $data['shipping_country_id'], 'contact_email' => $data['contact_email'], 'contact_phone' => $data['shipping_contact_phone'] ?? null, 'delivery_instructions' => $data['shipping_delivery_instructions'] ?? null, ]; $this->checkout->setBillingAddress($billing); $this->checkout->setShippingAddress($shipping); return redirect()->route('checkout.show', $locale); } public function selectShippingOption(string $locale, Request $request): RedirectResponse { $data = $request->validate([ 'shipping_option' => ['required', 'string'], ]); try { $this->checkout->selectShippingOption($data['shipping_option']); } catch (InvalidShippingOptionException) { return back()->withErrors([ 'shipping_option' => __('checkout.page.shipping_option_invalid'), ]); } return redirect()->route('checkout.show', $locale); } }