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
|
tokenLength: token?.length
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Declare tokenData at function scope
|
||||||
|
let tokenData = null;
|
||||||
|
|
||||||
// Verify token (optional in development)
|
// Verify token (optional in development)
|
||||||
const skipTokenValidation = process.env.NODE_ENV === 'development' && process.env.SKIP_TOKEN_VALIDATION === 'true';
|
const skipTokenValidation = process.env.NODE_ENV === 'development' && process.env.SKIP_TOKEN_VALIDATION === 'true';
|
||||||
|
|
||||||
if (token && !skipTokenValidation) {
|
if (token && !skipTokenValidation) {
|
||||||
const tokenData = verifyToken(token);
|
tokenData = verifyToken(token);
|
||||||
console.log('Token verification result:', {
|
console.log('Token verification result:', {
|
||||||
isValid: !!tokenData,
|
isValid: !!tokenData,
|
||||||
tokenData: 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:', {
|
console.error('Token validation failed:', {
|
||||||
tokenData,
|
tokenData,
|
||||||
expectedOrderId: wc_order_id,
|
expectedOrderId: wc_order_id,
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ function App() {
|
|||||||
gap={4}
|
gap={4}
|
||||||
>
|
>
|
||||||
<Image width="550px" src={logo} className="logo react" alt="React logo" />
|
<Image width="550px" src={logo} className="logo react" alt="React logo" />
|
||||||
<Center>
|
{/*<Center>*/}
|
||||||
<Button variant="outline" onClick={toggleColorMode} >
|
{/* <Button variant="outline" onClick={toggleColorMode} >*/}
|
||||||
{colorMode === "light" ? <><LuSun /> Toggle Light mode</> : <><LuMoon /> Toogle Dark mode</>}
|
{/* {colorMode === "light" ? <><LuSun /> Toggle Light mode</> : <><LuMoon /> Toogle Dark mode</>}*/}
|
||||||
</Button>
|
{/* </Button>*/}
|
||||||
</Center>
|
{/*</Center>*/}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Flex direction="row" gap="4" justify="space-between" align="center" mb="10">
|
<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.ItemValue>{orderData.customer_email}</DataList.ItemValue>
|
||||||
</DataList.Item>
|
</DataList.Item>
|
||||||
)}*/}
|
)}*/}
|
||||||
|
{order.shipping.method &&
|
||||||
<DataList.Item pt="4">
|
<DataList.Item pt="4">
|
||||||
<DataList.ItemLabel>
|
<DataList.ItemLabel>
|
||||||
<Badge colorPalette="teal" variant="solid">
|
<Badge colorPalette="teal" variant="solid">
|
||||||
@@ -72,7 +73,7 @@ const OrderSummary = ({ orderData, loading, order }) => {
|
|||||||
</Badge>
|
</Badge>
|
||||||
</DataList.ItemLabel>
|
</DataList.ItemLabel>
|
||||||
<DataList.ItemValue>{formatCurrency(order.shipping.total, orderData.currency)}</DataList.ItemValue>
|
<DataList.ItemValue>{formatCurrency(order.shipping.total, orderData.currency)}</DataList.ItemValue>
|
||||||
</DataList.Item>
|
</DataList.Item> }
|
||||||
</> }
|
</> }
|
||||||
<DataList.Item pt="4" textStyle="xl">
|
<DataList.Item pt="4" textStyle="xl">
|
||||||
<DataList.ItemLabel><strong>Total Amount:</strong></DataList.ItemLabel>
|
<DataList.ItemLabel><strong>Total Amount:</strong></DataList.ItemLabel>
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
import { Provider } from "@/components/ui/provider"
|
import { Provider } from "@/components/ui/provider"
|
||||||
import { StrictMode } from 'react'
|
import { StrictMode } from 'react'
|
||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import { ChakraProvider } from "@chakra-ui/react";
|
||||||
|
import { system } from "./theme";
|
||||||
import './index.css'
|
import './index.css'
|
||||||
import App from './App.jsx'
|
import App from './App.jsx'
|
||||||
|
import {ThemeProvider} from "next-themes";
|
||||||
|
|
||||||
createRoot(document.getElementById('root')).render(
|
createRoot(document.getElementById('root')).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<Provider>
|
<ChakraProvider value={system}>
|
||||||
|
<ThemeProvider attribute="class" defaultTheme="light" enableSystem={false}>
|
||||||
<App />
|
<App />
|
||||||
</Provider>
|
</ThemeProvider>
|
||||||
|
</ChakraProvider>
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,20 +16,40 @@ const Cancel = () => {
|
|||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
|
|
||||||
const error = searchParams.get('error');
|
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 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 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 = () => {
|
const handleRetryPayment = () => {
|
||||||
// Build the payment URL with original parameters
|
|
||||||
const paymentUrl = new URL('/payment', window.location.origin);
|
const paymentUrl = new URL('/payment', window.location.origin);
|
||||||
|
|
||||||
if (orderId) {
|
// Preserve all original order parameters
|
||||||
paymentUrl.searchParams.set('wc_order_id', orderId);
|
if (orderId) paymentUrl.searchParams.set('wc_order_id', orderId);
|
||||||
// You might want to fetch original order details here
|
if (orderTotal) paymentUrl.searchParams.set('total', orderTotal);
|
||||||
paymentUrl.searchParams.set('total', '25.99'); // This should come from order data
|
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();
|
window.location.href = paymentUrl.toString();
|
||||||
};
|
};
|
||||||
@@ -41,7 +61,7 @@ const Cancel = () => {
|
|||||||
<Alert.Content>
|
<Alert.Content>
|
||||||
<Alert.Title>Payment Cancelled</Alert.Title>
|
<Alert.Title>Payment Cancelled</Alert.Title>
|
||||||
<Alert.Description>
|
<Alert.Description>
|
||||||
<Text>Your payment was cancelled. You can try again or choose a different payment method.</Text>
|
<Text>{getErrorMessage()}</Text>
|
||||||
</Alert.Description>
|
</Alert.Description>
|
||||||
</Alert.Content>
|
</Alert.Content>
|
||||||
</Alert.Root>
|
</Alert.Root>
|
||||||
@@ -63,6 +83,13 @@ const Cancel = () => {
|
|||||||
<strong>Order ID:</strong>
|
<strong>Order ID:</strong>
|
||||||
<span className="badge bg-secondary ms-2">{orderId}</span>
|
<span className="badge bg-secondary ms-2">{orderId}</span>
|
||||||
<br/>
|
<br/>
|
||||||
|
{orderTotal && (
|
||||||
|
<>
|
||||||
|
<strong>Order Total:</strong>
|
||||||
|
<span className="ms-2">{formatCurrency(orderTotal, currency)}</span>
|
||||||
|
<br/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<small className="mt-2 d-block">
|
<small className="mt-2 d-block">
|
||||||
Your order is still pending. You can complete the payment to process your order.
|
Your order is still pending. You can complete the payment to process your order.
|
||||||
</small>
|
</small>
|
||||||
@@ -121,7 +148,7 @@ const Cancel = () => {
|
|||||||
<Accordion.ItemIndicator/>
|
<Accordion.ItemIndicator/>
|
||||||
</Accordion.ItemTrigger>
|
</Accordion.ItemTrigger>
|
||||||
<Accordion.ItemContent>
|
<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.ItemContent>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
</Accordion.Root>
|
</Accordion.Root>
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ const Payment = () => {
|
|||||||
<Grid
|
<Grid
|
||||||
templateColumns={{ base: "1fr", md: "repeat(3, 1fr)" }}
|
templateColumns={{ base: "1fr", md: "repeat(3, 1fr)" }}
|
||||||
templateRows="repeat(1, 1fr)"
|
templateRows="repeat(1, 1fr)"
|
||||||
gap="6"
|
// gap="6"
|
||||||
>
|
>
|
||||||
<GridItem colSpan={2}>
|
<GridItem colSpan={2}>
|
||||||
<Center>
|
<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