Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 集成错误条带无效值应为客户端机密字符串。您指定了:未定义_Node.js_Reactjs_Firebase_Stripe Payments - Fatal编程技术网

Node.js 集成错误条带无效值应为客户端机密字符串。您指定了:未定义

Node.js 集成错误条带无效值应为客户端机密字符串。您指定了:未定义,node.js,reactjs,firebase,stripe-payments,Node.js,Reactjs,Firebase,Stripe Payments,我有一个react项目,其中包含nodejs服务器端代码,并实现了stripe。我在本地机器上用测试卡测试了条带代码,效果很好,但当我将其上传到firebase主机并尝试在那里进行测试时,我收到了如下错误“Uncaught(in promise)IntegrationError:stripe的值无效。confirmCardPayment intent secret:值应为客户端密码字符串。您指定了“未定义”。所以我认为nodejs不能上传到firebase,所以我做了云计算,但仍然得到了相同的错

我有一个react项目,其中包含nodejs服务器端代码,并实现了stripe。我在本地机器上用测试卡测试了条带代码,效果很好,但当我将其上传到firebase主机并尝试在那里进行测试时,我收到了如下错误“Uncaught(in promise)IntegrationError:stripe的值无效。confirmCardPayment intent secret:值应为客户端密码字符串。您指定了“未定义”。所以我认为nodejs不能上传到firebase,所以我做了云计算,但仍然得到了相同的错误。我认为这是因为我是如何用URL中的项目位置、项目id和函数名调用API的其余部分的。这是我的服务器端代码

const express = require("express");
const app = express();
const cors = require("cors");
const bodyParser = require("body-parser")
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const stripe = require("stripe")(functions.config().stripe.secret);

app.use(bodyParser.urlencoded({ extended: false }));

// parse application/json
app.use(bodyParser.json());

app.use(cors());

app.post("/", cors(), async (req, res) => {
  try {
    const { email, amount } = req.body;
    const paymentIntent = await stripe.paymentIntents.create({
      amount,
      currency: "usd",
    
      // Verify your integration in this guide by including this parameter
      metadata: { integration_check: "accept_a_payment" },
      receipt_email: email,
    });
    console.log(paymentIntent);
// return res.status(200).json({
//   confirm: "abc123"
// })
    res.status(200).send({ client_secret: paymentIntent["client_secret"] });
  } catch (error) {
    console.log(error);
  }
});


exports.pay = functions.https.onRequest(app);
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions

exports.helloWorld = functions.https.onRequest((request, response) => {
  response.send("hello from jerry")
  console.log("Hello From Jerry");
});

// On sign up.
exports.processSignUp = functions.auth.user().onCreate((user) => {
  // Check if user meets role criteria.
  if (user.email) {
    const customClaims = {
      active: true,
      accessLevel:"paid",
    };
    // Set custom user claims on this newly created user.
    return admin
      .auth()
      .setCustomUserClaims(user.uid, customClaims)
      .then(() => {
        // Update real-time database to notify client to force refresh.
        const metadataRef = admin.database().ref(user.uid);
        // Set the refresh time to the current UTC timestamp.
        // This will be captured on the client to force a token refresh.
        return metadataRef.set({ refreshTime: new Date().getTime() });
      })
      .catch((error) => {
        console.log(error);
      });
  }
});
这是我的代码

 import React, { useState, useEffect } from "react";
import axios from "axios";
// MUI Components
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import TextField from "@material-ui/core/TextField";
import access from "../../assets/icon-5.png";
import { useAuth } from "../../context/AuthContext";
import rocket from "../../assets/rocket.png";
import question from "../../assets/question-mark.png";
import { useHistory } from "react-router-dom";
import { connect } from "react-redux";
import { getProducts } from "../../actions/products";
import Spinner from "../Spinner/Spinner";
import moment from "moment";
import { setAlert } from "../../actions/alert";
import { useStripe, useElements, CardElement } from "@stripe/react-stripe-js";
import { makeStyles } from "@material-ui/core/styles";
import CardInput from "./CardInput";
import "./common.css";
import { Fragment } from "react";

const useStyles = makeStyles({
  root: {
    // maxWidth: 500,
  },
  content: {
    display: "flex",
    flexDirection: "column",
    alignContent: "flex-start",
  },
  div: {
    display: "flex",
    flexDirection: "row",
    alignContent: "flex-start",
    justifyContent: "space-between",
  },
  button: {
    margin: "2em auto 1em",
  },
});

const HomePage = ({ getProducts, products, location, setAlert }) => {
  const history = useHistory();
  const { state } = location;
  console.log(state, "params");
  const { signup } = useAuth();

  const classes = useStyles();
  // State
  const [totalPlan, setPurchaseSummary] = useState({
    total: "19.99",
    planAccess: "",
    start: "",
    end: "",
  });
  const { total, planAccess, start, end } = totalPlan;
  const [loading, setLoading] = useState(true);
  const [planList, setPlan] = useState({
    bronze: "",
    silver: "",
    gold: "",
    platinum: "",
    amount: 0,
  });
  const { bronze, silver, gold, platinum, amount } = planList;

  const [formData, setFormData] = useState({
    email: "",
    password: "",
    confirmPassword: "",
  });
  const { email, customer, password, confirmPassword } = formData;
  const onChange = (e) =>
    setFormData({
      ...formData,
      [e.target.name]: e.target.value,
    });
  const stripe = useStripe();
  const elements = useElements();
  console.log(products, "products");

  let productArray = Object.values(products);
  let firstItemInProductArray = [];
  firstItemInProductArray = productArray[0];
  console.log(firstItemInProductArray);
  let onProductsArray = Object.values(firstItemInProductArray);
  console.log(onProductsArray);
  let holderArray = [];
  holderArray = holderArray.concat(onProductsArray);
  let secondProductArray = [];
  secondProductArray = holderArray[0];
  console.log(secondProductArray);
  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!stripe || !elements) {
      // Stripe.js has not yet loaded.
      // Make sure to disable form submission until Stripe.js has loaded.
      return null;
    }

    const res = await axios.post("http://us-central-nbe-online-prep.cloudfunctions.net/pay", {
      email: email,
      amount,
    });

    const clientSecret = res.data["client_secret"];
    console.log(clientSecret);
    const { paymentIntent } = await stripe.confirmCardPayment(
      clientSecret,
      {
        payment_method: {
          type: "card",
          card: elements.getElement(CardElement),
          billing_details: {
            email: email,
          },
        },
      }
    );
    let results = {
      total,
      planAccess,
      start,
      end,
      customer,
    };

    try {
      if (!!results && paymentIntent.status === "succeeded") {
        await signup(email, password);
        history.replace({
          pathname: "/success",
          state: { result: results },
        });
      }
    } catch (error) {
      setAlert(`${error.message}`, "danger");
    }
  };

  useEffect(() => {
    setLoading(false);
  }, [setLoading]);

  const selectProduct = (plan) => {
    switch (plan) {
      case "bronze":
        console.log("bronze");
        setPlan((prevState) => ({
          ...prevState,
          bronze: "bronze",
          silver: "",
          gold: "",
          platinum: "",
          amount: 1999,
        }));

        setPurchaseSummary((prevState) => ({
          ...prevState,
          total: "19.99",
          planAccess: "Bronze",
          start: moment().format("MMMM Do YYYY, h:mm:ss a"),
          end: moment().add(30, "days").format("MMMM Do YYYY, h:mm:ss a"),
        }));
        break;
      case "silver":
        console.log("silver");
        setPlan((prevState) => ({
          ...prevState,
          bronze: "",
          silver: "silver",
          gold: "",
          platinum: "",
          amount: 3999,
        }));
        setPurchaseSummary((prevState) => ({
          ...prevState,
          total: "39.99",
          planAccess: "Silver",
          start: moment().format(),
          end: moment().add(1, "months"),
        }));
        break;
      case "gold":
        console.log("gold");
        setPlan((prevState) => ({
          ...prevState,
          bronze: "",
          silver: "",
          gold: "gold",
          platinum: "",
          amount: 6999,
        }));
        setPurchaseSummary((prevState) => ({
          ...prevState,
          total: "69.99",
          planAccess: "Gold",
          start: moment().format(),
          end: moment().add(3, "months"),
        }));
        break;
      case "platinum":
        console.log("platinum");
        setPlan((prevState) => ({
          ...prevState,
          bronze: "",
          silver: "",
          gold: "",
          platinum: "platinum",
          amount: 11999,
        }));
        setPurchaseSummary((prevState) => ({
          ...prevState,
          total: "119.99",
          planAccess: "Platinum",
          start: moment().format(),
          end: moment().add(12, "months"),
        }));
        break;

      default:
        break;
    }
  };

  return (
    <section className="container">
      {!loading && stripe ? (
        <Fragment>
          <div className="grid-pay">
            <div className="start">
              <h1 style={{ color: "#000000", textAlign: "justify" }}>
                Start Learning Today
              </h1>
              <p style={{ textAlign: "justify" }}>
                It is a long established fact that a reader will be distracted
                by the readable content of a page when looking at its layout.
                The point of using Lorem Ipsum is that it has a more-or-less
                normal distribution of letters, as opposed to using 'Content
                here, content here', making it look like readable English.
              </p>
              <div style={{ marginTop: 20 }}>
                <ul style={{ textAlign: "justify" }}>
                  <li style={{ color: "#000000" }}>
                    <div style={{ display: "flex" }}>
                      <div>
                        <img
                          alt="lock"
                          src={question}
                          style={{ width: 60, height: 60, marginBottom: 20 }}
                        />
                      </div>
                      <div>
                        <p style={{ marginTop: 20, marginLeft: 10 }}>
                          Unlimited access to all courses
                        </p>
                      </div>
                    </div>
                  </li>
                  <li style={{ color: "#000000" }}>
                    {" "}
                    <div style={{ display: "flex" }}>
                      <div>
                        <img
                          alt="rocket icon"
                          src={rocket}
                          style={{ width: 60, height: 60, marginBottom: 20 }}
                        />
                      </div>
                      <div>
                        <p style={{ marginTop: 20, marginLeft: 10 }}>
                          Hands-on exercises
                        </p>
                      </div>
                    </div>
                  </li>
                  <li style={{ color: "#000000" }}>
                    {" "}
                    <div style={{ display: "flex" }}>
                      <div>
                        <img
                          alt="lock"
                          src={access}
                          style={{ width: 60, height: 60, marginBottom: 20 }}
                        />
                      </div>
                      <div style={{ marginTop: 20, marginLeft: 10 }}>
                        <p>Weekly additions and updates</p>
                      </div>
                    </div>
                  </li>
                </ul>
              </div>
            </div>
            <div>
              <form onSubmit={(e) => handleSubmit(e)}>
                <Card className={classes.root}>
                  <div>
                    <p
                      style={{
                        color: "#000000",
                        fontSize: 30,
                        textAlign: "justify",
                        marginLeft: 20,
                        marginTop: 20,
                      }}
                    >
                      Choose Your Plan
                    </p>
                  </div>
                  <div className="button-grid" style={{ display: "flex" }}>
                    <div
                      onClick={() => selectProduct("bronze")}
                      id={`${bronze}`}
                      className={`gray `}
                      style={{ paddingTop: 5 }}
                    >
                      <h3>$19.99</h3>
                    </div>
                    <div
                      onClick={() => selectProduct("silver")}
                      id={`${silver}`}
                      className={`gray `}
                      style={{ paddingTop: 5 }}
                    >
                      <h3>$39.99</h3>
                    </div>
                    <div
                      onClick={() => selectProduct("gold")}
                      id={`${gold}`}
                      className={`gray`}
                      style={{ paddingTop: 5 }}
                    >
                      <h3>$69.99</h3>
                    </div>
                    <div
                      onClick={() => selectProduct("platinum")}
                      id={`${platinum}`}
                      className={`gray`}
                      style={{ paddingTop: 5 }}
                    >
                      <h3>$119.99</h3>
                    </div>
                  </div>
                  <CardContent className={classes.content}>
                    <TextField
                      label="Name"
                      id="outlined-email-input"
                      helperText={`Enter full name`}
                      margin="normal"
                      variant="outlined"
                      type="text"
                      required
                      name="customer"
                      value={customer}
                      onChange={(e) => onChange(e)}
                      fullWidth
                    />
                    <TextField
                      label="Email"
                      id="outlined-email-input"
                      helperText={`Email you'll recive updates and receipts on`}
                      margin="normal"
                      variant="outlined"
                      type="email"
                      required
                      name="email"
                      value={email}
                      onChange={(e) => onChange(e)}
                      fullWidth
                    />
                    <TextField
                      label="Passwod"
                      id="outlined-password-input"
                      helperText={`Create Password for your account`}
                      margin="normal"
                      variant="outlined"
                      type="password"
                      required
                      name="password"
                      value={password}
                      onChange={(e) => onChange(e)}
                      fullWidth
                    />
                    <TextField
                      label="confirm password"
                      id="outlined-password-input"
                      helperText={`Confirm Password`}
                      margin="normal"
                      variant="outlined"
                      type="password"
                      required
                      name="confirmPassword"
                      value={confirmPassword}
                      onChange={(e) => onChange(e)}
                      fullWidth
                    />
                    <div
                      style={{
                        display: "flex",
                        justifyContent: "space-between",
                      }}
                    >
                      <div>
                        <h3>Amount</h3>
                      </div>
                      <div>
                        <p style={{ color: "#000", fontSize: 22 }}>${total}</p>
                      </div>
                    </div>
                    <div style={{ marginTop: 10 }}>
                      <CardInput />
                    </div>
                  </CardContent>
                  <div
                    style={{
                      marginTop: 50,
                      marginLeft: 10,
                      marginRight: 10,
                      marginBottom: 30,
                    }}
                  >
                    <input
                      style={{}}
                      type="submit"
                      className="btn-style-two btn-primary button-gradient"
                      value="Purchase"
                    />
                  </div>
                </Card>
              </form>
            </div>
          </div>
        </Fragment>
      ) : (
        <Spinner />
      )}
    </section>
  );
};

const mapStateToProps = (state) => ({
  products: state.products,
});

export default connect(mapStateToProps, { getProducts, setAlert })(HomePage);
import React,{useState,useffect}来自“React”;
从“axios”导入axios;
//MUI组件
从“@物料界面/核心/卡片”导入卡片;
从“@material ui/core/CardContent”导入CardContent;
从“@material ui/core/TextField”导入TextField;
从“../../assets/icon-5.png”导入访问权限;
从“../../context/AuthContext”导入{useAuth}”;
从“../../assets/rocket.png”导入火箭;
从“../../assets/问号.png”导入问题;
从“react router dom”导入{useHistory};
从“react redux”导入{connect};
从“../../actions/products”导入{getProducts};
从“./Spinner/Spinner”导入微调器;
从“时刻”中导入时刻;
从“../../actions/alert”导入{setAlert};
从“@stripe/react stripe js”导入{useStripe,useElements,CardElement};
从“@material ui/core/styles”导入{makeStyles}”;
从“/CardInput”导入CardInput;
导入“/common.css”;
从“react”导入{Fragment};
const useStyles=makeStyles({
根目录:{
//最大宽度:500,
},
内容:{
显示:“flex”,
flexDirection:“列”,
alignContent:“灵活启动”,
},
分区:{
显示:“flex”,
flexDirection:“行”,
alignContent:“灵活启动”,
辩护内容:“间隔空间”,
},
按钮:{
页边空白:“2em自动1em”,
},
});
const主页=({getProducts,products,location,setAlert})=>{
const history=useHistory();
const{state}=位置;
console.log(状态为“params”);
const{signup}=useAuth();
const classes=useStyles();
//陈述
const[totalPlan,setPurchaseSummary]=useState({
总数:“19.99”,
计划访问:“,
开始:“,
完:,
});
const{total,planAccess,start,end}=totalPlan;
const[loading,setLoading]=useState(true);
常量[planList,setPlan]=useState({
青铜:“,
银币:“,
黄金:“,
白金:“,
金额:0,
});
常量{青铜、银、金、铂,数量}=平面图;
常量[formData,setFormData]=useState({
电邮:“,
密码:“”,
确认密码:“”,
});
const{email,customer,password,confirmPassword}=formData;
const onChange=(e)=>
setFormData({
…表格数据,
[e.target.name]:e.target.value,
});
常量stripe=useStripe();
常量元素=useElements();
控制台日志(产品,“产品”);
让productArray=Object.values(产品);
让firstItemInProductArray=[];
firstItemInProductArray=productArray[0];
log(firstItemInProductArray);
让onProductsArray=Object.values(firstItemInProductArray);
console.log(onProductsArray);
设holderArray=[];
holderArray=holderArray.concat(onProductsArray);
设secondProductArray=[];
secondProductArray=holderArray[0];
log(secondProductArray);
const handleSubmit=async(e)=>{
e、 预防默认值();
如果(!stripe | |!元素){
//Stripe.js尚未加载。
//确保在加载Stripe.js之前禁用表单提交。
返回null;
}
const res=等待axios.post(“http://us-central-nbe-online-prep.cloudfunctions.net/pay", {
电邮:电邮,,
数量
});
const clientSecret=res.data[“client_secret”];
console.log(clientSecret);
const{paymentIntent}=wait stripe.confirmCardPayment(
客户机密,
{
付款方式:{
输入:“卡片”,
卡片:elements.getElement(CardElement),
账单详情:{
电邮:电邮,,
},
},
}
);
让结果={
全部的
计划访问,
开始
完,,
顾客
};
试一试{
if(!!results&&paymentIntent.status==“successed”){
等待注册(电子邮件、密码);
历史。替换({
路径名:“/success”,
状态:{result:results},
});
}
}捕获(错误){
setAlert(`${error.message}`,`danger');
}
};
useffect(()=>{
设置加载(假);
},[setLoading]);
const selectProduct=(计划)=>{
道岔(平面图){
“青铜”案:
控制台日志(“青铜”);
setPlan((prevState)=>({
…国家,
青铜:“青铜”,
银币:“,
黄金:“,
白金:“,
金额:1999年,
}));
setPurchaseSummary((prevState)=>({
…国家,
总数:“19.99”,
planAccess:“青铜”,
开始:矩().format(“MMMM-Do-YYYY,h:mm:ss-a”),
结束:矩().添加(30,“天”).格式(“mm-Do-yyy,h:mm:ss-a”),
}));
打破
“银”案:
控制台日志(“银色”);
setPlan((prevState)=>({
…国家,
青铜:“,
银牌:“银牌”,
黄金:“,
白金:“,
金额:3999,
}));
setPurchaseSummary((prevState)=>({
…国家,
总数:“39.99”,
计划访问:“银色”,
开始:矩().format(),
结束:力矩()。添加(1,“月”),
}));
打破
案例“黄金”:
控制台日志(“黄金”);
setPlan((prevState)=>({
…国家,
铜牌:“