Node.js 单击“使用节点付款”和“快速付款”后,未返回成功消息
我目前正在使用带条带支付API的ReactJS、node和express。单击“支付”按钮并输入虚拟信用卡凭据后,页面将不处理支付。我已经输入了从仪表板获得的正确的发布密钥和api密钥。我相信这可能与我需要添加到server.js文件(又名节点后端)中的内容有关。我已经阅读了文档,以获得任何线索。也在这里搜索了堆栈溢出。没有一个问题和我想问的一样。请参阅下面的图片和代码。谢谢 这是在按下按钮之前。请注意右侧的控制台。 这是在按下按钮之后。加载微调器将永远显示。还要注意右侧的控制台Node.js 单击“使用节点付款”和“快速付款”后,未返回成功消息,node.js,reactjs,express,stripe-payments,stripe-api,Node.js,Reactjs,Express,Stripe Payments,Stripe Api,我目前正在使用带条带支付API的ReactJS、node和express。单击“支付”按钮并输入虚拟信用卡凭据后,页面将不处理支付。我已经输入了从仪表板获得的正确的发布密钥和api密钥。我相信这可能与我需要添加到server.js文件(又名节点后端)中的内容有关。我已经阅读了文档,以获得任何线索。也在这里搜索了堆栈溢出。没有一个问题和我想问的一样。请参阅下面的图片和代码。谢谢 这是在按下按钮之前。请注意右侧的控制台。 这是在按下按钮之后。加载微调器将永远显示。还要注意右侧的控制台 //pro
//provate.js
从“React”导入React;
导入“/Donate.css”;
从“@stripe/stripe js”导入{loadStripe};
从“@stripe/react stripe js”导入{Elements}”;
从“/CheckoutForm”导入CheckoutForm;
//确保在组件渲染外部调用'loadStripe',以避免
//在每个渲染上重新创建“条带”对象。
常量条带=加载条带(
“主键*****************************”
);
条带。然后((数据)=>{
控制台日志(数据);
});
常数=()=>{
返回(
现在捐赠
);
};
出口违约金;
//检查口
从“React”导入React,{useState,useffect};
从“@stripe/react stripe js”导入{CardElement,useStripe,useElements};
导入“/CheckoutForm.css”;
导出默认函数CheckoutForm(){
const[successed,setSucceeded]=使用状态(false);
const[error,setError]=useState(null);
const[processing,setProcessing]=useState(“”);
const[disabled,setDisabled]=使用状态(true);
const[clientSecret,setClientSecret]=useState(“”);
常量stripe=useStripe();
常量元素=useElements();
useffect(()=>{
//页面加载后立即创建PaymentIntent
窗口
.fetch(“/捐赠”{
方法:“张贴”,
标题:{
“内容类型”:“应用程序/json”,
接受:“应用程序/json”,
},
body:JSON.stringify({items:[{id:'xl tshirt}]}),
})
。然后((res)=>{
返回res.json();
})
。然后((数据)=>{
setClientSecret(data.clientSecret);
});
}, []);
常数cardStyle={
风格:{
基数:{
颜色:“32325d”,
fontFamily:“Arial,无衬线”,
字体平滑:“抗锯齿”,
字体大小:“16px”,
“::占位符”:{
颜色:“32325d”,
},
},
无效:{
颜色:“fa755a”,
iconColor:#fa755a“,
},
},
};
const handleChange=async(事件)=>{
//侦听CardElement中的更改
//并在客户键入卡片详细信息时显示任何错误
setDisabled(event.empty);
setError(event.error?event.error.message:);
};
const handleSubmit=异步(ev)=>{
ev.preventDefault();
设置处理(真);
const payload=wait stripe.confirmCardPayment(clientSecret{
付款方式:{
卡片:elements.getElement(CardElement),
},
});
if(有效负载错误){
setError(`Payment failed${payload.error.message}`);
设置处理(假);
}否则{
设置错误(空);
设置处理(假);
设置成功(真);
}
console.log(clientSecret);
};
返回(
{处理?:“支付”}
{/*显示处理付款时发生的任何错误*/}
{错误&&(
{错误}
)}
{/*完成后显示成功消息*/}
付款成功,请在您的帐户中查看结果
{" "}
刷新页面以再次付款。
);
}
//server.js
const express=要求(“express”);
常量app=express();
const{resolve}=require(“路径”);
//这是您真正的测试机密API密钥。
常量条带=需要(“条带”)(
“SKU测试**************************************”
);
应用程序使用(快速静态(“.”);
使用(express.json());
常量calculateOrderAmount=(项)=>{
//用订单金额的计算替换此常量
//计算服务器上的订单总数以防止
//人们不能直接在客户机上操纵金额
返回1400;
};
app.post(“/create payment intent”),异步(请求、回复)=>{
const{items}=req.body;
//使用订单金额和货币创建PaymentIntent
const paymentIntent=wait stripe.paymentIntents.create({
金额:1099,
货币:“美元”,
//通过包含此参数验证您在本指南中的集成
元数据:{集成检查:“接受付款”},
});
res.send({
clientSecret:paymentIntent.client\u secret,
});
});
app.listen(4242,()=>console.log(“节点服务器在端口4242上侦听”);
您需要使用客户端密码查看服务器呼叫/网络响应。控制台错误表示您向confirmCardPayment
提供了无效的密码,显然是一个空字符串
您指定:。
您的应用程序似乎没有按预期通过setClientSecret
设置状态,您最终得到的是useState(“”)中的初始空字符串值代码>
在调用confirmCardPayment
之前,检查您的client\u secret
值,然后后退一步查找该值的删除位置
// Donate.js
import React from "react";
import "./Donate.css";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import CheckoutForm from "./CheckoutForm";
// Make sure to call `loadStripe` outside of a component’s render to avoid
// recreating the `Stripe` object on every render.
const stripe = loadStripe(
"pk*****************************"
);
stripe.then((data) => {
console.log(data);
});
const Donate = () => {
return (
<div className="donate">
<h1 className="donate__sectionHeader">Donate Now</h1>
<Elements stripe={stripe}>
<CheckoutForm />
</Elements>
</div>
);
};
export default Donate;
//CheckoutForm
import React, { useState, useEffect } from "react";
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
import "./CheckoutForm.css";
export default function CheckoutForm() {
const [succeeded, setSucceeded] = useState(false);
const [error, setError] = useState(null);
const [processing, setProcessing] = useState("");
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState("");
const stripe = useStripe();
const elements = useElements();
useEffect(() => {
// Create PaymentIntent as soon as the page loads
window
.fetch("/donate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({ items: [{ id: "xl-tshirt" }] }),
})
.then((res) => {
return res.json();
})
.then((data) => {
setClientSecret(data.clientSecret);
});
}, []);
const cardStyle = {
style: {
base: {
color: "#32325d",
fontFamily: "Arial, sans-serif",
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#32325d",
},
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a",
},
},
};
const handleChange = async (event) => {
// Listen for changes in the CardElement
// and display any errors as the customer types their card details
setDisabled(event.empty);
setError(event.error ? event.error.message : "");
};
const handleSubmit = async (ev) => {
ev.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
});
if (payload.error) {
setError(`Payment failed ${payload.error.message}`);
setProcessing(false);
} else {
setError(null);
setProcessing(false);
setSucceeded(true);
}
console.log(clientSecret);
};
return (
<form id="payment-form" onSubmit={handleSubmit}>
<CardElement
id="card-element"
options={{ hidePostalCode: true, cardStyle }}
onChange={handleChange}
/>
<button disabled={processing || disabled || succeeded} id="submit">
<span id="button-text">
{processing ? <div className="spinner" id="spinner"></div> : "Pay"}
</span>
</button>
{/* Show any error that happens when processing the payment */}
{error && (
<div className="card-error" role="alert">
{error}
</div>
)}
{/* Show a success message upon completion */}
<p className={succeeded ? "result-message" : "result-message hidden"}>
Payment succeeded, see the result in your
<a href={`https://dashboard.stripe.com/test/payments`}>
{" "}
Stripe dashboard.
</a>{" "}
Refresh the page to pay again.
</p>
</form>
);
}
//server.js
const express = require("express");
const app = express();
const { resolve } = require("path");
// This is your real test secret API key.
const stripe = require("stripe")(
"sk_test_**********************************"
);
app.use(express.static("."));
app.use(express.json());
const calculateOrderAmount = (items) => {
// Replace this constant with a calculation of the order's amount
// Calculate the order total on the server to prevent
// people from directly manipulating the amount on the client
return 1400;
};
app.post("/create-payment-intent", async (req, res) => {
const { items } = req.body;
// Create a PaymentIntent with the order amount and currency
const paymentIntent = await stripe.paymentIntents.create({
amount: 1099,
currency: "usd",
// Verify your integration in this guide by including this parameter
metadata: { integration_check: "accept_a_payment" },
});
res.send({
clientSecret: paymentIntent.client_secret,
});
});
app.listen(4242, () => console.log("Node server listening on port 4242!"));