Automatically Create a Stripe Customer for Each User with Supabase Function Hooks

Jon Meyers
InstructorJon Meyers

Share this video with your friends

Send Tweet
Published 3 months ago
Updated 2 weeks ago

We want to call our API route to create a new Stripe customer anytime a new user signs into our application. Since this triggers an insert on our profile table, we can use hooks in Supabase to listen to insert events and call our API route.

Function hooks in Supabase are similar to PostgreSQL triggers, however, rather than executing a function, we can call a HTTP endpoint. Since our Next.js application is running locally on our machine it is not possible for Supabase to send a HTTP request directly to our API route.

Ngrok is a simple tool that allows us to tunnel traffic from a publicly accessible URL on the internet, through to our Next.js application running locally.

In order for our API route to process the request, we need to tell our Supabase hook to also send our API_ROUTE_SECRET. Query parameters can be declared as HTTP params for our hook.

Lastly, we want our Stripe customer to be associated with our user via their email address.

Instructor: [0:00] We want to call this API route to create a new Stripe customer for us, any time a new row is added to the profile table. In order to do this, we're going to use Supabase's function hooks, which can be found under the database menu.

[0:11] Let's enable hooks for this project. Now we can create a function hook. The name of our function hook is going to be getStripeCustomer. Similarly to Postgres triggers, we can listen to different events that occur on particular tables. We would like to watch the profile table, and call this endpoint any time an insert event happens.

[0:30] Our type of hook is going to be a HTTP request. We're going to select the POST method, and put in the URL to our API route. Because this function hook will be executed by the Supabase server, it doesn't actually know what our localhost is. Therefore, we need to tunnel traffic from a public Internet address through to port 3000 on our localhost machine.

[0:51] To do this, we're going to use a tool called ngrok. Since we'll need to keep this process running while we're testing in development, I'm going to start a new process. I'm going to install ngrok globally with the -g flag. Once that's finished, we can tell ngrok to route all HTTP traffic to port 3000. It will then give us a temporary public URL that we can route traffic to.

[1:14] We can copy that from here and replace http://localhost over port 3000 with our new public address. Now any HTTP requests that this public address receives will be forwarded to our localhost over port 3000, which will be handled by our Next.js server running on port 3000.

[1:31] The last thing we need to remember to send to our API route is the API route secret, or our request will just get rejected with status 401. Let's grab that value from our .env file. It's going to be API route secret. We're going to pass this along as a HTTP param.

[1:48] The value is going to be this value. Let's click confirm to create our new function hook. To test this works, let's go delete the row from the profile table and then our Supabase user from the authentication tab. We can delete our previous customers from our Stripe dashboard.

[2:06] Back in our application, we can logout our current user by going to /logout and then navigating to /login. If we go back to our Supabase dashboard and refresh our users in the authentication pane, we will see we have our user back.

[2:21] If we check our profile table, we have an associated row for our new customer complete with our new Stripe customer ID, which matches the customer in our dashboard.

[2:31] Our customer ID is correct, but our customer doesn't have a name and we haven't been able to correctly associate an email with this customer. If we have a look at our API route, we're setting the email for our new Stripe customer based on the request.body.record.email.

[2:47] This record represents the row in our profile table, that has just been inserted, which doesn't have a column for email. Our email only exists on our auth.users table. If we want to pipe this through to Stripe, we just need to create a new column for email in our profile table. This is going to be of type, text. Let's click Save to add our new column.

[3:09] We then need to tell our Trigger function that there is an email that we want to pass across. We can do that by editing our function here. When we insert into public profile, we now also care about the email column, and we want to set that to the value, new.email. Let's click Confirm to update our function. Let's delete our test records again.

[3:37] When we go back to our application and log out and back in, we should see our new customer in Stripe, complete with an email address. Our customer ID should match our profile table's Stripe customer.