Jay*_*Kay 2 stripe-payments reactjs react-redux next.js vercel
我的本地主机上的条带结帐会话工作正常,但是当我尝试从部署的网站的结帐页面重定向时,出现错误。
我认为错误来自的代码:
/src/pages/checkout.js
import { useSession } from "next-auth/client";
import Image from "next/image";
import { useSelector } from "react-redux";
import CheckoutProduct from "../components/CheckoutProduct";
import Header from "../components/Header";
import Currency from "react-currency-formatter";
import { selectItems, selectTotal } from "../slices/basketSlice";
import { loadStripe } from "@stripe/stripe-js";
import axios from "axios";
const stripePromise = loadStripe(process.env.stripe_public_key);
function checkout() {
const items = useSelector(selectItems);
const total = useSelector(selectTotal);
const [session] = useSession();
const createCheckoutSession = async () => {
const stripe = await stripePromise;
// call the backend to create a checkout session
const checkoutSession = await axios.post("/api/create-checkout-session", {
items: items,
email: session.user.email,
});
// redirect customers to stripe checkout
const result = await stripe.redirectToCheckout({
sessionId: checkoutSession.data.id,
});
if (result.error) {
alert(result.error.message);
}
};
return (
<div className="h-screen">
<Header />
<main className="lg:flex flex-1 overflow-y-auto max-w-screen-2xl mx-auto">
{/* Left side */}
<div className="flex-grow m-5 shadow-sm">
<Image
src="/images/amazon-cart.jpg"
width={1020}
height={250}
objectFit="contain"
/>
<div className="fex flex-col p-5 space-y-10 bg-white">
<h1 className="text-3xl border-b pb-4">
{items.length === 0
? "Your Amazon basket is empty"
: "Shopping Basket"}
</h1>
{items.map((item, i) => (
<CheckoutProduct
key={i}
id={item.id}
title={item.title}
rating={item.rating}
price={item.price}
description={item.description}
category={item.category}
image={item.image}
hasPrime={item.hasPrime}
/>
))}
</div>
</div>
{/* Right side */}
<div className="flex flex-col bg-white p-10 shadow-md">
{items.length > 0 && (
<>
<h2 className="whitespace-nowrap">
Subtotal ({items.length} items):
<span className="font-bold">
<Currency quantity={total} currency="EUR" />
</span>
</h2>
<button
role="link"
onClick={createCheckoutSession}
disabled={!session}
className={`button mt-2 ${
!session &&
"from-gray-300 to-gray-500 border-gray-200 text-gray-300 cursor-not-allowed"
}`}
>
{!session ? "Sign in to Checkout" : "Proceed to Checkout"}
</button>
</>
)}
</div>
</main>
</div>
);
}
export default checkout;
Run Code Online (Sandbox Code Playgroud)
/next.config.js
module.exports = {
env: {
stripe_public_key: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
},
};
Run Code Online (Sandbox Code Playgroud)
我的环境变量也部署在 Vercel 上,命名约定如下:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_mykey
# Stripe Terminal/CLI
STRIPE_WEBHOOK_SECRET=whsec_mywebhooksecret
STRIPE_SECRET_KEY=sk_test_mysecret
Run Code Online (Sandbox Code Playgroud)
/src/pages/api/create-checkout-session.js
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
export default async (req, res) => {
const { items, email } = req.body;
// console.log(items);
// console.log(email);
const transformedItems = items.map((item) => ({
price_data: {
currency: "eur",
product_data: {
name: item.title,
images: [item.image],
},
unit_amount: item.price * 100,
},
description: item.description,
quantity: 1,
}));
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
shipping_rates: ["shr_1JPZN2HHQ2qhqkUCKLyMJDLO"],
shipping_address_collection: {
allowed_countries: ["GB", "US", "CA", "DE"],
},
line_items: transformedItems,
mode: "payment",
success_url: `${process.env.HOST}/success`,
cancel_url: `${process.env.HOST}/checkout`,
metadata: {
email,
images: JSON.stringify(items.map((item) => item.image)),
},
});
res.status(200).json({ id: session.id });
};
Run Code Online (Sandbox Code Playgroud)
/src/pages/api/webhook.js
import { buffer } from "micro";
import * as admin from "firebase-admin";
// secure a connection to FIREBASE from backend
const serviceAccount = require("../../../permissions.json");
const app = !admin.apps.length
? admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
})
: admin.app();
// Establish connection to stripe
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
const fullfillOrder = async (session) => {
//console.log("Fulfilling order", session);
return app
.firestore()
.collection("users")
.doc(session.metadata.email)
.collection("orders")
.doc(session.id)
.set({
amount: session.amount_total / 100,
amount_shipping: session.total_details.amount_shipping / 100,
images: JSON.parse(session.metadata.images),
timestamp: admin.firestore.FieldValue.serverTimestamp(),
customer_email: session.customer_details.email,
})
.then(() => {
console.log(`SUCCESS: Order ${session.id} has been added to DB`);
});
};
export default async (req, res) => {
if (req.method === "POST") {
const requestBuffer = await buffer(req);
const payload = requestBuffer.toString();
const sig = req.headers["stripe-signature"];
let event;
// verify that the event posted came from stripe
try {
event = stripe.webhooks.constructEvent(payload, sig, endpointSecret);
} catch (error) {
console.log("ERROR while constructing event", error.message);
return res
.status(400)
.send(`Webhook error while constructing event:${error.message}`);
}
// Handle checkout.session.completed event
if (event.type === "checkout.session.completed") {
const session = event.data.object;
// fulfill the order...
return fullfillOrder(session)
.then(() => res.status(200))
.catch((err) => {
console.log("ERROR while fulfilling order", err.message);
res
.status(400)
.send(`Webhook Error while fulfilling order: ${err.message}`);
});
}
}
};
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
Run Code Online (Sandbox Code Playgroud)
该应用程序托管在 Vercel 上。使用 Next.js / React / Redux 创建。连接到 Firebase / Stripe,我使用 Axios。
这段代码是错误的根源吗?理解此错误最困难的部分是我的应用程序在本地主机中运行得很好,控制台中所有页面上的问题为零,但在部署的网站上出现了此错误。
我的代码的哪一部分可能是错误的?我希望能够单击该按钮并进入 Stripe 结账页面。
小智 8
代替 ...
const stripePromise = loadStripe(process.env.stripe_public_key);
和 ...
const stripePromise = loadStripe(`${process.env.stripe_public_key}');
...希望对您有帮助。
| 归档时间: |
|
| 查看次数: |
3386 次 |
| 最近记录: |