NodeJS 使用条带支付网关获取状态时:“requires_payment_method”即使已定义付款方式

qv7cva1a  于 2023-10-17  发布在  Node.js
关注(0)|答案(1)|浏览(92)

我已经构建了一个电子商务Web应用程序,我正在尝试使用Stripe集成支付网关。
我用Firebase函数做后台...
我已经使用了条纹支付元素来构建一个卡表单,所以当我点击Buy Now按钮时,
enter image description here
enter image description here
Stripe API正在更新状态为requires_payment_method

{
>    id: 'pi_3O19vcSHgvSf9YWJ1IG2OQz6',
>    object: 'payment_intent',
>    amount: 4839800,
>    amount_capturable: 0,
>    amount_details: { tip: {} },
>    amount_received: 0,
>    application: null,
>    application_fee_amount: null,
>    automatic_payment_methods: null,
>    canceled_at: null,
>    cancellation_reason: null,
>    capture_method: 'automatic',
>    client_secret: 'pi_3O19vcSHgvSf9YWJ1IG2OQz6_secret_bDfh5jdZ42kEwJSAkhmKV66Hr',
>    confirmation_method: 'automatic',
>    created: 1697297940,
>    currency: 'inr',
>    customer: null,
>    description: null,
>    invoice: null,
>    last_payment_error: null,
>    latest_charge: null,
>    livemode: false,
>    metadata: {},
>    next_action: null,
>    on_behalf_of: null,
>    payment_method: null,
>    payment_method_configuration_details: null,
>    payment_method_options: {
>      card: {
>        installments: null,
>        mandate_options: null,
>        network: null,
>        request_three_d_secure: 'automatic'
>      }
>    },
>    payment_method_types: [ 'card' ],
>    processing: null,
>    receipt_email: null,
>    review: null,
>    setup_future_usage: null,
>    shipping: null,
>    source: null,
>    statement_descriptor: null,
>    statement_descriptor_suffix: null,
>    status: 'requires_payment_method',
>    transfer_data: null,
>    transfer_group: null
     }

下面是后端index.js文件

const functions = require("firebase-functions");
const cors = require("cors");
const express = require("express");
// const stripe = require("stripe")(process.env.REACT_APP_STRIPE_S_KEY);
const stripe = require("stripe")(
  "sk_test_51Lx20gSHgvSf9YWJE38GQ3cVmP0AGMzoN5DDV9HKWkmXTdNUZg3sYGc2awYKggWJ70cjpKYmXMJjjvBXn9r4nj1Z009XYH8Yiw"
);
// config
const app = express();

app.use(express.json());
app.use(cors()); //CORS == cross object references
app.get("/config", (req, res) =>
  res.send({
    publishablekey:
      "pk_test_51Lx20gSHgvSf9YWJnU5hpwZ8HmOUodPhMjoimQNjuu1GPQumoAV0ip6OficVVnszkjpFijVv5Kl8Amt0imLnt3pD00MtJASpXe",
  })
);
app.post("/payment/create", async (req, res) => {
  const total = req.query.total;
  console.log(total);
  const paymentIntent = await stripe.paymentIntents.create({
    amount: total,
    currency: "INR",
    payment_method_types: ["card"],
    // automatic_payment_methods: { enabled: true },
  });
  console.log(paymentIntent);
  res.status(201).send({
    clientSecret: paymentIntent.client_secret,
  });
});

// app.listen(5252, () =>
//   console.log(`Node server listening at http://localhost:5252`)
// );

exports.api = functions.https.onRequest(app);

下面是Payments.jsx文件

import { useEffect, useState } from "react";
import { loadStripe } from "@stripe/stripe-js";
import { final_subtotal } from "./Reducer";
import React from "react";
import AxiosToFetch from "../axios";
import { useStateValue } from "./StateProvider";
import { Link } from "react-router-dom";
import CartProducts from "./CartProducts";
import CheckoutForm from "./CheckoutForm";
import { Elements } from "@stripe/react-stripe-js";

const Payments = () => {
  const [{ Cart }, dispatch] = useStateValue();
  const [stripepromise, setStripepromise] = useState(null);
  const [clientSecret, setClientSecret] = useState("");
  /* eslint-disable */
  useEffect(() => {
    AxiosToFetch({
      method: "post",
      url: `/payment/create?total=${final_subtotal(Cart) * 100}`,
    }).then(async (res) => {
      console.log(res);
      const clintSecret = await res.data.clientSecret;
      setClientSecret(clintSecret);
    });
  }, [Cart]);
  useEffect(() => {
    AxiosToFetch.get("/config").then(async (r) => {
      const { publishablekey } = await r.data;

      setStripepromise(loadStripe(publishablekey));
    });
  }, []);
  const appearance = {
      theme: "night",
      labels: "floating,",
    };
    const options = {
      clientSecret,
      appearance,
    };
  return (
    <div className="container-fluid">
      <h2 className="text-center p-2">
        Your Checkout{" "}
        <Link className="text-warning" to="/cart">
          {Cart.length} items
        </Link>
      </h2>
      <hr />
      {/* this above tag is used to draw a horizontal line */}
      <h3 className="mt-2">Review items and dehlivery </h3>
      <div className="container">
        {Cart.map((item) => (
          <CartProducts
            id={item.id}
            image={item.image}
            title={item.title}
            price={item.price}
            ratings={0}
          />
        ))}
      </div>
      <hr/>
      {
      clientSecret && stripepromise &&
      <Elements stripe={stripepromise} options={options}>
      <CheckoutForm />
      </Elements>}
      
    </div>
    
  );
};

export default Payments;

下面是Checkoutform.jsx文件

import { useState } from "react";
import {
  useStripe,
  useElements,
  PaymentElement,
} from "@stripe/react-stripe-js";
import { useNavigate } from "react-router-dom";
import { final_subtotal } from "./Reducer";
import { useStateValue } from "./StateProvider";
import CurrencyFormat from "react-currency-format";

const CheckoutForm = () => {
  const [{ Cart }, dispatch] = useStateValue();
  let total_price = final_subtotal(Cart);
  const navigate = useNavigate();
  const stripe = useStripe();
  const elements = useElements();
  const [message, setMessage] = useState(null);
  const [processing, setProcessing] = useState(false);
  const handlesubmit = async (e) => {
    e.preventDefault();
    if (!stripe || !elements) {
      alert("getting in valid response");
    }
    setProcessing(true);

    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: navigate("/order"),
      },
    });
    if (error) {
      setMessage(error.message);
    }
    setProcessing("false");
  };

  return (
    <form
      className="card container bg-dark "
      style={{ width: "30rem" }}
      onSubmit={handlesubmit}
    >
      <div className="card-body">
        <div className="card-title">
          <PaymentElement />
        </div>
        <div className="card-title ">
          <CurrencyFormat
            renderText={(value) => (
              <>
                <h5>
                  Order Total ({Cart?.length} items) : {value}
                </h5>
              </>
            )}
            decimalScale={2}
            displayType="text"
            value={total_price}
            thousandSeparator={true}
            prefix="₹"
          />
        </div>

        <div className="card-title text-center pt-1">
          <button
            className=" btn btn-warning "
            style={{ minWidth: "20rem" }}
            disabled={total_price === 0 ? true : false && processing}
          >
            Buy Now
          </button>
          <div className="text-danger pt-1">{message}</div>
        </div>
      </div>
    </form>
  );
};

export default CheckoutForm;

请告诉我哪里出错了……

7hiiyaii

7hiiyaii1#

您可以在Dashboard request log上进行确认,但requires_payment_method通常意味着确认调用失败或从未发生。您可能希望在您的“提交”函数周围添加更多的调试日志。

相关问题