diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/index.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/index.jsx
index 073141b2ec..8b648f5963 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/index.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/index.jsx
@@ -57,7 +57,7 @@ import {nanoid} from 'nanoid'
const CheckoutOneClick = () => {
const {formatMessage} = useIntl()
const navigate = useNavigation()
- const {step, STEPS} = useCheckout()
+ const {step, STEPS, contactPhone} = useCheckout()
const showToast = useToast()
const [isLoading, setIsLoading] = useState(false)
const [enableUserRegistration, setEnableUserRegistration] = useState(false)
@@ -147,7 +147,8 @@ const CheckoutOneClick = () => {
// Form for billing address
const billingAddressForm = useForm({
- mode: 'onChange',
+ mode: 'onTouched',
+ reValidateMode: 'onChange',
shouldUnregister: false,
defaultValues: {...selectedBillingAddress}
})
@@ -200,17 +201,66 @@ const CheckoutOneClick = () => {
let billingAddress
if (billingSameAsShipping && selectedShippingAddress) {
billingAddress = selectedShippingAddress
+ // Validate that shipping address has required address fields
+ if (!billingAddress?.address1) {
+ showError(
+ formatMessage({
+ id: 'checkout.error.billing_address_required',
+ defaultMessage: 'Please enter a billing address.'
+ })
+ )
+ return
+ }
} else {
- const isFormValid = await billingAddressForm.trigger()
+ // Validate all required address fields (excluding phone for billing)
+ const fieldsToValidate = [
+ 'address1',
+ 'firstName',
+ 'lastName',
+ 'city',
+ 'stateCode',
+ 'postalCode',
+ 'countryCode'
+ ]
+
+ // First, mark all fields as touched so errors will be displayed when validation runs
+ // This must happen BEFORE trigger() so errors show immediately
+ fieldsToValidate.forEach((field) => {
+ const currentValue = billingAddressForm.getValues(field) || ''
+ billingAddressForm.setValue(field, currentValue, {
+ shouldValidate: false,
+ shouldTouch: true
+ })
+ })
+
+ // Now trigger validation - errors will show because fields are already touched
+ const isFormValid = await billingAddressForm.trigger(fieldsToValidate)
if (!isFormValid) {
+ // Payment section should already be open from onPlaceOrder
+ // Focus on the first name field (first field in the form)
+ setTimeout(() => {
+ billingAddressForm.setFocus('firstName')
+ }, 100)
return
}
billingAddress = billingAddressForm.getValues()
+
+ // Double-check that address is present
+ if (!billingAddress?.address1) {
+ showError(
+ formatMessage({
+ id: 'checkout.error.billing_address_required',
+ defaultMessage: 'Please enter a billing address.'
+ })
+ )
+ setIsEditingPayment(true)
+ return
+ }
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- const {addressId, creationDate, lastModified, preferred, ...address} = billingAddress
+ const {addressId, creationDate, lastModified, preferred, phone, ...address} = billingAddress
const latestBasketId = currentBasketQuery.data?.basketId || basket.basketId
return await updateBillingAddressForBasket({
body: address,
@@ -370,15 +420,21 @@ const CheckoutOneClick = () => {
}
})
}
+ }
- // Also persist billing phone as phoneHome
- const phoneHome = order?.billingAddress?.phone
- if (phoneHome) {
- await updateCustomer.mutateAsync({
- parameters: {customerId},
- body: {phoneHome}
- })
- }
+ // Persist phone number as phoneHome from contact info, shipping address, or basket
+ // Priority: contactPhone (from contact info form) > shipping address phone > basket customerInfo phone
+ const phoneHome =
+ contactPhone && contactPhone.length > 0
+ ? contactPhone
+ : deliveryShipments.length > 0
+ ? deliveryShipments[0]?.shippingAddress?.phone
+ : basket?.customerInfo?.phone
+ if (phoneHome) {
+ await updateCustomer.mutateAsync({
+ parameters: {customerId},
+ body: {phoneHome}
+ })
}
} catch (_e) {
// Only surface error if shopper opted to register/save details; otherwise fail silently
@@ -442,6 +498,13 @@ const CheckoutOneClick = () => {
}
}
+ // Ensure payment section is open before validating billing address
+ // This ensures the billing form is rendered and visible when we validate
+ setIsEditingPayment(true)
+
+ // Wait for the payment section to open and billing form to render
+ await new Promise((resolve) => setTimeout(resolve, 0))
+
// If successful `onBillingSubmit` returns the updated basket. If the form was invalid on
// submit, `undefined` is returned.
const updatedBasket = await onBillingSubmit()
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/index.test.js b/packages/template-retail-react-app/app/pages/checkout-one-click/index.test.js
index 92e5f74ff4..83105cb410 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/index.test.js
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/index.test.js
@@ -1268,6 +1268,304 @@ describe('Checkout One Click', () => {
expect(screen.queryByText(/success/i)).not.toBeInTheDocument()
})
+ test('billing address validation shows errors on first click for delivery orders', async () => {
+ // Create a delivery basket with shipping address but no billing address
+ const deliveryBasket = JSON.parse(JSON.stringify(scapiBasketWithItem))
+ deliveryBasket.paymentInstruments = []
+ deliveryBasket.billingAddress = null // No billing address set
+
+ // Override baskets endpoint
+ global.server.use(
+ rest.get('*/baskets', (req, res, ctx) => {
+ return res(
+ ctx.json({
+ baskets: [deliveryBasket],
+ total: 1
+ })
+ )
+ })
+ )
+
+ window.history.pushState({}, 'Checkout', createPathWithDefaults('/checkout'))
+ const {user} = renderWithProviders(, {
+ wrapperProps: {
+ isGuest: true,
+ siteAlias: 'uk',
+ appConfig: mockConfig.app
+ }
+ })
+
+ // Navigate to payment step
+ try {
+ await screen.findByText(/contact info/i)
+ const emailInput = await screen.findByLabelText(/email/i)
+ await user.type(emailInput, 'delivery@test.com')
+ await user.tab()
+ const contToShip = await screen.findByText(/continue to shipping address/i)
+ await user.click(contToShip)
+ } catch (_e) {
+ return
+ }
+
+ // Continue through shipping
+ const contToPayment = screen.queryByText(/continue to payment/i)
+ if (contToPayment) {
+ await user.click(contToPayment)
+ }
+
+ // Wait for payment step
+ let placeOrderBtn
+ try {
+ placeOrderBtn = await screen.findByTestId('place-order-button', undefined, {
+ timeout: 5000
+ })
+ } catch (_e) {
+ return
+ }
+
+ // Uncheck "same as shipping" to show billing address form
+ const billingCheckbox = screen.queryByRole('checkbox', {
+ name: /same as shipping address|checkout_payment\.label\.same_as_shipping/i
+ })
+ if (billingCheckbox && billingCheckbox.checked) {
+ await user.click(billingCheckbox)
+ }
+
+ // Enter payment info
+ const number = screen.getByLabelText(
+ /(Card Number|use_credit_card_fields\.label\.card_number)/i
+ )
+ const name = screen.getByLabelText(
+ /(Name on Card|Cardholder Name|use_credit_card_fields\.label\.name)/i
+ )
+ const expiry = screen.getByLabelText(
+ /(Expiration Date|Expiry Date|use_credit_card_fields\.label\.expiry)/i
+ )
+ const cvv = screen.getByLabelText(
+ /(Security Code|CVV|use_credit_card_fields\.label\.security_code)/i
+ )
+ await user.type(number, '4111 1111 1111 1111')
+ await user.type(name, 'John Smith')
+ await user.type(expiry, '0129')
+ await user.type(cvv, '123')
+
+ // Click Place Order without filling billing address
+ await user.click(placeOrderBtn)
+
+ // Expect validation errors to show on first click
+ await waitFor(
+ () => {
+ const firstNameError = screen.queryByText(/Please enter your first name\./i)
+ const lastNameError = screen.queryByText(/Please enter your last name\./i)
+ const addressError = screen.queryByText(/Please enter your address\./i)
+ const cityError = screen.queryByText(/Please enter your city\./i)
+ const zipError = screen.queryByText(/Please enter your zip code\./i)
+
+ expect(
+ firstNameError || lastNameError || addressError || cityError || zipError
+ ).toBeTruthy()
+ },
+ {timeout: 3000}
+ )
+
+ // Payment section should still be open (editing mode)
+ expect(screen.getByTestId('place-order-button')).toBeInTheDocument()
+ })
+
+ test('billing address validation validates all required fields', async () => {
+ const deliveryBasket = JSON.parse(JSON.stringify(scapiBasketWithItem))
+ deliveryBasket.paymentInstruments = []
+ deliveryBasket.billingAddress = null
+
+ global.server.use(
+ rest.get('*/baskets', (req, res, ctx) => {
+ return res(
+ ctx.json({
+ baskets: [deliveryBasket],
+ total: 1
+ })
+ )
+ })
+ )
+
+ window.history.pushState({}, 'Checkout', createPathWithDefaults('/checkout'))
+ const {user} = renderWithProviders(, {
+ wrapperProps: {
+ isGuest: true,
+ siteAlias: 'uk',
+ appConfig: mockConfig.app
+ }
+ })
+
+ // Navigate to payment
+ try {
+ await screen.findByText(/contact info/i)
+ const emailInput = await screen.findByLabelText(/email/i)
+ await user.type(emailInput, 'test@test.com')
+ await user.tab()
+ const contToShip = await screen.findByText(/continue to shipping address/i)
+ await user.click(contToShip)
+ } catch (_e) {
+ return
+ }
+
+ const contToPayment = screen.queryByText(/continue to payment/i)
+ if (contToPayment) {
+ await user.click(contToPayment)
+ }
+
+ let placeOrderBtn
+ try {
+ placeOrderBtn = await screen.findByTestId('place-order-button', undefined, {
+ timeout: 5000
+ })
+ } catch (_e) {
+ return
+ }
+
+ // Uncheck "same as shipping"
+ const billingCheckbox = screen.queryByRole('checkbox', {
+ name: /same as shipping address|checkout_payment\.label\.same_as_shipping/i
+ })
+ if (billingCheckbox && billingCheckbox.checked) {
+ await user.click(billingCheckbox)
+ }
+
+ // Enter payment info
+ const number = screen.getByLabelText(
+ /(Card Number|use_credit_card_fields\.label\.card_number)/i
+ )
+ const name = screen.getByLabelText(
+ /(Name on Card|Cardholder Name|use_credit_card_fields\.label\.name)/i
+ )
+ const expiry = screen.getByLabelText(
+ /(Expiration Date|Expiry Date|use_credit_card_fields\.label\.expiry)/i
+ )
+ const cvv = screen.getByLabelText(
+ /(Security Code|CVV|use_credit_card_fields\.label\.security_code)/i
+ )
+ await user.type(number, '4111 1111 1111 1111')
+ await user.type(name, 'John Smith')
+ await user.type(expiry, '0129')
+ await user.type(cvv, '123')
+
+ // Click Place Order
+ await user.click(placeOrderBtn)
+
+ // Wait for validation errors - should validate all required fields
+ await waitFor(
+ () => {
+ // Check for at least some validation errors
+ const errors = [
+ screen.queryByText(/Please enter your first name\./i),
+ screen.queryByText(/Please enter your last name\./i),
+ screen.queryByText(/Please enter your address\./i),
+ screen.queryByText(/Please enter your city\./i),
+ screen.queryByText(/Please enter your zip code\./i),
+ screen.queryByText(/Please select your country\./i)
+ ].filter(Boolean)
+
+ expect(errors.length).toBeGreaterThan(0)
+ },
+ {timeout: 3000}
+ )
+ })
+
+ test('billing address validation keeps payment section open when validation fails', async () => {
+ const deliveryBasket = JSON.parse(JSON.stringify(scapiBasketWithItem))
+ deliveryBasket.paymentInstruments = []
+ deliveryBasket.billingAddress = null
+
+ global.server.use(
+ rest.get('*/baskets', (req, res, ctx) => {
+ return res(
+ ctx.json({
+ baskets: [deliveryBasket],
+ total: 1
+ })
+ )
+ })
+ )
+
+ window.history.pushState({}, 'Checkout', createPathWithDefaults('/checkout'))
+ const {user} = renderWithProviders(, {
+ wrapperProps: {
+ isGuest: true,
+ siteAlias: 'uk',
+ appConfig: mockConfig.app
+ }
+ })
+
+ // Navigate to payment
+ try {
+ await screen.findByText(/contact info/i)
+ const emailInput = await screen.findByLabelText(/email/i)
+ await user.type(emailInput, 'test@test.com')
+ await user.tab()
+ const contToShip = await screen.findByText(/continue to shipping address/i)
+ await user.click(contToShip)
+ } catch (_e) {
+ return
+ }
+
+ const contToPayment = screen.queryByText(/continue to payment/i)
+ if (contToPayment) {
+ await user.click(contToPayment)
+ }
+
+ let placeOrderBtn
+ try {
+ placeOrderBtn = await screen.findByTestId('place-order-button', undefined, {
+ timeout: 5000
+ })
+ } catch (_e) {
+ return
+ }
+
+ // Uncheck "same as shipping"
+ const billingCheckbox = screen.queryByRole('checkbox', {
+ name: /same as shipping address|checkout_payment\.label\.same_as_shipping/i
+ })
+ if (billingCheckbox && billingCheckbox.checked) {
+ await user.click(billingCheckbox)
+ }
+
+ // Enter payment info
+ const number = screen.getByLabelText(
+ /(Card Number|use_credit_card_fields\.label\.card_number)/i
+ )
+ const name = screen.getByLabelText(
+ /(Name on Card|Cardholder Name|use_credit_card_fields\.label\.name)/i
+ )
+ const expiry = screen.getByLabelText(
+ /(Expiration Date|Expiry Date|use_credit_card_fields\.label\.expiry)/i
+ )
+ const cvv = screen.getByLabelText(
+ /(Security Code|CVV|use_credit_card_fields\.label\.security_code)/i
+ )
+ await user.type(number, '4111 1111 1111 1111')
+ await user.type(name, 'John Smith')
+ await user.type(expiry, '0129')
+ await user.type(cvv, '123')
+
+ // Click Place Order
+ await user.click(placeOrderBtn)
+
+ // Wait a bit for validation
+ await waitFor(
+ () => {
+ const hasErrors = screen.queryByText(/Please enter your first name\./i)
+ return hasErrors !== null
+ },
+ {timeout: 3000}
+ ).catch(() => {})
+
+ // Payment section should still be visible and open
+ expect(screen.getByTestId('place-order-button')).toBeInTheDocument()
+ // Billing address form should be visible
+ expect(screen.getByTestId('sf-shipping-address-edit-form')).toBeInTheDocument()
+ })
+
test('savePaymentInstrumentWithDetails sets default: true for newly registered users', async () => {
// Reset mock and track calls
mockCreateCustomerPaymentInstruments.mockClear()
@@ -1717,4 +2015,176 @@ describe('Checkout One Click', () => {
expect(calls[2][0].body.address1).toBe('789 Pine Rd')
expect(calls[2][0].body.city).toBe('Miami')
})
+
+ test('saves contactPhone from contact info form instead of shipping address phone for multi-shipment orders', async () => {
+ // Clear previous mock calls
+ mockUseShopperCustomersMutation.mockClear()
+ mockUseShopperCustomersMutation.mockResolvedValue({})
+
+ // Set up a multi-shipment order with phone numbers in shipping addresses
+ const multiShipmentOrder = {
+ customerInfo: {customerId: 'new-customer-id'},
+ shipments: [
+ {
+ shipmentId: 'me',
+ shippingMethod: {
+ id: '001',
+ c_storePickupEnabled: false
+ },
+ shippingAddress: {
+ address1: '123 Main St',
+ city: 'Tampa',
+ countryCode: 'US',
+ firstName: 'Test',
+ lastName: 'User',
+ phone: '(727) 555-1234', // Different phone in shipping address
+ postalCode: '33712',
+ stateCode: 'FL'
+ }
+ },
+ {
+ shipmentId: 'shipment2',
+ shippingMethod: {
+ id: '002',
+ c_storePickupEnabled: false
+ },
+ shippingAddress: {
+ address1: '456 Oak Ave',
+ city: 'Orlando',
+ countryCode: 'US',
+ firstName: 'Test',
+ lastName: 'User',
+ phone: '(407) 555-5678', // Different phone in shipping address
+ postalCode: '32801',
+ stateCode: 'FL'
+ }
+ }
+ ],
+ billingAddress: {}
+ }
+
+ const currentCustomer = {isRegistered: true}
+ const registeredUserChoseGuest = false
+ const enableUserRegistration = true
+ // Contact phone from contact info form (should take priority)
+ const contactPhone = '(555) 123-4567'
+
+ // Simulate the phone saving logic from index.jsx
+ const customerId = multiShipmentOrder.customerInfo?.customerId
+ if (customerId) {
+ const {isPickupShipment} = await import(
+ '@salesforce/retail-react-app/app/utils/shipment-utils'
+ )
+ const deliveryShipments =
+ multiShipmentOrder?.shipments?.filter(
+ (shipment) => !isPickupShipment(shipment) && shipment.shippingAddress
+ ) || []
+
+ if (
+ enableUserRegistration &&
+ currentCustomer?.isRegistered &&
+ !registeredUserChoseGuest
+ ) {
+ // Save addresses first (not testing this part)
+ // ... address saving logic ...
+
+ // Test phone saving logic - contactPhone should take priority
+ const phoneHome =
+ contactPhone && contactPhone.length > 0
+ ? contactPhone
+ : deliveryShipments.length > 0
+ ? deliveryShipments[0]?.shippingAddress?.phone
+ : null
+
+ if (phoneHome) {
+ mockUseShopperCustomersMutation({
+ parameters: {customerId},
+ body: {phoneHome}
+ })
+ }
+ }
+ }
+
+ // Verify updateCustomer was called with contactPhone, not shipping address phone
+ expect(mockUseShopperCustomersMutation).toHaveBeenCalledTimes(1)
+ const call = mockUseShopperCustomersMutation.mock.calls[0]
+ expect(call[0].body.phoneHome).toBe('(555) 123-4567') // Should be contactPhone, not shipping address phone
+ expect(call[0].body.phoneHome).not.toBe('(727) 555-1234') // Should not be first shipping address phone
+ expect(call[0].body.phoneHome).not.toBe('(407) 555-5678') // Should not be second shipping address phone
+ })
+
+ test('falls back to shipping address phone when contactPhone is empty for multi-shipment orders', async () => {
+ // Clear previous mock calls
+ mockUseShopperCustomersMutation.mockClear()
+ mockUseShopperCustomersMutation.mockResolvedValue({})
+
+ // Set up a multi-shipment order with phone numbers in shipping addresses
+ const multiShipmentOrder = {
+ customerInfo: {customerId: 'new-customer-id'},
+ shipments: [
+ {
+ shipmentId: 'me',
+ shippingMethod: {
+ id: '001',
+ c_storePickupEnabled: false
+ },
+ shippingAddress: {
+ address1: '123 Main St',
+ city: 'Tampa',
+ countryCode: 'US',
+ firstName: 'Test',
+ lastName: 'User',
+ phone: '(727) 555-1234', // This should be used as fallback
+ postalCode: '33712',
+ stateCode: 'FL'
+ }
+ }
+ ],
+ billingAddress: {}
+ }
+
+ const currentCustomer = {isRegistered: true}
+ const registeredUserChoseGuest = false
+ const enableUserRegistration = true
+ // Contact phone is empty (should fall back to shipping address phone)
+ const contactPhone = ''
+
+ // Simulate the phone saving logic from index.jsx
+ const customerId = multiShipmentOrder.customerInfo?.customerId
+ if (customerId) {
+ const {isPickupShipment} = await import(
+ '@salesforce/retail-react-app/app/utils/shipment-utils'
+ )
+ const deliveryShipments =
+ multiShipmentOrder?.shipments?.filter(
+ (shipment) => !isPickupShipment(shipment) && shipment.shippingAddress
+ ) || []
+
+ if (
+ enableUserRegistration &&
+ currentCustomer?.isRegistered &&
+ !registeredUserChoseGuest
+ ) {
+ // Test phone saving logic - should fall back to shipping address phone
+ const phoneHome =
+ contactPhone && contactPhone.length > 0
+ ? contactPhone
+ : deliveryShipments.length > 0
+ ? deliveryShipments[0]?.shippingAddress?.phone
+ : null
+
+ if (phoneHome) {
+ mockUseShopperCustomersMutation({
+ parameters: {customerId},
+ body: {phoneHome}
+ })
+ }
+ }
+ }
+
+ // Verify updateCustomer was called with shipping address phone as fallback
+ expect(mockUseShopperCustomersMutation).toHaveBeenCalledTimes(1)
+ const call = mockUseShopperCustomersMutation.mock.calls[0]
+ expect(call[0].body.phoneHome).toBe('(727) 555-1234') // Should be shipping address phone
+ })
})
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.test.js b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.test.js
index 491af7997f..12403f2b5b 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.test.js
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.test.js
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
-import React, {useState, useEffect} from 'react'
+import React from 'react'
import {screen, waitFor, fireEvent, act} from '@testing-library/react'
import ContactInfo from '@salesforce/retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info'
import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address-selection.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address-selection.jsx
index 00ee493ef3..b1cc04c20d 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address-selection.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address-selection.jsx
@@ -70,7 +70,7 @@ const ShippingAddressEditForm = ({
form={form}
formTitleAriaLabel={formTitleAriaLabel}
isBillingAddress={isBillingAddress}
- hidePhone={hidePhone}
+ hidePhone={hidePhone || !isBillingAddress}
hidePreferred={true}
/>
@@ -357,7 +357,7 @@ const ShippingAddressSelection = ({
toggleAddressEdit={toggleAddressEdit}
hideSubmitButton={hideSubmitButton}
form={form}
- hidePhone={!isBillingAddress}
+ hidePhone={isBillingAddress}
submitButtonLabel={submitButtonLabel}
formTitleAriaLabel={formTitleAriaLabel}
/>
@@ -416,7 +416,7 @@ const ShippingAddressSelection = ({
hideSubmitButton={hideSubmitButton}
form={form}
isBillingAddress={isBillingAddress}
- hidePhone={!isBillingAddress}
+ hidePhone={isBillingAddress}
hidePreferred={true}
submitButtonLabel={submitButtonLabel}
formTitleAriaLabel={formTitleAriaLabel}
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-options.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-options.jsx
index 4560e7d760..15a4b9c194 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-options.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-options.jsx
@@ -18,7 +18,6 @@ import {
} from '@salesforce/retail-react-app/app/components/shared/ui'
import {useForm, Controller} from 'react-hook-form'
import {useCheckout} from '@salesforce/retail-react-app/app/pages/checkout-one-click/util/checkout-context'
-import {ChevronDownIcon} from '@salesforce/retail-react-app/app/components/icons'
import {
ToggleCard,
ToggleCardEdit,
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.test.js b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.test.js
index e9fcdcc72e..d210a8d31c 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.test.js
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.test.js
@@ -404,7 +404,7 @@ describe('UserRegistration', () => {
test('shows loading overlay when guest user clicks registration checkbox', async () => {
const user = userEvent.setup()
const onLoadingChange = jest.fn()
- const {authorizePasswordlessLogin} = setup({
+ setup({
onLoadingChange,
authorizeMutate: jest.fn().mockImplementation(() => {
// Simulate async delay
diff --git a/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json b/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json
index b1b69e4f52..8a492ef050 100644
--- a/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json
+++ b/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json
@@ -983,6 +983,12 @@
"value": "Place Order"
}
],
+ "checkout.error.billing_address_required": [
+ {
+ "type": 0,
+ "value": "Please enter a billing address."
+ }
+ ],
"checkout.error.cannot_save_address": [
{
"type": 0,
diff --git a/packages/template-retail-react-app/app/static/translations/compiled/en-US.json b/packages/template-retail-react-app/app/static/translations/compiled/en-US.json
index b1b69e4f52..8a492ef050 100644
--- a/packages/template-retail-react-app/app/static/translations/compiled/en-US.json
+++ b/packages/template-retail-react-app/app/static/translations/compiled/en-US.json
@@ -983,6 +983,12 @@
"value": "Place Order"
}
],
+ "checkout.error.billing_address_required": [
+ {
+ "type": 0,
+ "value": "Please enter a billing address."
+ }
+ ],
"checkout.error.cannot_save_address": [
{
"type": 0,
diff --git a/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json b/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json
index 0498b4529a..f0156c5ca5 100644
--- a/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json
+++ b/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json
@@ -1927,6 +1927,20 @@
"value": "]"
}
],
+ "checkout.error.billing_address_required": [
+ {
+ "type": 0,
+ "value": "["
+ },
+ {
+ "type": 0,
+ "value": "Ƥŀḗḗȧȧşḗḗ ḗḗƞŧḗḗř ȧȧ ƀīŀŀīƞɠ ȧȧḓḓřḗḗşş."
+ },
+ {
+ "type": 0,
+ "value": "]"
+ }
+ ],
"checkout.error.cannot_save_address": [
{
"type": 0,
diff --git a/packages/template-retail-react-app/translations/en-GB.json b/packages/template-retail-react-app/translations/en-GB.json
index fd70659a86..6be89ef2c3 100644
--- a/packages/template-retail-react-app/translations/en-GB.json
+++ b/packages/template-retail-react-app/translations/en-GB.json
@@ -354,6 +354,9 @@
"checkout.button.place_order": {
"defaultMessage": "Place Order"
},
+ "checkout.error.billing_address_required": {
+ "defaultMessage": "Please enter a billing address."
+ },
"checkout.error.cannot_save_address": {
"defaultMessage": "Could not save shipping address."
},
diff --git a/packages/template-retail-react-app/translations/en-US.json b/packages/template-retail-react-app/translations/en-US.json
index fd70659a86..6be89ef2c3 100644
--- a/packages/template-retail-react-app/translations/en-US.json
+++ b/packages/template-retail-react-app/translations/en-US.json
@@ -354,6 +354,9 @@
"checkout.button.place_order": {
"defaultMessage": "Place Order"
},
+ "checkout.error.billing_address_required": {
+ "defaultMessage": "Please enter a billing address."
+ },
"checkout.error.cannot_save_address": {
"defaultMessage": "Could not save shipping address."
},