Skip to content

Commit 4349bc7

Browse files
committed
W-21372336: Addressing comments
1 parent 80ca151 commit 4349bc7

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

packages/template-retail-react-app/app/pages/checkout/payment-processing.jsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ const PaymentProcessing = () => {
9090

9191
const isError = !isValidReturnUrl()
9292
const isHandled = useRef(false)
93-
const failOrderCalledRef = useRef(false)
9493

9594
async function handleAdyenRedirect() {
9695
// Find SF Payments payment instrument in order
@@ -134,7 +133,7 @@ const PaymentProcessing = () => {
134133
* @returns {Promise<void>}
135134
*/
136135
async function attemptFailOrderForPayment() {
137-
if (!orderNo || failOrderCalledRef.current) {
136+
if (!orderNo) {
138137
return
139138
}
140139

@@ -156,10 +155,11 @@ const PaymentProcessing = () => {
156155
}
157156
})
158157
}
159-
} catch {
160-
// Order may already be failed by webhook; avoid hanging
158+
} catch (error) {
159+
// Swallow so flow continues (invalidate, navigate). Causes: (1) Race: getOrder
160+
// returned 'created' but webhook already failed the order, so failOrder fails. (2) getOrder,
161+
// getTokenWhenReady, or failOrder threw error. Behavior for all: don't hang.
161162
} finally {
162-
failOrderCalledRef.current = true
163163
queryClient.invalidateQueries()
164164
}
165165
}
@@ -210,11 +210,11 @@ const PaymentProcessing = () => {
210210
duration: 30000
211211
})
212212

213-
// Attempt to fail the order (no-op if already failed by webhook
213+
// Attempt to fail the order (no-op if already failed by webhook)
214214
await attemptFailOrderForPayment()
215215

216-
// Redirect to cart when payment fails
217-
navigate('/cart')
216+
// Navigate back to the checkout page to try again
217+
navigate('/checkout')
218218
})()
219219
}
220220
}, [sfp, order])

packages/template-retail-react-app/app/pages/checkout/payment-processing.test.js

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -407,13 +407,13 @@ describe('PaymentProcessing', () => {
407407
})
408408
})
409409

410-
test('navigates to cart on failed payment', async () => {
410+
test('navigates back to checkout on failed payment', async () => {
411411
mockHandleRedirect.mockResolvedValue({responseCode: 1})
412412

413413
renderWithProviders(<PaymentProcessing />)
414414

415415
await waitFor(() => {
416-
expect(mockNavigate).toHaveBeenCalledWith('/cart')
416+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
417417
})
418418
})
419419

@@ -440,24 +440,41 @@ describe('PaymentProcessing', () => {
440440
})
441441
})
442442

443-
expect(mockNavigate).toHaveBeenCalledWith('/cart')
443+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
444444
})
445445

446-
test('does not call failOrder when order already failed by webhook (e.g. 3DS declined)', async () => {
446+
test('does not call failOrder when order already failed by webhook', async () => {
447447
mockHandleRedirect.mockResolvedValue({responseCode: 1})
448448
mockGetOrder.mockResolvedValue({status: 'failed'})
449449

450450
renderWithProviders(<PaymentProcessing />)
451451

452452
await waitFor(() => {
453453
expect(mockToast).toHaveBeenCalled()
454-
expect(mockNavigate).toHaveBeenCalledWith('/cart')
454+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
455455
})
456456

457457
expect(mockGetOrder).toHaveBeenCalled()
458458
expect(mockFailOrder).not.toHaveBeenCalled()
459459
})
460460

461+
test('shows toast and navigates to checkout when failOrder fails', async () => {
462+
mockHandleRedirect.mockResolvedValue({responseCode: 1})
463+
mockGetOrder.mockResolvedValue({status: 'created'})
464+
mockFailOrder.mockRejectedValue(new Error('Order already failed'))
465+
466+
renderWithProviders(<PaymentProcessing />)
467+
468+
await waitFor(() => {
469+
expect(mockToast).toHaveBeenCalled()
470+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
471+
})
472+
473+
expect(mockGetOrder).toHaveBeenCalled()
474+
expect(mockFailOrder).toHaveBeenCalledTimes(1)
475+
expect(mockInvalidateQueries).toHaveBeenCalled()
476+
})
477+
461478
test('handles different error response codes', async () => {
462479
const errorCodes = [1, 2, -1, 999]
463480

@@ -471,7 +488,7 @@ describe('PaymentProcessing', () => {
471488

472489
await waitFor(() => {
473490
expect(mockToast).toHaveBeenCalled()
474-
expect(mockNavigate).toHaveBeenCalledWith('/cart')
491+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
475492
})
476493
}
477494
})
@@ -581,11 +598,11 @@ describe('PaymentProcessing', () => {
581598
})
582599
})
583600

584-
test('navigates to cart on failed payment', async () => {
601+
test('navigates back to checkout on failed payment', async () => {
585602
renderWithProviders(<PaymentProcessing />)
586603

587604
await waitFor(() => {
588-
expect(mockNavigate).toHaveBeenCalledWith('/cart')
605+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
589606
})
590607
})
591608

@@ -610,7 +627,7 @@ describe('PaymentProcessing', () => {
610627
})
611628
})
612629

613-
expect(mockNavigate).toHaveBeenCalledWith('/cart')
630+
expect(mockNavigate).toHaveBeenCalledWith('/checkout')
614631
})
615632
})
616633
})

0 commit comments

Comments
 (0)