Skip to content

Commit d9ea96c

Browse files
dragosp1011Tymmmy
andauthored
feat(boutique): check order status before showing success message (#1988)
* feat(boutique): check order status before showing success message * add extra info for error message --------- Co-authored-by: Tymmmy <117268143+Tymmmy@users.noreply.github.com>
1 parent 208d78c commit d9ea96c

3 files changed

Lines changed: 50 additions & 3 deletions

File tree

packages/boutique/backend/src/app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export class App {
7979
router.post('/orders/setup-one-click', orderController.setup)
8080
router.post('/orders/setup-one-click/finish', orderController.setupFinish)
8181
router.patch('/orders/:id', orderController.finish)
82+
router.get('/orders/:id', orderController.get)
8283

8384
router.use('*', (req: Request, res: TypedResponse) => {
8485
const e = Error(`Requested path ${req.path} was not found.`)

packages/boutique/frontend/src/app/checkout/confirmation.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useEffect } from 'react'
1010
import { Link, Navigate, useSearchParams } from 'react-router-dom'
1111
import { checkoutConfirmationSearchParamsSchema } from '../route-schemas.ts'
1212
import { Loader } from '@/components/loader.tsx'
13+
import { OrderStatus, useOrderQuery } from '@/hooks/use-order-query.ts'
1314

1415
function InstantBuy() {
1516
return (
@@ -27,8 +28,8 @@ function CheckoutConfirmation() {
2728
const [{ orderId, hash, interact_ref, result }] = useZodSearchParams(
2829
checkoutConfirmationSearchParamsSchema
2930
)
30-
const { mutate, data, error } = useFinishCheckoutMutation(orderId)
31-
31+
const { data: orderResponse } = useOrderQuery(orderId)
32+
const { mutate, error } = useFinishCheckoutMutation(orderId)
3233
useEffect(() => {
3334
mutate({
3435
hash,
@@ -38,7 +39,13 @@ function CheckoutConfirmation() {
3839
// eslint-disable-next-line react-hooks/exhaustive-deps
3940
}, [])
4041

41-
if (data) {
42+
if (!orderResponse) {
43+
return <Loader />
44+
}
45+
46+
const order = orderResponse.result
47+
48+
if (order.status !== OrderStatus.PROCESSING) {
4249
let color: string = ' text-green dark:text-green-neon'
4350
let text: string = 'Thank you for your order!'
4451
let variant: VariantProps<typeof buttonVariants>['variant'] = 'default'
@@ -49,6 +56,12 @@ function CheckoutConfirmation() {
4956
variant = 'secondary'
5057
}
5158

59+
if (order.status === OrderStatus.FAILED) {
60+
color = ' text-orange-dark dark:text-pink-neon'
61+
text = 'Payment failed. Check funds and please try again.'
62+
variant = 'secondary'
63+
}
64+
5265
return (
5366
<div
5467
className={cn(
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { UseQueryResult, useQuery } from '@tanstack/react-query'
2+
import { fetcher, APIError } from '@/lib/fetcher.ts'
3+
import { SuccessResponse } from '@/lib/types.ts'
4+
5+
export enum OrderStatus {
6+
PROCESSING = 'PROCESSING',
7+
FAILED = 'FAILED',
8+
COMPLETED = 'COMPLETED',
9+
REJECTED = 'REJECTED'
10+
}
11+
12+
export interface Order {
13+
id: string
14+
status: OrderStatus
15+
}
16+
export function useOrderQuery(
17+
id: string
18+
): UseQueryResult<SuccessResponse<Order>, APIError> {
19+
return useQuery({
20+
queryKey: ['orders', id],
21+
queryFn: async function () {
22+
return await fetcher('/orders/' + id, {
23+
method: 'GET'
24+
})
25+
},
26+
refetchInterval: (query) => {
27+
return !query.state.data ||
28+
query.state.data.result?.status === OrderStatus.PROCESSING
29+
? 2000
30+
: undefined
31+
}
32+
})
33+
}

0 commit comments

Comments
 (0)