I store users in firebase realtime database and stripe to handle payments. An authenticated user can click a button and will get redirected to Stripe Checkout. After making a payment, user gets redirected to success_url
back in the app. Next I would like to update user Object in database - just save the information that the payment was successful and its id.
The problem: I don't know how to find a user which completed a payment, after redirection to success_url
. I would like to update user's data on database after the payment.
The idea: I can save the payment_intent
in the user profile, as this information is sent to the client side with a session. And then, after the payment completion I could search for the payment_intent
and update the user which had this data. But is this a good approach? Is there any better way to find a user?
My code is based on Firebase Cloud Function HTTP Requests. Following the Stripe guidelines to accept a payment, I create a session for a user which wants to make a payment:
export const payment = functions.https.onRequest((request, response) => {
cors(request, response, async () => {
response.set("Access-Control-Allow-Headers", "Content-Type");
response.set("Access-Control-Allow-Credentials", "true");
response.set("Access-Control-Allow-Origin", "*");
await stripe.checkout.sessions.create(
{
payment_method_types: ["card"],
line_items: [
{
price_data: {
currency: "usd",
product_data: {
name: "Test"
},
unit_amount: 1000
},
quantity: 1
}
],
mode: "payment",
success_url: "https://example.com/success",
cancel_url: "https://example.com/cancel"
},
function(err: Error, session: any) {
response.send(session);
// the session is sent to the client and can be used to finalise a transaction
}
);
});
});
On the client side I use axios to call a payment
cloud function request and afterwards I pass the sessionId
to Stripe.redirectToCheckout
which starts the checkout redirection:
let sessionId = "";
await axios.post("payment function url request")
.then(response => {
sessionId = response.data.id;
});
const stripe: any = await loadStripe("stripe key");
stripe.redirectToCheckout({
sessionId: sessionId
});
After the customer completes a payment on Stripe Checkout, they’re redirected to the URL that is specified as success_url
, it is advised to run a webhook from stripe when the checkout is completed.
It allows to fire another cloud function, which sends a response to the client side about a successful payment response.json({ received: true })
:
export const successfulPayment = functions.https.onRequest(
(request, response) => {
const sig = request.headers["stripe-signature"];
let event;
try {
event = stripe.webhooks.constructEvent(
request.rawBody,
sig,
endpointSecret
);
} catch (err) {
return response.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the checkout.session.completed event
// Should I update the user data in the database here?
if (event.type === "checkout.session.completed") {
const session = event.data.object;
console.log(`Event passed: ${session}`);
}
// Return a response to acknowledge receipt of the event
response.json({ received: true });
// Or how do I use this response to then update the user from the client side?
}
);
I will really appreciate all the help and suggestions :)