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 2c34c1a5b9..28faa58c7c 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
@@ -430,7 +430,7 @@ describe('Checkout One Click', () => {
}
// Wait for continue button and click
- const continueBtn = await screen.findByText(/continue to shipping address/i)
+ const continueBtn = await screen.findByText(/continue to payment/i)
await user.click(continueBtn)
// Verify we skip directly to payment
@@ -524,7 +524,7 @@ describe('Checkout One Click', () => {
}
// Wait for continue button and click
- const continueBtn = await screen.findByText(/continue to shipping address/i)
+ const continueBtn = await screen.findByText(/continue to payment/i)
await user.click(continueBtn)
// Verify we continue to payment
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.jsx
index 5984873c5d..28348f5216 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-contact-info.jsx
@@ -50,6 +50,7 @@ import {API_ERROR_MESSAGE} from '@salesforce/retail-react-app/app/constants'
import {isValidEmail} from '@salesforce/retail-react-app/app/utils/email-utils'
import {formatPhoneNumber} from '@salesforce/retail-react-app/app/utils/phone-utils'
import useMultiSite from '@salesforce/retail-react-app/app/hooks/use-multi-site'
+import {isPickupShipment} from '@salesforce/retail-react-app/app/utils/shipment-utils'
const ContactInfo = ({isSocialEnabled = false, idps = [], onRegisteredUserChoseGuest}) => {
const {formatMessage} = useIntl()
@@ -70,6 +71,14 @@ const ContactInfo = ({isSocialEnabled = false, idps = [], onRegisteredUserChoseG
const {step, STEPS, goToStep, goToNextStep, setContactPhone} = useCheckout()
+ // Determine if this order has delivery shipments
+ const shipments = basket?.shipments || []
+ const productItems = basket?.productItems || []
+ const shipmentsWithItems = shipments.filter((s) =>
+ productItems.some((i) => i.shipmentId === s.shipmentId)
+ )
+ const hasDeliveryShipments = shipmentsWithItems.some((s) => !isPickupShipment(s))
+
const form = useForm({
defaultValues: {
email: customer?.email || basket?.customerInfo?.email || '',
@@ -615,10 +624,17 @@ const ContactInfo = ({isSocialEnabled = false, idps = [], onRegisteredUserChoseG
isLoading={isSubmitting}
disabled={isSubmitting}
>
-
+ {hasDeliveryShipments ? (
+
+ ) : (
+
+ )}
)}
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 12403f2b5b..73cdbefb1a 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
@@ -48,7 +48,9 @@ const mockUseCurrentBasket = jest.fn(() => ({
basketId: 'test-basket-id',
customerInfo: {
email: null
- }
+ },
+ shipments: [{shipmentId: 'shipment-1', shipmentType: 'delivery'}],
+ productItems: [{productId: 'product-1', shipmentId: 'shipment-1'}]
},
derivedData: {
hasBasket: true,
@@ -126,6 +128,17 @@ beforeEach(() => {
jest.clearAllMocks()
// Default: allow OTP authorization so modal can open unless a test overrides it
mockAuthHelperFunctions[AuthHelpers.AuthorizePasswordless].mutateAsync.mockResolvedValue({})
+ // Reset basket mock to default (delivery shipment)
+ mockUseCurrentBasket.mockReturnValue({
+ data: {
+ basketId: 'test-basket-id',
+ customerInfo: {email: null},
+ shipments: [{shipmentId: 'shipment-1', shipmentType: 'delivery'}],
+ productItems: [{productId: 'product-1', shipmentId: 'shipment-1'}]
+ },
+ derivedData: {hasBasket: true, totalItems: 1},
+ refetch: jest.fn()
+ })
})
afterEach(() => {})
@@ -405,6 +418,43 @@ describe('ContactInfo Component', () => {
})
})
+ test('renders "Continue to Payment" button for BOPIS-only orders', async () => {
+ // Mock BOPIS-only basket
+ mockUseCurrentBasket.mockReturnValue({
+ data: {
+ basketId: 'test-basket-id',
+ customerInfo: {email: null},
+ shipments: [{shipmentId: 'pickup-1', c_fromStoreId: 'store-123'}],
+ productItems: [{productId: 'product-1', shipmentId: 'pickup-1'}]
+ },
+ derivedData: {hasBasket: true, totalItems: 1},
+ refetch: jest.fn()
+ })
+
+ // Mock the passwordless login to fail (guest checkout)
+ mockAuthHelperFunctions[AuthHelpers.AuthorizePasswordless].mutateAsync.mockRejectedValue(
+ new Error('Email not found')
+ )
+
+ const {user} = renderWithProviders()
+
+ const emailInput = screen.getByLabelText('Email')
+ await user.type(emailInput, validEmail)
+ fireEvent.blur(emailInput)
+
+ await waitFor(() => {
+ const continueBtn = screen.getByRole('button', {
+ name: /continue to payment/i
+ })
+ expect(continueBtn).toBeEnabled()
+ })
+
+ // Verify "Continue to Shipping Address" is NOT shown
+ expect(
+ screen.queryByRole('button', {name: /continue to shipping address/i})
+ ).not.toBeInTheDocument()
+ })
+
test('requires phone for guest shoppers on submit', async () => {
// Ensure guest path (no OTP modal)
mockAuthHelperFunctions[AuthHelpers.AuthorizePasswordless].mutateAsync.mockRejectedValue(
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 8a492ef050..89d8658dd3 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
@@ -1547,6 +1547,12 @@
"value": "Checkout as Guest"
}
],
+ "contact_info.button.continue_to_payment": [
+ {
+ "type": 0,
+ "value": "Continue to Payment"
+ }
+ ],
"contact_info.button.continue_to_shipping_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 8a492ef050..89d8658dd3 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
@@ -1547,6 +1547,12 @@
"value": "Checkout as Guest"
}
],
+ "contact_info.button.continue_to_payment": [
+ {
+ "type": 0,
+ "value": "Continue to Payment"
+ }
+ ],
"contact_info.button.continue_to_shipping_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 f0156c5ca5..2c641e591c 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
@@ -3147,6 +3147,20 @@
"value": "]"
}
],
+ "contact_info.button.continue_to_payment": [
+ {
+ "type": 0,
+ "value": "["
+ },
+ {
+ "type": 0,
+ "value": "Ƈǿǿƞŧīƞŭŭḗḗ ŧǿǿ Ƥȧȧẏḿḗḗƞŧ"
+ },
+ {
+ "type": 0,
+ "value": "]"
+ }
+ ],
"contact_info.button.continue_to_shipping_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 6be89ef2c3..52e1ef67f8 100644
--- a/packages/template-retail-react-app/translations/en-GB.json
+++ b/packages/template-retail-react-app/translations/en-GB.json
@@ -601,6 +601,9 @@
"contact_info.button.checkout_as_guest": {
"defaultMessage": "Checkout as Guest"
},
+ "contact_info.button.continue_to_payment": {
+ "defaultMessage": "Continue to Payment"
+ },
"contact_info.button.continue_to_shipping_address": {
"defaultMessage": "Continue to 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 6be89ef2c3..52e1ef67f8 100644
--- a/packages/template-retail-react-app/translations/en-US.json
+++ b/packages/template-retail-react-app/translations/en-US.json
@@ -601,6 +601,9 @@
"contact_info.button.checkout_as_guest": {
"defaultMessage": "Checkout as Guest"
},
+ "contact_info.button.continue_to_payment": {
+ "defaultMessage": "Continue to Payment"
+ },
"contact_info.button.continue_to_shipping_address": {
"defaultMessage": "Continue to Shipping Address"
},