簡體   English   中英

ReactJS Stripe Payments 在點擊使用節點支付和快遞后未返回成功消息

[英]ReactJS Stripe Payments not returning successful message after clicking pay with node and express

我目前正在使用 ReactJS、node 和 express 與 Stripe Payment API。 點擊支付按鈕並輸入虛擬信用卡憑證后,頁面不處理支付。 我已經輸入了從儀表板中獲得的正確發布密鑰和 api 密鑰。我相信這可能與我需要在 server.js 文件(又名節點后端)中添加的內容有關。我已閱讀文檔我能得到的任何線索。 也在 Stack Overflow 上搜索過這里。 沒有一個問題與我正在尋找的相同。 請參閱下面的圖片和代碼。 謝謝

這是在按下按鈕之前。 請注意右側的控制台。 在此處輸入圖片說明

這是按下按鈕后。 加載微調器永遠顯示。 還要注意右側的控制台在此處輸入圖片說明

    // 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!"));

您需要使用client_secret查看服務器調用/網絡響應。 控制台錯誤表明您為confirmCardPayment提供了一個無效的秘密,顯然是一個空字符串。

You specified: .

看起來您的應用程序沒有按預期通過setClientSecret設置狀態,並且您最終得到useState("");的初始空字符串值useState(""); .

在調用confirmCardPayment之前檢查您的client_secret值,並后退以查找該值被丟棄的位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM