无法在使用 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_method
、requires_confirmation
、requires_action
、processing
、succeeded
、canceled
我看到您也在使用 Checkout。您可能需要考虑设置 webhook 以侦听与您的付款流程相关的事件,例如结帐完成或付款成功。
我正在尝试使用 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_method
、requires_confirmation
、requires_action
、processing
、succeeded
、canceled
我看到您也在使用 Checkout。您可能需要考虑设置 webhook 以侦听与您的付款流程相关的事件,例如结帐完成或付款成功。