【发布时间】:2021-08-30 12:09:42
【问题描述】:
我已成功使用 Stripe 调用结帐会话,以便用户可以订阅新订阅,但是当我尝试添加代码以便同一用户可以维护订阅时,我的 firebase 函数中出现以下错误:
maintainStripeCheckout
Unhandled error TypeError: Cannot read property 'sessions' of undefined at /workspace/lib/services/stripe/subscriptions.js:40:56 at func (/workspace/node_modules/firebase-functions/lib/providers/https.js:336:32) at processTicksAndRejections (internal/process/task_queues.js:97:5)
谁能解释为什么我一开始可以进入订阅,但后来无法维护它?
我的代码: index.html:
<html>
<head>
<title>Stripe Checkout Sample</title>
</head>
<body>
<div class="card">
<h2>Stripe Payments Testing</h1>
<button id="checkout-button">Checkout</button>
<p></p>
<button id="maintain-sub-button">Maintain Subscription</button>
</div>
<script src="https://www.gstatic.com/firebasejs/8.6.5/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.5/firebase-functions.js"></script>
<script src="https://js.stripe.com/v3/"></script>
<script src="./scripts.js"></script>
</body>
</html>
scripts.js:
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
var firebaseConfig = {
apiKey: "AIzaxxxxxxxxxxY",
authDomain: "xxxxxxxxxx.firebaseapp.com",
projectId: "xxxxxxx-framework-dev",
storageBucket: "xxxxxxxxxxxx-framework-dev.appspot.com",
messagingSenderId: "xxxxx6479",
appId: "xxxxxxxx7f88ea8a",
measurementId: "xxxxxxRNG"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const checkoutButton = document.getElementById('checkout-button')
const maintainSubButton = document.getElementById('maintain-sub-button')
const createStripeCheckout = firebase.functions().httpsCallable('createStripeCheckout')
const maintainStripeCheckout = firebase.functions().httpsCallable('maintainStripeCheckout')
const stripe = Stripe('pk_test_koZ19rxxxxxxxxxxxx')
checkoutButton.addEventListener('click', () => {
console.log('Clicked Add Subscription Button...')
createStripeCheckout({
priceId: "price_1Iw7lCHx6drz9dmyercIcXEx",
userId: "cus_JfbyXEfgxxxx",
email: "test@e.studio",
})
.then(response => {
console.log("sessionId",response.data.id)
const sessionId = response.data.id
stripe.redirectToCheckout({ sessionId: sessionId})
})
})
maintainSubButton.addEventListener('click', () => {
console.log('Clicked Maintain Subscription Button...')
maintainStripeCheckout({
userId: "cus_xxxxxxxxxFPJ",
})
.then(response => {
console.log("response: ",response);
console.log("response url: ",response.url);
const portalSessionId = response;
stripe.redirectToCheckout({ sessionId: portalSessionId})
})
})
和firebase功能:
import * as functions from "firebase-functions";
import {stripe, SUCCESS_URL, CANCEL_URL} from "../../config";
// const admin = require("firebase-admin");
import {getUser} from "../firebase/firestore";
export const createStripeCheckout = functions.https.onCall( async ( data, context ) => {
// TODO: Do some checks to make sure the subscription and customer email have been
// passed in correctly...
const userId = data.userId;
const priceId = data.priceId;
const customerEmail = data.email;
const user = await getUser(userId);
console.log("users: ", user);
console.log("PriceId: ", priceId);
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
mode: "subscription",
success_url: SUCCESS_URL,
cancel_url: CANCEL_URL,
// pass in the users email so that the subscription links up with the logged in user.
customer_email: customerEmail,
line_items: [
{
price: priceId,
// For metered billing, do not pass quantity
quantity: 1,
},
],
});
return {
id: session.id,
};
});
export const maintainStripeCheckout = functions.https.onCall( async ( data, context ) => {
const userId = data.userId;
console.log("userId: ", userId);
const session = await stripe.bilingPortal.sessions.create({
customer: userId,
return_url: "https://example.com/success.html",
});
console.log("PortalSession: ", session);
return (session);
});
【问题讨论】: