I need some help with my next.js application and I can't seem to find an answer that fully works. I am using Firebase as my backend, and using the "Run Payment with Stripe" extension to handle my web payments. I have implemented the subscription method successfully, but I want to add a one-time payment option to my website. I have implemented everything the same and added the "mode: "payment"
" to my checkout function. I want to fire another function once there is a successful payment, but I am not sure how to integrate that with my existing code. The webhook documentation for the extension doesn't provide any insight into how to handle a success case, so here I am asking for some help / guidance. Any help is greatly appreciated! Below is my code for creating a checkout session based on the extension docs:
export async function createTenCheckoutSession(uid) {
const firestore = firebase.firestore();
const checkoutSessionRef = await firestore
.collection("users")
.doc(uid)
.collection("checkout_sessions")
.add({
mode: "payment",
price: "price_xxxxxxxxxxxxxxxxxx",
success_url: window.location.origin,
cancel_url: window.location.origin,
});
checkoutSessionRef.onSnapshot(async (snap) => {
const { sessionId } = snap.data();
if (sessionId) {
const stripe = await getStripe();
stripe.redirectToCheckout({ sessionId });
}
});
};
Figured out a way to do this using Firebase Functions.
My current createCheckoutSession function is as follows:
export async function createCheckoutSession(uid) {
const firestore = firebase.firestore();
const checkoutSessionRef = await firestore
.collection("users")
.doc(uid)
.collection("checkout_sessions")
.add({
price: "price_xxxxxxxxxxxxxxxxxxxxxxxx",
success_url: window.location.origin,
cancel_url: window.location.origin,
});
checkoutSessionRef.onSnapshot(async (snap) => {
const { sessionId } = snap.data();
if (sessionId) {
const stripe = await getStripe();
stripe.redirectToCheckout({ sessionId });
}
});
};
I wanted to update my RTDB after a successful checkout session dependent on which one-time purchase was made. This is my Firebase Function:
const firestore = admin.firestore();
const realtimeDatabase = admin.database();
exports.updateRealtimeDatabase = functions.firestore
.document('users/{userId}/payments/{paymentId}')
.onCreate(async (snapshot, context) => {
const paymentId = context.params.paymentId;
const userId = context.params.userId;
// Get the data of the newly created document
const eventData = snapshot.data();
// Check if the event data meets the specified conditions
if (eventData.status === 'succeeded') {
if (eventData.amount === 4900) {
// Increase the Realtime Database viewCount for the corresponding user by 10
const updates = {};
updates[`/users/${userId}/viewCount`] = admin.database.ServerValue.increment(10);
try {
await realtimeDatabase.ref().update(updates);
console.log('Realtime Database updated successfully.');
} catch (error) {
console.error('Error updating Realtime Database:', error);
}
} else if (eventData.amount === 19900) {
// Increase the Realtime Database viewCount for the corresponding user by 50
const updates = {};
updates[`/users/${userId}/viewCount`] = admin.database.ServerValue.increment(50);
try {
await realtimeDatabase.ref().update(updates);
console.log('Realtime Database updated successfully.');
} catch (error) {
console.error('Error updating Realtime Database:', error);
}
} else {
console.log('No specific condition met. No update needed.');
}
} else {
console.log('Status is not "succeeded". No update needed.');
}
});