#CMarabate
1 messages · Page 1 of 1 (latest)
Hi there, you can use Stripe's customerID to map with your customers in your own DB.
Hi, so I have done that already I think. I have used Auth0 Actions which creates a a Stripe Customer ID and adds it to my Auth0 users app_metadata added to the Login Flow but I am having a hell of a time figuring out how to use it to add roles to the app_metadata based on the customers purchases.
So it's more a question on how your application handle the Auth instead of payments?
Well ideally I would want it to set the roles after Stripe checkout is completed but I tried that first and I was able to get it to the point where I could complete checkout for a product and it would return me to the /success page and say everything was successful and it even added the customer in Stripe but no matter what I tried I could not get it to set the roles. I was calling a Netlify Function in the code for the success page. Was that a better approach?
Any way it can be accomplished I am cool with at this point lol
So you only want to set the role on customer (I assume the role is enable paid customer to enjoy your service) when the first invoice of the subscription is paid successfully?
Yeah pretty much.
Here is a function I created for returning the Role name based on the product's price id...
// Get role name from product ID
function getRoleFromPlan(planId) {
switch (planId) {
case 'price_1LAIw9FUDFxTEzZGYzM290b6':
return 'Free Member';
case 'price_1LAIzgFUDFxTEzZGIhVayoGC':
case 'price_1MbqhmFUDFxTEzZGSxfA0Ed5':
return 'Epic Member';
case 'price_1LAJ0tFUDFxTEzZGaNqoqBqi':
case 'price_1MbqiVFUDFxTEzZGo87RhTHT':
return 'Legendary Member';
default:
return null;
}
}
OK. I'll suggest you to listen to webhook event invoice.paid, which is fired when a invoice is paid successfully.
Okay thanks but I tried using a webhook once too and it was very confusing to me. Do you have a example of how to use a webhook to do something like this you can link me to or something?
https://stripe.com/docs/billing/subscriptions/webhooks This doc provides a list of recommended webhook events for subscription
https://stripe.com/docs/webhooks/quickstart and this page helps you to get started with webhook, it provides sample code in many languages so that you just copy and paste
Perfect thanks a bunch!
Is this correct? And will it trigger automatically whenever stripe receives an invoice.paid event, I don't need to call it in my code anywhere?
My code for the handle-subscription-change function is...
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const ManagementClient = require('auth0').ManagementClient;
// Set up the Auth0 Management API client
const auth0 = new ManagementClient({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_API_EXPLORER_CLIENT_ID,
clientSecret: process.env.AUTH0_API_EXPLORER_CLIENT_SECRET,
audience: `https://${process.env.AUTH0_DOMAIN}/api/v2/`,
});
// Get role name from product ID
function getRoleFromPlan(planId) {
switch (planId) {
case 'price_1LAIw9FUDFxTEzZGYzM290b6':
return 'Free Member';
case 'price_1LAIzgFUDFxTEzZGIhVayoGC':
case 'price_1MbqhmFUDFxTEzZGSxfA0Ed5':
return 'Epic Member';
case 'price_1LAJ0tFUDFxTEzZGaNqoqBqi':
case 'price_1MbqiVFUDFxTEzZGo87RhTHT':
return 'Legendary Member';
default:
return null;
}
}
exports.handler = async (event) => {
const sig = event.headers['stripe-signature'];
let eventObject;
try {
eventObject = stripe.webhooks.constructEvent(event.body, sig, 'whsec_MKxjsjSYqz5MdmetrTCbupmAQD2hFxpX');
} catch (err) {
return { statusCode: 400, body: `Webhook Error: ${err.message}` };
}
if (eventObject.type === 'customer.subscription.updated') {
const subscription = eventObject.data.object;
const userId = subscription.metadata.userId;
// Update user role in Auth0 based on subscription status and price ID
const isSubscriptionActive = subscription.status === 'active';
const role = isSubscriptionActive ? getRoleFromPlan(subscription.items.data[0].price.id) : 'Free Member';
try {
await auth0.updateUserMetadata({ id: userId }, { app_metadata: { role } });
return { statusCode: 200, body: 'Webhook received successfully' };
} catch (error) {
console.error(error);
return { statusCode: 500, body: 'Error updating user role in Auth0' };
}
}
return { statusCode: 200, body: 'Webhook received successfully' };
};
I don't see invoice.paid being handled in your code,
I thought that selecting it when setting up the webhook was all that was needed.
No, you still need to handle the event in your own code.
Good to know, thanks!
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const ManagementClient = require('auth0').ManagementClient;
// Set up the Auth0 Management API client
const auth0 = new ManagementClient({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_API_EXPLORER_CLIENT_ID,
clientSecret: process.env.AUTH0_API_EXPLORER_CLIENT_SECRET,
audience: `https://${process.env.AUTH0_DOMAIN}/api/v2/`,
});
// Get role name from product ID
function getRoleFromPlan(planId) {
switch (planId) {
case 'price_1LAIw9FUDFxTEzZGYzM290b6':
return 'Free Member';
case 'price_1LAIzgFUDFxTEzZGIhVayoGC':
case 'price_1MbqhmFUDFxTEzZGSxfA0Ed5':
return 'Epic Member';
case 'price_1LAJ0tFUDFxTEzZGaNqoqBqi':
case 'price_1MbqiVFUDFxTEzZGo87RhTHT':
return 'Legendary Member';
default:
return null;
}
}
exports.handler = async (event) => {
const sig = event.headers['stripe-signature'];
let eventObject;
try {
eventObject = stripe.webhooks.constructEvent(event.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
return { statusCode: 400, body: `Webhook Error: ${err.message}` };
}
if (eventObject.type === 'customer.subscription.updated') {
const subscription = eventObject.data.object;
const userId = subscription.metadata.userId;
// Update user role in Auth0 based on subscription status and price ID
const isSubscriptionActive = subscription.status === 'active';
const role = isSubscriptionActive ? getRoleFromPlan(subscription.items.data[0].price.id) : 'Free Member';
try {
await auth0.updateUserMetadata({ id: userId }, { app_metadata: { role } });
return { statusCode: 200, body: 'Webhook received successfully' };
} catch (error) {
console.error(error);
return { statusCode: 500, body: 'Error updating user role in Auth0' };
}
} else if (eventObject.type === 'invoice.paid') {
const invoice = eventObject.data.object;
const subscription = invoice.subscription;
if (subscription) {
const userId = invoice.metadata.userId;
// Update user role in Auth0 based on subscription status and price ID
const role = getRoleFromPlan(invoice.lines.data[0].price.id);
try {
await auth0.updateUserMetadata({ id: userId }, { app_metadata: { role } });
return { statusCode: 200, body: 'Webhook received successfully' };
} catch (error) {
console.error(error);
return { statusCode: 500, body: 'Error updating user role in Auth0' };
}
}
}
return { statusCode: 200, body: 'Webhook received successfully' };
};
Do free subscriptions also trigger the invoice.paid event? I want to test checking out with my Free Subscription to see if it assigns me the Free Member role.
nitpick: invoice.subscription may be null because invoice.paid is also fired for one-off invoice (i.e., not generated by subscription)
Oh I see what you mean now, thanks...
let subscription;
if (invoice.subscription) {
subscription = invoice.subscription;
}
By free subscription you mean subscription with trial? Yes an invoice.paid event will be fired for the first $0 invoice as well
No I mean just a subscription that cost nothing...
Yes, an invoice.paid event will be fired.
Your server returns 500, which means server error. You should check your server log and investigate the problem
My Netlify Logs for the function?
Ahh yeah I see some clues in there. One more thing real quick...
When I click on the customer I made completed checkout for the Free Membership with, I saw the webhook icon but when I clicked it it has the wrong function name it has the name I used last time I tried using a webhook. Where do I change that?
What do you mean by wrong function name? this is the webhook URL that you configured in the webhook settings page https://dashboard.stripe.com/webhooks
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
I mean that the function I just wrote is named handle-subscription-change not stripe-webhook
That function name is internal to you, you can change to whatever you want as long as the URL that you specify for webhook endpoint is valid.