Successful Checkout condition with Firebase and Stripe "Run Payment with Stripe"

46 views Asked by At

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 });
        }
    });
};
1

There are 1 answers

0
Christopher Koziol On BEST ANSWER

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.');
        }
    });