无法在使用 Firebase 和 Stripe 的配置中获得付费状态

Unable to get paid status in a configuration using Firebase and Stripe

我正在尝试使用 React、Firebase 和 Stripe 配置实现订阅支付。
我们正在将 Stripe 工程师创建的 this repository 重写为 React。

下面是我将其重写为 React 的存储库。
Stripe-Firebase-React
上述存储库可以执行以下操作

但是,由于我们没有得到已付款状态,我们无法告诉用户付款已经完成。
我如何获得付费状态?


主要代码如下

const STRIPE_PUBLISHABLE_KEY =
  "pk_test_51ISANPL0xj88kG6SYhHBAq0vvMumxhKL5qtk2O6gwRzMCjZ7mb9BLwGx8fvSwQdNKCVCWlW1DwavpiIcl54E8Qbq00wBeOmIF9";
const taxRates = ["txr_1ISW2nL0xj88kG6S0HUKfuKd"];
const prices = {};
let priceId = "";

const Products = ({ user }) => {
  const [active, setActive] = useState(false);
  const [product, setProduct] = useState({});
  useEffect(() => {
    // get products
    db.collection("products")
      .where("active", "==", true)
      .get()
      .then((querySnapshot) => {
        querySnapshot.forEach(async (doc) => {
          const priceSnap = await doc.ref
            .collection("prices")
            .where("active", "==", true)
            .orderBy("unit_amount")
            .get();
          const productData = doc.data();

          priceSnap.docs.forEach((doc) => {
            priceId = doc.id;
            const priceData = doc.data();
            prices[priceId] = priceData;
            const content = document.createTextNode(
              `${new Intl.NumberFormat("en-US", {
                style: "currency",
                currency: priceData.currency,
              }).format((priceData.unit_amount / 100).toFixed(2))} per ${
                priceData.interval
              }`
            );
            setProduct({
              name: productData.name,
              price: content.data,
            });
          });
        });
      });

    // get subscriptions user
    db.collection("customers")
      .doc(user.uid)
      .collection("subscriptions")
      .where("status", "in", ["trialing", "active"])
      .onSnapshot(async (snapshot) => {
        console.log(snapshot);
        if (snapshot.empty) {
          setActive(false);
          return;
        }
        setActive(true);
        const subscription = snapshot.docs[0].data();
        const priceData = (await subscription.price.get()).data();
        console.log(priceData);
      });
  }, [active, user]);

  const cancell = async () => {
    const functionRef = func.httpsCallable(
      "ext-firestore-stripe-subscriptions-createPortalLink"
    );
    const { data } = await functionRef({ returnUrl: window.location.origin });
    window.location.assign(data.url);
  };

  const subscribe = async (e) => {
    e.preventDefault();
    const selectedPrice = {
      price: priceId,
      dynamic_tax_rates: taxRates,
      quantity: 1,
    };
    const docRef = await db
      .collection("customers")
      .doc(user.uid)
      .collection("checkout_sessions")
      .add({
        allow_promotion_codes: true,
        line_items: [selectedPrice],
        success_url: window.location.origin,
        cancel_url: window.location.origin,
        metadata: {
          key: "value",
        },
      });
    docRef.onSnapshot(async (snap) => {
      const { error, sessionId } = snap.data();
      if (error) alert(`An error occured: ${error.message}`);
      if (sessionId) {
        const stripePromise = loadStripe(STRIPE_PUBLISHABLE_KEY);
        const stripe = await stripePromise;
        stripe.redirectToCheckout({ sessionId });
      }
    });
  };

  return (
    <>
      {active ? (
        <div>
          <h2>You are subscribed.</h2>
          <button onClick={cancell}>Cancell</button>
        </div>
      ) : (
        <div>
          <h2>Products</h2>
          <p>Test card numbers: 4242 4242 4242 4242</p>
          <dl>
            <dt>{product ? product.name : ""}</dt>
            <dd>{product ? product.price : ""}</dd>
          </dl>
          <button onClick={subscribe}>Subscribe</button>
        </div>
      )}
      <button onClick={() => auth.signOut()}>Signout</button>
    </>
  );
};
db.collection("customers")
      .doc(user.uid)
      .collection("subscriptions")
      .where("status", "in", ["trialing", "active"])
      .onSnapshot(async (snapshot) => {
...

主要代码中,获取付费用户的代码就是上面的部分。
我认为“subscriptions”集合是在付款后创建的,并将“subscriptions”集合设置为付费状态。
但是,当我查看我的 Firestore 时,没有创建“订阅”集合。
但是控制台没有显示权限错误。

你不是应该调用 Stripe 的 API 然后将值填充到 Firebase 中吗?

如果您想获取 PaymentIntent 的付款状态,请检索 PaymentIntent 对象并检查 status 字段。这些是根据 https://stripe.com/docs/payments/intents:

的可能状态

requires_payment_methodrequires_confirmationrequires_actionprocessingsucceededcanceled

我看到您也在使用 Checkout。您可能需要考虑设置 webhook 以侦听与您的付款流程相关的事件,例如结帐完成或付款成功。