我正在尝试在我的数据库中实现分条支付和创建订单。即使我的条纹支付是成功的,我无法在数据库中创建订单。我的实现-购物车:
import './ShoppingCart.css';
import {useSelector} from 'react-redux';
import { useState, useEffect } from 'react';
import {useNavigate }from 'react-router-dom';
import { useDispatch } from 'react-redux';
import StripeCheckout from 'react-stripe-checkout';
import logo from '../images/BritonStore.png';
import {userRequest} from '../requestMethods';
import { Link } from 'react-router-dom';
// const KEY = process.env.REACT_APP_STRIPE;
const ShoppingCart = ({id}) => {
const cart = useSelector(state=>state.cart);
const [stripeToken, setStripeToken] = useState(null);
const history = useNavigate();
const user = JSON.parse(localStorage.getItem("persist:root"))?.user;
const currentUser = user && JSON.parse(user).currentUser;
const TOKEN = currentUser?.accessToken;
// console.log(TOKEN)
const width = window.innerWidth;
const onToken = (token) => {
setStripeToken(token);
};
useEffect(()=>{
const makeRequest = async ()=>{
try{
const res = await userRequest.post("/checkout/pay", {
tokenId:stripeToken.id,
amount: cart.total,
});
console.log(res)
history('/success', {stripeData: res.data, products: cart});
}catch(err){
console.log(err)
}
};
stripeToken && makeRequest();
}, [stripeToken, cart.total, history])
return (
<div>
{cart.products.length === 0 && width < 451 ?
<div className='emt-cart'>
<div className="emt-wrapper">
<h2 className="emt-header">Your Bag is Empty.</h2>
<div id="sc-empty-cart-animated-image" type="image/svg+xml" data="https://m.media-amazon.com/images/G/02/cart/empty/animated/rolling-cart-desaturated._CB405717979_.svg">
<img alt="" src="https://m.media-amazon.com/images/G/02/cart/empty/animated/cart-fallback-desaturated._CB405717979_.svg"/>
</div>
</div>
</div>
:
cart.products.length === 0 && width > 451 ?
<div className="emt-pc-wrapper">
<div className='emt-pc'>
<img src="https://m.media-amazon.com/images/G/02/cart/empty/kettle-desaturated._CB424695504_.svg" alt="" />
<div className="emt-pc-text">
<h2>Your Bag is Empty</h2>
<Link to='/store'>Continue Shopping</Link>
</div>
</div>
</div>
:
<div className='cartscreen'>
<div className='cartscreen-title'>
<h2>Review your bag.</h2>
<p>Free delivery and free returns</p>
</div>
{cart.products.map(product=>(
<div className='cart' key={cart.products.id}>
<div className='image'>
<img src={product.image} key={product._id}/>
</div>
<div className='details'>
<div className='title'>
<h3>{product.title}</h3>
<p>Product ID: {product._id}</p>
</div>
<div className='quantity'>
<p>Quantity: {product.quantity}</p>
</div>
<div className='total-price'>
<p>{product.price*product.quantity}$</p>
<p>Remove</p>
</div>
</div>
</div>
))}
<div className='total'>
<div className='left'>
<p>Subtotal</p>
<p>Shipping</p>
</div>
<div className='right'>
<p> {cart.total} $</p>
<p>Free</p>
</div>
</div>
<div className='f-total'>
<h4>Total</h4>
<h4> {cart.total} $</h4>
</div>
<div className='checkout'>
<div className='method'>
<h3>How would you like to checkout ?</h3>
</div>
</div>
<div className='method-cards'>
<div className='card'>
<h2>Proceed To Checkout</h2>
{TOKEN ? <StripeCheckout
name='Store'
image={logo}
billingAddress
shippingAddress
description={`Your total is $${cart.total}`}
amount={cart.total*100}
token={onToken}
stripeKey={"pk_test_51KLN11ITl57zrxjuYSYut39BpN1qKSqcUWCksXqFXJU95FxSIei4O4Lfb4BrH4Rc7hWN7rZRy7sbz2J7QCC08QSf00AwpDVnBB"}
>
<button className='btn-payment'>Pay Now!</button>
</StripeCheckout> : <p className='login-wrng'>Please <Link to='/login'>Login</Link> to continue payment</p>}
{TOKEN ? <p className='payment-methods'>We accept payments from PayPal, Visa, MasterCard</p> : null}
</div>
</div>
</div>}
</div>
)
}
export default ShoppingCart
成功屏幕/创建订单屏幕:我认为问题在[ const data = location.state.stripeData; const cart = location.state.cart;]
行。屏幕变为空白,控制台显示“无法读取未定义的stripeData的属性。”location = useLocation()返回状态null。
import React, {useState, useEffect} from 'react';
import { useLocation } from 'react-router';
import {useSelector} from 'react-redux';
import { userRequest } from '../requestMethods';
const Success = () => {
const location = useLocation();
const data = location.state.stripeData;
const cart = location.state.cart;
const currentUser = useSelector((state) => state.user.currentUser);
const [orderId, setOrderId] = useState(null);
useEffect(() => {
const createOrder = async () => {
try {
const res = await userRequest.post("/orders", {
userId: currentUser._id,
products: cart.products.map((item) => ({
productId: item._id,
quantity: item._quantity,
})),
amount: cart.total,
address: data.billing_details.address,
});
setOrderId(res.data._id);
} catch(err) {
console.log(err)
}
};
data && createOrder();
}, [cart, data, currentUser]);
return (
<div>
{orderId
? `Order has been created successfully. Your order number is ${orderId}`
: `Failed...`}
</div>
)
}
export default Success
订单模型-
const mongoose = require('mongoose');
const orderSchema = new mongoose.Schema(
{
userId: {type: String, required: true, unique:true},
products: [
{
productId: {type: String},
quantity: {type: Number, default: 1},
},
],
amount: {type:Number, required:true},
address: { type: Object, required:true },
status: {type: String, default: 'pending'},
}, {timestamps: true}
);
module.exports = mongoose.model('Order', orderSchema);
订购路线-
const Order = require("../models/Order");
const {
verifyToken,
verifyTokenAndAuthorization,
verifyTokenAndAdmin,
} = require("./verifyToken");
const router = require("express").Router();
//CREATE
router.post("/", verifyToken, async (req, res) => {
const newOrder = new Order(req.body);
try {
const savedOrder = await newOrder.save();
res.status(200).json(savedOrder);
} catch (err) {
res.status(500).json(err);
}
});
2条答案
按热度按时间ecfsfe2w1#
1.创建orderRedux.js
1.然后我们在apiCalls.js中创建一个函数来调用redux
1.然后在ShoppingCart脚本中,
1.支付成功后,调用我们创建的函数addOrder
在success脚本的最后,从API获取请求。我希望这个解决方案能帮助你
5ktev3wc2#
我不知道你是否解决了这个问题,但我相信别人会觉得我的答案很有价值。从react-router-dom v6开始,useHistory()钩子被useNavigate()取代。你需要使用useNavigate()而不是useNHistory()。所以你的代码应该是这样的:
从“react-router-dom”导入{ useNavigate }
const navigate = useNavigate()
... navigate(“/success”,{state:{data:res.data})
这是一种新的方式,我希望你能理解我的解决方案,并在你的代码中实现它。