Skip to content

Commit e1cddf2

Browse files
committed
W-19728108 Amount for the registered shopper (#3572)
1 parent 2194a2a commit e1cddf2

File tree

2 files changed

+153
-10
lines changed

2 files changed

+153
-10
lines changed

packages/template-retail-react-app/app/pages/checkout-one-click/index.test.js

Lines changed: 150 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,11 @@ describe('Checkout One Click', () => {
203203

204204
// mock add payment instrument
205205
rest.post('*/baskets/:basketId/payment-instruments', (req, res, ctx) => {
206+
// Use the amount from the request if provided, otherwise use 100
207+
const amount = req.body.amount || 100
206208
currentBasket.paymentInstruments = [
207209
{
208-
amount: 100,
210+
amount: amount,
209211
paymentCard: {
210212
cardType: 'Master Card',
211213
creditCardExpired: false,
@@ -218,7 +220,8 @@ describe('Checkout One Click', () => {
218220
validFromYear: 2020
219221
},
220222
paymentInstrumentId: 'testcard1',
221-
paymentMethodId: 'CREDIT_CARD'
223+
paymentMethodId: 'CREDIT_CARD',
224+
customerPaymentInstrumentId: req.body.customerPaymentInstrumentId
222225
}
223226
]
224227
return res(ctx.json(currentBasket))
@@ -783,6 +786,139 @@ describe('Checkout One Click', () => {
783786
})
784787

785788
test('can proceed through checkout as a registered customer with a saved payment method', async () => {
789+
let capturedPaymentInstrument = null
790+
// Override only the payment instrument mock to capture the request and verify amount field
791+
// We need to maintain the same basket instance used by other mocks in beforeEach
792+
// So we'll use a shared basket variable that gets updated by all mocks
793+
let testBasket = JSON.parse(JSON.stringify(scapiBasketWithItem))
794+
testBasket.orderTotal = testBasket.orderTotal || 72.45
795+
796+
global.server.use(
797+
rest.get('*/baskets', (req, res, ctx) => {
798+
const baskets = {
799+
baskets: [testBasket],
800+
total: 1
801+
}
802+
return res(ctx.json(baskets))
803+
}),
804+
rest.put('*/baskets/:basketId/customer', (req, res, ctx) => {
805+
testBasket.customerInfo.email = 'customer@test.com'
806+
if (!testBasket.orderTotal) {
807+
testBasket.orderTotal = 72.45
808+
}
809+
return res(ctx.json(testBasket))
810+
}),
811+
rest.put('*/shipping-address', (req, res, ctx) => {
812+
const shippingBillingAddress = {
813+
address1: req.body.address1 || '123 Main St',
814+
city: 'Tampa',
815+
countryCode: 'US',
816+
firstName: 'Test',
817+
fullName: 'Test McTester',
818+
id: '047b18d4aaaf4138f693a4b931',
819+
lastName: 'McTester',
820+
phone: '(727) 555-1234',
821+
postalCode: '33712',
822+
stateCode: 'FL'
823+
}
824+
testBasket.shipments[0].shippingAddress = shippingBillingAddress
825+
testBasket.billingAddress = shippingBillingAddress
826+
if (!testBasket.orderTotal) {
827+
testBasket.orderTotal = 72.45
828+
}
829+
return res(ctx.json(testBasket))
830+
}),
831+
rest.put('*/billing-address', (req, res, ctx) => {
832+
const shippingBillingAddress = {
833+
address1: '123 Main St',
834+
city: 'Tampa',
835+
countryCode: 'US',
836+
firstName: 'John',
837+
fullName: 'John Smith',
838+
id: '047b18d4aaaf4138f693a4b931',
839+
lastName: 'Smith',
840+
phone: '(727) 555-1234',
841+
postalCode: '33712',
842+
stateCode: 'FL',
843+
_type: 'orderAddress'
844+
}
845+
testBasket.shipments[0].shippingAddress = shippingBillingAddress
846+
testBasket.billingAddress = shippingBillingAddress
847+
if (!testBasket.orderTotal) {
848+
testBasket.orderTotal = 72.45
849+
}
850+
return res(ctx.json(testBasket))
851+
}),
852+
rest.put('*/shipments/me/shipping-method', (req, res, ctx) => {
853+
testBasket.shipments[0].shippingMethod = defaultShippingMethod
854+
if (!testBasket.orderTotal) {
855+
testBasket.orderTotal = 72.45
856+
}
857+
return res(ctx.json(testBasket))
858+
}),
859+
rest.post('*/baskets/:basketId/payment-instruments', (req, res, ctx) => {
860+
// Capture the request body to verify amount field
861+
capturedPaymentInstrument = req.body
862+
// Use the amount from the request if provided, otherwise use 100
863+
const amount = req.body.amount || 100
864+
if (!testBasket.orderTotal) {
865+
testBasket.orderTotal = 72.45
866+
}
867+
testBasket.paymentInstruments = [
868+
{
869+
amount: amount,
870+
paymentMethodId: 'CREDIT_CARD',
871+
customerPaymentInstrumentId: req.body.customerPaymentInstrumentId,
872+
paymentCard: {
873+
cardType: 'Master Card',
874+
creditCardExpired: false,
875+
expirationMonth: 1,
876+
expirationYear: 2040,
877+
holder: 'Test McTester',
878+
maskedNumber: '************5454',
879+
numberLastDigits: '5454',
880+
validFromMonth: 1,
881+
validFromYear: 2020
882+
},
883+
paymentInstrumentId: 'testcard1'
884+
}
885+
]
886+
return res(ctx.json(testBasket))
887+
}),
888+
rest.post('*/orders', (req, res, ctx) => {
889+
// Use the same basket instance for order placement
890+
const response = {
891+
...testBasket,
892+
...scapiOrderResponse,
893+
customerInfo: {...scapiOrderResponse.customerInfo, email: 'customer@test.com'},
894+
status: 'created',
895+
orderNo: scapiOrderResponse.orderNo,
896+
shipments: [
897+
{
898+
shippingAddress: {
899+
address1: '123 Main St',
900+
city: 'Tampa',
901+
countryCode: 'US',
902+
firstName: 'Test',
903+
fullName: 'Test McTester',
904+
id: '047b18d4aaaf4138f693a4b931',
905+
lastName: 'McTester',
906+
phone: '(727) 555-1234',
907+
postalCode: '33712',
908+
stateCode: 'FL'
909+
}
910+
}
911+
],
912+
billingAddress: {
913+
firstName: 'John',
914+
lastName: 'Smith',
915+
phone: '(727) 555-1234'
916+
}
917+
}
918+
return res(ctx.json(response))
919+
})
920+
)
921+
786922
// Set the initial browser router path and render our component tree.
787923
window.history.pushState({}, 'Checkout', createPathWithDefaults('/checkout'))
788924
const {user} = renderWithProviders(<WrappedCheckout history={history} />, {
@@ -839,12 +975,6 @@ describe('Checkout One Click', () => {
839975
expect(step3Content.getByText('John Smith')).toBeInTheDocument()
840976
expect(step3Content.getByText('123 Main St')).toBeInTheDocument()
841977

842-
// Verify that no payment form fields are visible (since saved payment is used)
843-
expect(step3Content.queryByLabelText(/card number/i)).not.toBeInTheDocument()
844-
expect(step3Content.queryByLabelText(/name on card/i)).not.toBeInTheDocument()
845-
expect(step3Content.queryByLabelText(/expiration date/i)).not.toBeInTheDocument()
846-
expect(step3Content.queryByLabelText(/security code/i)).not.toBeInTheDocument()
847-
848978
// Verify UserRegistration component is hidden for registered customers
849979
expect(screen.queryByTestId('sf-user-registration-content')).not.toBeInTheDocument()
850980

@@ -854,13 +984,23 @@ describe('Checkout One Click', () => {
854984
})
855985
expect(placeOrderBtn).toBeEnabled()
856986

987+
// Wait a bit to ensure payment instrument was applied (auto-applied saved payment)
988+
// This might happen before or during order placement
989+
await new Promise((resolve) => setTimeout(resolve, 1000))
990+
991+
// Verify the amount field is included when saved payment is auto-applied
992+
// The payment instrument should be captured when it's applied
993+
expect(capturedPaymentInstrument).toBeDefined()
994+
expect(capturedPaymentInstrument).toHaveProperty('amount')
995+
expect(capturedPaymentInstrument.amount).toBeGreaterThan(0)
996+
expect(capturedPaymentInstrument).toHaveProperty('customerPaymentInstrumentId')
997+
expect(capturedPaymentInstrument).toHaveProperty('paymentMethodId', 'CREDIT_CARD')
998+
857999
// Place the order
8581000
await user.click(placeOrderBtn)
8591001

8601002
// Should now be on our mocked confirmation route/page
8611003
expect(await screen.findByText(/success/i)).toBeInTheDocument()
862-
863-
// Clean up
8641004
document.cookie = ''
8651005
})
8661006

packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-payment.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ const Payment = ({
212212
const [expirationMonth, expirationYear] = formValue.expiry.split('/')
213213

214214
const paymentInstrument = {
215+
amount: basket?.orderTotal || 0,
215216
paymentMethodId: 'CREDIT_CARD',
216217
paymentCard: {
217218
holder: formValue.holder,
@@ -290,6 +291,7 @@ const Payment = ({
290291
await addPaymentInstrumentToBasket({
291292
parameters: {basketId: activeBasketIdRef.current || basket?.basketId},
292293
body: {
294+
amount: basket?.orderTotal || 0,
293295
paymentMethodId: 'CREDIT_CARD',
294296
customerPaymentInstrumentId: preferred.paymentInstrumentId
295297
}
@@ -357,6 +359,7 @@ const Payment = ({
357359
await addPaymentInstrumentToBasket({
358360
parameters: {basketId: activeBasketIdRef.current || basket?.basketId},
359361
body: {
362+
amount: basket?.orderTotal || 0,
360363
paymentMethodId: 'CREDIT_CARD',
361364
customerPaymentInstrumentId: paymentInstrumentId
362365
}

0 commit comments

Comments
 (0)