My /api/orders is not getting found. I had the same approach for users and products and they worked. I am following BradTraversy's Mern Ecommerce from scratch. This is his github repo but this is mostly outdated. https://github.com/bradtraversy/proshop_mern
This is my actions file
import {
ORDER_CREATE_REQUEST,
ORDER_CREATE_SUCCESS,
ORDER_CREATE_FAIL,
} from '../constants/orderConstants'
import axios from 'axios'
export const createOrder = (order) => async (dispatch, getState) => {
try {
dispatch({
type: ORDER_CREATE_REQUEST,
})
const {
userLogin: { userInfo },
} = getState()
const config = {
headers: {
Content_Type: 'application/json',
Authorization: `Bearer ${userInfo.token}`,
},
}
const { data } = await axios.post('/api/products', order, config)
dispatch({
type: ORDER_CREATE_SUCCESS,
payload: data,
})
localStorage.setItem('userInfo', JSON.stringify(data))
} catch (error) {
dispatch({
type: ORDER_CREATE_FAIL,
payload: error.response?.data.message
? error.response.data.message
: error.message,
})
}
}
This is the placeorderscreen
import React, { useEffect } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import {
Button,
Row,
Col,
ListGroup,
Image,
Card,
ListGroupItem,
} from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import Message from '../components/Message'
import CheckoutSteps from '../components/CheckoutSteps'
import { createOrder } from '../actions/orderActions.js'
const PlaceOrderScreen = () => {
const navigate = useNavigate()
const dispatch = useDispatch()
const cart = useSelector((state) => state.cart)
// to the end of prices
const addDecimals = (num) => {
return (Math.round(num * 100) / 100).toFixed(2)
}
// calculate prices
cart.itemsPrice = addDecimals(
cart.cartItems.reduce((acc, item) => acc + item.price * item.qty, 0)
)
cart.shippingPrice = addDecimals(cart.itemsPrice > 100 ? 0 : 100)
cart.taxPrice = addDecimals(Number((0.07 * cart.itemsPrice).toFixed(2)))
cart.totalPrice = (
Number(cart.itemsPrice) +
Number(cart.shippingPrice) +
Number(cart.taxPrice)
).toFixed(2)
// get order from the state
const orderCreate = useSelector((state) => state.orderCreate)
const { order, success, error } = orderCreate
// undefined no order created
console.log(orderCreate.order)
useEffect(() => {
if (success) {
navigate(`/order/${order._id}`)
}
// eslint-disable-next-line
}, [navigate, success])
// after click placeOrder button we would fire the create order which will take us to
orderActions
const placeOrderHandler = () => {
dispatch(
// it's going to pass it through the state and we need to grab it
createOrder({
orderItems: cart.cartItems,
shippingAddress: cart.shippingAddress,
paymentMethod: cart.paymentMethod,
itemsPrice: cart.itemsPrice,
shippingPrice: cart.shippingPrice,
taxPrice: cart.taxPrice,
totalPrice: cart.totalPrice,
})
)
}
return (
<>
<CheckoutSteps step1 step2 step3 step4 />
<Row>
<Col md={8}>
<ListGroup variant='flush'>
<ListGroupItem>
<h2>Shipping</h2>
<p>
<strong>Address:</strong>
{cart.shippingAddress.address}, {cart.shippingAddress.city}{' '}
{cart.shippingAddress.postalCode},{' '}
{cart.shippingAddress.country}
</p>
</ListGroupItem>
<ListGroupItem>
<h2>Payment Method</h2>
{/* <p> */}
<strong>Method:</strong>
{cart.paymentMethod}
{/* </p> */}
</ListGroupItem>
<ListGroupItem>
<h2>Order Items</h2>
{cart.cartItems.length === 0 ? (
<Message>Your Cart is Empty</Message>
) : (
<ListGroup variant='flush'>
{cart.cartItems.map((item, index) => (
<ListGroupItem key={index}>
<Row>
<Col md={1}>
<Image
src={item.image}
alt={item.name}
fluid
rounded
/>
</Col>
<Col>
<Link to={`/product/${item.product}`}>
{item.name}
</Link>
</Col>
<Col md={4}>
{item.qty} x ${item.price} = ${item.qty * item.price}
</Col>
</Row>
</ListGroupItem>
))}
</ListGroup>
)}
</ListGroupItem>
</ListGroup>
</Col>
<Col md={4}>
<Card>
<ListGroup variant='flush'>
<ListGroupItem>
<h2>Order Summary</h2>
</ListGroupItem>
<ListGroupItem>
<Row>
<Col>Items</Col>
<Col>${cart.itemsPrice}</Col>
</Row>
</ListGroupItem>
<ListGroupItem>
<Row>
<Col>Shipping</Col>
<Col>${cart.shippingPrice}</Col>
</Row>
</ListGroupItem>
<ListGroupItem>
<Row>
<Col>Tax</Col>
<Col>${cart.taxPrice}</Col>
</Row>
</ListGroupItem>
<ListGroupItem>
<Row>
<Col>Total</Col>
<Col>${cart.totalPrice}</Col>
</Row>
</ListGroupItem>
<ListGroupItem>
{error && <Message variant='danger'>{error}</Message>}
</ListGroupItem>
<ListGroupItem className='d-grid gap-2'>
<Button
type='button'
disabled={cart.cartItems.length === 0}
onClick={placeOrderHandler}
>
Place Order
</Button>
</ListGroupItem>
</ListGroup>
</Card>
</Col>
</Row>
</>
)
}
export default PlaceOrderScreen
This is the store js
import {
configureStore,
combineReducers,
applyMiddleware,
} from '@reduxjs/toolkit'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'
// Reducers import
import {
productListReducer,
productDetailsReducer,
} from './reducers/productReducers.js'
import { cartReducer } from './reducers/cartReducers.js'
import {
userLoginReducer,
userRegisterReducer,
userDetailsReducer,
userUpdateProfileReducer,
} from './reducers/userReducers'
import { orderCreateReducer } from './reducers/orderReducers'
const reducer = combineReducers({
productList: productListReducer,
productDetails: productDetailsReducer,
cart: cartReducer,
userLogin: userLoginReducer,
userRegister: userRegisterReducer,
userDetails: userDetailsReducer,
userUpdateProfile: userUpdateProfileReducer,
orderCreate: orderCreateReducer,
})
// getting data from local storage
const cartItemsFromStorage = localStorage.getItem('cartItems')
? JSON.parse(localStorage.getItem('cartItems'))
: []
const userInfoFromStorage = localStorage.getItem('userInfo')
? JSON.parse(localStorage.getItem('userInfo'))
: null
const shippingAddressFromStorage = localStorage.getItem('shippingAddress')
? JSON.parse(localStorage.getItem('shippingAddress'))
: {}
//initial state
const initialState = {
cart: {
cartItems: cartItemsFromStorage,
shippingAddress: shippingAddressFromStorage,
},
userLogin: {
userInfo: userInfoFromStorage,
},
}
const middleware = [thunk]
const store = configureStore({
initialState,
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware(
{
serializableCheck: {
immutableCheck: false,
serializableCheck: false,
},
},
composeWithDevTools(applyMiddleware(...middleware))
),
})
export default store

In your code you're doing this in createOrder action.
it should be
this instead. You need to post to
/api/ordersand not the products