//api/Keys/paypal.js
import { getSession } from \'next-auth/react\'; const handler = async (req, res) => { const session = await getSession({ req }); if (!session) { return res.status(401).send(\'signin required\'); } res.send(process.env.PAYPAL_CLIENT_ID || \'sb\'); }; export default handler;
import axios from \'axios\'; import Image from \'next/image\'; import Link from \'next/link\'; import { useRouter } from \'next/router\'; import { useEffect, useReducer } from \'react\'; import Layout from \'../../components/Layout\'; import { getError } from \'../../utils/error\'; import { PayPalButtons, usePayPalScriptReducer } from \'@paypal/react-paypal-js\'; import { toast } from \'react-toastify\'; function reducer(state, action) { switch (action.type) { case \'FETCH_REQUEST\': return { ...state, loading: true, error: \'\' }; case \'FETCH_SUCCESS\': return { ...state, loading: false, order: action.payload, error: \'\' }; case \'FETCH_FAIL\': return { ...state, loading: false, error: action.payload }; case \'PAY_REQUEST\': return { ...state, loadingPay: true }; case \'PAY_SUCCESS\': return { ...state, loadingPay: false, successPay: true }; case \'PAY_FAIL\': return { ...state, loadingPay: false, errorPay: action.payload }; case \'PAY_RESET\': return { ...state, loadingPay: false, successPay: false, errorPay: \'\' }; default: state; } } function OrderScreen() { // order/:id const [{ isPending }, paypalDispatch] = usePayPalScriptReducer(); const { query } = useRouter(); const orderId = query.id; const [{ loading, error, order, successPay, loadingPay }, dispatch] = useReducer(reducer, { loading: true, order: {}, error: \'\', }); useEffect(() => { const fetchOrder = async () => { try { dispatch({ type: \'FETCH_REQUEST\' }); const { data } = await axios.get(`/api/orders/${orderId}`); dispatch({ type: \'FETCH_SUCCESS\', payload: data }); } catch (err) { dispatch({ type: \'FETCH_FAIL\', payload: getError(err) }); } }; if (!order._id || successPay || (order._id && order._id !== orderId)) { fetchOrder(); if (successPay) { dispatch({ type: \'PAY_RESET\' }); } } else { const loadPaypalScript = async () => { const { data: clientId } = await axios.get(\'/api/keys/paypal\'); paypalDispatch({ type: \'resetOptions\', value: { \'client-id\': clientId, currency: \'USD\', }, }); paypalDispatch({ type: \'setLoadingStatus\', value: \'pending\' }); }; loadPaypalScript(); } }, [order, orderId, paypalDispatch, successPay]); const { shippingAddress, paymentMethod, orderItems, itemsPrice, taxPrice, shippingPrice, totalPrice, isPaid, paidAt, isDelivered, deliveredAt, } = order; function createOrder(data, actions) { return actions.order .create({ purchase_units: [ { amount: { value: totalPrice }, }, ], }) .then((orderID) => { return orderID; }); } function onApprove(data, actions) { return actions.order.capture().then(async function (details) { try { dispatch({ type: \'PAY_REQUEST\' }); const { data } = await axios.put( `/api/orders/${order._id}/pay`, details ); dispatch({ type: \'PAY_SUCCESS\', payload: data }); toast.success(\'Order is paid successgully\'); } catch (err) { dispatch({ type: \'PAY_FAIL\', payload: getError(err) }); toast.error(getError(err)); } }); } function onError(err) { toast.error(getError(err)); } return ( <Layout title={`Order ${orderId}`}> <h1 className=\"mb-4 text-xl\">{`Order ${orderId}`}</h1> {loading ? ( <div>Loading...</div> ) : error ? ( <div className=\"alert-error\">{error}</div> ) : ( <div className=\"grid md:grid-cols-4 md:gap-5\"> <div className=\"overflow-x-auto md:col-span-3\"> <div className=\"card p-5\"> <h2 className=\"mb-2 text-lg\">Shipping Address</h2> <div> {shippingAddress.fullName}, {shippingAddress.address},{\' \'} {shippingAddress.city}, {shippingAddress.postalCode},{\' \'} {shippingAddress.country} </div> {isDelivered ? ( <div className=\"alert-success\">Delivered at {deliveredAt}</div> ) : ( <div className=\"alert-error\">Not delivered</div> )} </div> <div className=\"card p-5\"> <h2 className=\"mb-2 text-lg\">Payment Method</h2> <div>{paymentMethod}</div> {isPaid ? ( <div className=\"alert-success\">Paid at {paidAt}</div> ) : ( <div className=\"alert-error\">Not paid</div> )} </div> <div className=\"card overflow-x-auto p-5\"> <h2 className=\"mb-2 text-lg\">Order Items</h2> <table className=\"min-w-full\"> <thead className=\"border-b\"> <tr> <th className=\"px-5 text-left\">Item</th> <th className=\" p-5 text-right\">Quantity</th> <th className=\" p-5 text-right\">Price</th> <th className=\"p-5 text-right\">Subtotal</th> </tr> </thead> <tbody> {orderItems.map((item) => ( <tr key={item._id} className=\"border-b\"> <td> <Link legacyBehavior href={`/product/${item.slug}`}> <a className=\"flex items-center\"> <Image src={item.image} alt={item.name} width={50} height={50} ></Image> {item.name} </a> </Link> </td> <td className=\" p-5 text-right\">{item.quantity}</td> <td className=\"p-5 text-right\">${item.price}</td> <td className=\"p-5 text-right\"> ${item.quantity * item.price} </td> </tr> ))} </tbody> </table> </div> </div> <div> <div className=\"card p-5\"> <h2 className=\"mb-2 text-lg\">Order Summary</h2> <ul> <li> <div className=\"mb-2 flex justify-between\"> <div>Items</div> <div>${itemsPrice}</div> </div> </li>{\' \'} <li> <div className=\"mb-2 flex justify-between\"> <div>Tax</div> <div>${taxPrice}</div> </div> </li> <li> <div className=\"mb-2 flex justify-between\"> <div>Shipping</div> <div>${shippingPrice}</div> </div> </li> <li> <div className=\"mb-2 flex justify-between\"> <div>Total</div> <div>${totalPrice}</div> </div> </li> {!isPaid && ( <li> {isPending ? ( <div>Loading...</div> ) : ( <div className=\"w-full\"> <PayPalButtons createOrder={createOrder} onApprove={onApprove} onError={onError} ></PayPalButtons> </div> )} {loadingPay && <div>Loading...</div>} </li> )} </ul> </div> </div> </div> )} </Layout> ); } OrderScreen.auth = true; export default OrderScreen;
Unhandled Runtime Error
AxiosError: Request failed with status code 404
Call Stack
settle
node_modules\\axios\\lib\\core\\settle.js (19:0)
XMLHttpRequest.onloadend
node_modules\\axios\\lib\\adapters\\xhr.js (103:12)
xhr.js:247 GET http://localhost:3000/api/keys/paypal 404 (Not Found)
settle.js:19 Uncaught (in promise) AxiosError {message: \’Request failed with status code 404\’, name: \’AxiosError\’, code: \’ERR_BAD_REQUEST\’, config: {…}, request: XMLHttpRequest, …}
I have successfully followed and completed all the tutorials up to 25. Pay Order By PayPal.
waleed Posted new comment May 18, 2023

RESOLVED:
LINE 58: const { data: clientId } = await axios.get(‘/api/keys/paypal’);
should be:const { data: clientId } = await axios.get(‘/api/Keys/paypal’);