Fixed order total mismatch issue on cancelled page
Fixed token validation issue Fixed issue displaying shipping method and fee on checkout Added Light only theme Fixed positioning issue on mobile view
This commit is contained in:
@@ -160,17 +160,20 @@ router.post('/capture-order', validateCaptureOrder, async (req, res) => {
|
||||
tokenLength: token?.length
|
||||
});
|
||||
|
||||
// Declare tokenData at function scope
|
||||
let tokenData = null;
|
||||
|
||||
// Verify token (optional in development)
|
||||
const skipTokenValidation = process.env.NODE_ENV === 'development' && process.env.SKIP_TOKEN_VALIDATION === 'true';
|
||||
|
||||
if (token && !skipTokenValidation) {
|
||||
const tokenData = verifyToken(token);
|
||||
tokenData = verifyToken(token);
|
||||
console.log('Token verification result:', {
|
||||
isValid: !!tokenData,
|
||||
tokenData: tokenData
|
||||
});
|
||||
|
||||
if (!tokenData || tokenData.wc_order_id !== parseInt(wc_order_id)) {
|
||||
if (!tokenData || tokenData.wc_order_id !== String(wc_order_id)) {
|
||||
console.error('Token validation failed:', {
|
||||
tokenData,
|
||||
expectedOrderId: wc_order_id,
|
||||
|
||||
@@ -39,11 +39,11 @@ function App() {
|
||||
gap={4}
|
||||
>
|
||||
<Image width="550px" src={logo} className="logo react" alt="React logo" />
|
||||
<Center>
|
||||
<Button variant="outline" onClick={toggleColorMode} >
|
||||
{colorMode === "light" ? <><LuSun /> Toggle Light mode</> : <><LuMoon /> Toogle Dark mode</>}
|
||||
</Button>
|
||||
</Center>
|
||||
{/*<Center>*/}
|
||||
{/* <Button variant="outline" onClick={toggleColorMode} >*/}
|
||||
{/* {colorMode === "light" ? <><LuSun /> Toggle Light mode</> : <><LuMoon /> Toogle Dark mode</>}*/}
|
||||
{/* </Button>*/}
|
||||
{/*</Center>*/}
|
||||
</Grid>
|
||||
<Flex direction="row" gap="4" justify="space-between" align="center" mb="10">
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ const OrderSummary = ({ orderData, loading, order }) => {
|
||||
<DataList.ItemValue>{orderData.customer_email}</DataList.ItemValue>
|
||||
</DataList.Item>
|
||||
)}*/}
|
||||
{order.shipping.method &&
|
||||
<DataList.Item pt="4">
|
||||
<DataList.ItemLabel>
|
||||
<Badge colorPalette="teal" variant="solid">
|
||||
@@ -72,7 +73,7 @@ const OrderSummary = ({ orderData, loading, order }) => {
|
||||
</Badge>
|
||||
</DataList.ItemLabel>
|
||||
<DataList.ItemValue>{formatCurrency(order.shipping.total, orderData.currency)}</DataList.ItemValue>
|
||||
</DataList.Item>
|
||||
</DataList.Item> }
|
||||
</> }
|
||||
<DataList.Item pt="4" textStyle="xl">
|
||||
<DataList.ItemLabel><strong>Total Amount:</strong></DataList.ItemLabel>
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { Provider } from "@/components/ui/provider"
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { ChakraProvider } from "@chakra-ui/react";
|
||||
import { system } from "./theme";
|
||||
import './index.css'
|
||||
import App from './App.jsx'
|
||||
import {ThemeProvider} from "next-themes";
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<Provider>
|
||||
<ChakraProvider value={system}>
|
||||
<ThemeProvider attribute="class" defaultTheme="light" enableSystem={false}>
|
||||
<App />
|
||||
</Provider>
|
||||
</ThemeProvider>
|
||||
</ChakraProvider>
|
||||
</StrictMode>,
|
||||
)
|
||||
|
||||
@@ -16,20 +16,40 @@ const Cancel = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const error = searchParams.get('error');
|
||||
const orderId = searchParams.get('order_id');
|
||||
const orderId = searchParams.get('order_id') || searchParams.get('wc_order_id');
|
||||
const paypalToken = searchParams.get('token');
|
||||
|
||||
const orderTotal = searchParams.get('total');
|
||||
const currency = searchParams.get('currency') || 'USD';
|
||||
const description = searchParams.get('description');
|
||||
const customerEmail = searchParams.get('customer_email');
|
||||
const cancelUrl = searchParams.get('cancel_url');
|
||||
const returnUrl = searchParams.get('return_url');
|
||||
|
||||
const formatCurrency = (amount, curr = 'USD') => {
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: curr,
|
||||
}).format(parseFloat(amount));
|
||||
};
|
||||
|
||||
const getErrorMessage = () => {
|
||||
if (error) {
|
||||
return decodeURIComponent(error);
|
||||
}
|
||||
return 'Your payment was cancelled. You can try again or choose a different payment method.';
|
||||
};
|
||||
|
||||
const handleRetryPayment = () => {
|
||||
// Build the payment URL with original parameters
|
||||
const paymentUrl = new URL('/payment', window.location.origin);
|
||||
|
||||
if (orderId) {
|
||||
paymentUrl.searchParams.set('wc_order_id', orderId);
|
||||
// You might want to fetch original order details here
|
||||
paymentUrl.searchParams.set('total', '25.99'); // This should come from order data
|
||||
}
|
||||
// Preserve all original order parameters
|
||||
if (orderId) paymentUrl.searchParams.set('wc_order_id', orderId);
|
||||
if (orderTotal) paymentUrl.searchParams.set('total', orderTotal);
|
||||
if (currency) paymentUrl.searchParams.set('currency', currency);
|
||||
if (description) paymentUrl.searchParams.set('description', description);
|
||||
if (customerEmail) paymentUrl.searchParams.set('customer_email', customerEmail);
|
||||
if (returnUrl) paymentUrl.searchParams.set('return_url', returnUrl);
|
||||
if (cancelUrl) paymentUrl.searchParams.set('cancel_url', cancelUrl);
|
||||
|
||||
window.location.href = paymentUrl.toString();
|
||||
};
|
||||
@@ -41,7 +61,7 @@ const Cancel = () => {
|
||||
<Alert.Content>
|
||||
<Alert.Title>Payment Cancelled</Alert.Title>
|
||||
<Alert.Description>
|
||||
<Text>Your payment was cancelled. You can try again or choose a different payment method.</Text>
|
||||
<Text>{getErrorMessage()}</Text>
|
||||
</Alert.Description>
|
||||
</Alert.Content>
|
||||
</Alert.Root>
|
||||
@@ -63,6 +83,13 @@ const Cancel = () => {
|
||||
<strong>Order ID:</strong>
|
||||
<span className="badge bg-secondary ms-2">{orderId}</span>
|
||||
<br/>
|
||||
{orderTotal && (
|
||||
<>
|
||||
<strong>Order Total:</strong>
|
||||
<span className="ms-2">{formatCurrency(orderTotal, currency)}</span>
|
||||
<br/>
|
||||
</>
|
||||
)}
|
||||
<small className="mt-2 d-block">
|
||||
Your order is still pending. You can complete the payment to process your order.
|
||||
</small>
|
||||
@@ -121,7 +148,7 @@ const Cancel = () => {
|
||||
<Accordion.ItemIndicator/>
|
||||
</Accordion.ItemTrigger>
|
||||
<Accordion.ItemContent>
|
||||
<Accordion.ItemBody>Text</Accordion.ItemBody>
|
||||
<Accordion.ItemBody>Contact Support: Reach us anytime at {import.meta.env.VITE_REACT_APP_SUPPORT_EMAIL} or through live chat.</Accordion.ItemBody>
|
||||
</Accordion.ItemContent>
|
||||
</Accordion.Item>
|
||||
</Accordion.Root>
|
||||
|
||||
@@ -190,7 +190,7 @@ const Payment = () => {
|
||||
<Grid
|
||||
templateColumns={{ base: "1fr", md: "repeat(3, 1fr)" }}
|
||||
templateRows="repeat(1, 1fr)"
|
||||
gap="6"
|
||||
// gap="6"
|
||||
>
|
||||
<GridItem colSpan={2}>
|
||||
<Center>
|
||||
|
||||
8
frontend/src/theme.js
Normal file
8
frontend/src/theme.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react";
|
||||
|
||||
const config = defineConfig({
|
||||
// put tokens/recipes if you need; not required just to force light mode
|
||||
theme: {},
|
||||
});
|
||||
|
||||
export const system = createSystem(defaultConfig, config);
|
||||
Reference in New Issue
Block a user