我使用 next js 构建了一个电子商务网站。我使用 Strapi 作为 cms,使用 stripe 作为支付网关。所以在 Strapi 后端应用程序中我添加了 api 来进行支付操作。这是代码
'use strict';
// @ts-ignore
const stripe = require('stripe')(process.env.STIPE_SECRET_KEY);
/**
* order controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::order.order', ({ strapi }) => ({
async create(ctx) {
// @ts-ignore
const { products } = ctx.request.body;
const lineItems = await Promise.all(
products.map(async (product) => {
const item = await strapi
.service("api::product.product")
.findOne(product.id);
return {
price_data: {
currency: "cad",
product_data: {
name: item.title,
},
unit_amount: item.price * 100,
},
quantity: item.quantity,
};
})
);
try {
const session = await stripe.checkout.sessions.create({
shipping_address_collection: { allowed_countries: ['US', 'CA'] },
payment_method_types: ["card"],
mode: "payment",
success_url:`${process.env.CLIENT_URL}?success=true`,
cancel_url: `${process.env.CLIENT_URL}??success=false`,
line_items: lineItems,
});
await strapi.service("api::order.order").create({ data: { products, stripeId: session.id } });
return { stripeSession: session };
} catch (error) {
ctx.response.status = 500;
return { error };
}
}
}));
然后在客户端,如果用户单击结账按钮,这是处理提交的函数
const stripePromise = loadStripe(
"pk_test_51P2oOLKBSRV7dryrpTP3KRN4DZKqvqj7B9cgBPib65JdpIZa5g9i2QTP8VruvddPl5zG8dq7OAa4fIoUGG8f7Ido00hVKbRT1R"
);
const handlePayment = async () => {
try {
const stripe = await stripePromise;
const res = await makeRequest.post("/orders", {
products: cartItemList,
});
await stripe.redirectToCheckout({
sessionId: res.data.stripeSession.id,
});
} catch (err) {
console.log(err);
}
};
我期待去条纹结账页面。但它没有重定向到那里。但显示此错误
Axios错误{ message: '请求失败,状态码 401', name: 'AxiosError', 代码:'ERR_BAD_REQUEST', 配置:{ 过渡:{ SilentJSONParsing: true, 强制JSON解析:true, 澄清超时错误:假 }, 适配器:['xhr','http'], 变换请求:[0:λ:变换请求], 变换响应:[0:λ:变换响应], 超时:0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', 最大内容长度:-1, 最大主体长度:-1, 环境:{}, 标题:AxiosHeaders { 接受:'application/json,text/plain,/', '内容类型':'应用程序/json', 授权:“未定义承载者” }, baseURL: 'http://localhost:1337/api', 方法:'发布', url: '/订单', 数据: '{"产品":[{"名称":"马萨尔绿一号","数量":3,"金额":270,"图片":"/uploads/Rectangle_90_84c9813ece.png","实际价格":100," id":32,"产品":1}]}' }, 请求:XMLHttpRequest { onreadystatechange:空, 就绪状态:4, 超时:0, withCredentials:假, 上传:XMLHttpRequestUpload { 加载开始:空, 进行中:空, 中止:空, 错误:空, 加载:空, 超时:空, 加载结束:空 }, 响应URL: 'http://localhost:1337/api/orders', 状态:401, statusText: '未经授权', 响应类型:'', 回复: '{"data":null,"error":{"status":401,"name":"UnauthorizedError","message":"凭据缺失或无效","details":{}}}', 响应文本: '{“data”:null,“error”:{“status”:401,“name”:“UnauthorizedError”,“message”:“凭据丢失或无效”,“details”:{}}}',
这似乎是您的客户端和您自己的 API 之间的授权错误。也就是说,您对自己的
POST
端点的 /orders
请求似乎缺少一些预期的凭据。您需要根据您正在使用的框架和工具来调试该部分。
不过,对于结帐会话有一个注释。会话现在有一个
url
(API 参考),因此您可以自己重定向到该会话,并且不再需要 redirectToCheckout
。事实上,如果您每次都只重定向到结账(并且不在您自己的页面上收集付款详细信息),那么您可能根本不需要 Stripe.js。