Implement metered billing in Stripe in record time with callable Firebase cloud functions https://angularfirebase.com/lessons/saas-metered-subscriptions-with-stripe-billing-and-firebase/

Stripe Billing https://stripe.com/us/billing
Callable Functions https://firebase.google.com/docs/functions/callable
2024-02-04T07:26:39.661Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
7e92a40c-02e7-4774-8c5c-750ab239ebcb
e9913cb63053748bacfa4d8ef53d5b6e9bf2a66c3e4619e574615b25781549bd
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Back in April, Stripe payments released a new billing platform that makes complex subscription payments easier than ever.
To demonstrate this tool, we're to build a pretty ambitious feature.
A subscription plan that doesn't get billed on a fixed rate, but rather based on the user's volume of usage within the app.
The goal is to give you a foundation for building your own software as a service type application that has a pay as you go payment plan.
If you're new here, make sure to like and And also a little later today at 1 pm Pacific Time or 7 pm GMT, I will be appearing on the Angular Academy show.
So make sure to register so you can live chat with myself and the world famous David East.
To get started with this project, you'll need to have a Stripe account and we'll be making heavy Use of Firebase functions.
There's a new tool in Firebase that makes a feature like this much easier to build than it was a few months ago, and that's thanks to callable functions.
Basically, a callable function is just like an HTTP function, except that it sends the context for the authenticated user.
This is extremely powerful because it means you don't have to set your own authorization headers in the front end or have to decode them on the back end, which means a lot less code to write and test.
We'll be writing 3 different Cloud Functions, so let's walk through this step by step.
The first one is an auth function that happens after the user logs in and sets up their account with Stripe customer ID.
After we have the customer ID set up, the next major milestone is to collect a payment source and sign up a user for the subscription plan.
We'll implement Stripe Elements to collect and validate the credit card from the user.
Then when they click the submit payment button, it will trigger our callable function with the auth context so we can securely attach that credit card to the user in our back end.
That signs the user up for the plan and writes a bunch of information to their Firestore user document.
But at this point, their estimated bill is 0 because they haven't actually done anything in the app.
In this particular app, we will charge the user $1 per month for every project that they create.
If we click this create project button, it will create a document in Firestore which again triggers another Cloud function.
This 3rd and final cloud function will report usage to Stripe, so we know what to bill them for a given month.
So if we create a couple more projects here, you'll see that our estimated bill jumps up to $3 per month.
And we can also see this in the Stripe dashboard where we have an upcoming invoice for $3 for the subscriber.
And we can inspect all the usage events, which again will get reported via our cloud function.
Before we write any code, let's start with the fun part which is setting up the actual billing plan in Stripe.
The first thing you'll do is set up your product, which is an entity that can hold multiple payment plans.
So for example, a pro subscription would be product and then I might have multiple plans for weekly, monthly, or quarterly.
For this demo here, we'll just set up a single payment plan and we'll make sure to make it a metered Usage plan.
There's a whole bunch of ways you can customize the plan.
For example, you might have tiers for different levels of volume usage Or you might have different ways of aggregating the actual usage through the payment period.
The whole idea behind Stripe Billing is to allow you, the developer, to build a complex payment system without having to write a whole bunch of code to maintain it.
When you're finished, you'll have a product ID and a plan The make a note of the plan ID because we'll need that later in the Cloud Function.
Now we're going to switch gears into our Angular app and initialize Firebase Cloud Functions.
You'll want to select the TypeScript option.
Just go with the defaults and everything else, then cd into the functions directory and run npm install Stripe.
Then the other thing we need to do is set up our Stripe secret key in the Cloud Functions environment.
You can find it on the Stripe dashboard, and I would recommend using that test data so you're not working with live payment information.
Then run Firebase functions config set stripe dot secret with your secret key, And this will securely store it in our functions environment.
At this point, we're going to be jumping back and forth between our front end and back end code, so I'll do my best to keep that clear, but the first thing we'll do is implement our front end user authentication code.
I'm going to go over that quickly because I cover it in detail on episode 55, And this demo uses the same system with some slight modifications.
I'd first like to point out that we have AngularFire 2 installed, and we have auth, Firestore, as well as the New AngularFire functions module.
So you wanna make sure you have an app module that looks something like this.
And you'll also notice that I generated a payment form component and project manager component with the Angular CLI that we'll build out here in the following steps.
But the first thing we'll do is quickly go through the auth service to get our user logged in to our Firebase app.
One of the key differences from episode 55 is that we have additional properties on the user interface, mainly the Stripe customer ID as well as some information about the subscription itself.
We have AngularFire 2 installed here, so we can inject AngularFire auth and Firestore in the constructor.
And then we'll represent our user as an observable of a Firestore document.
If the user's authenticated, then we'll go ahead and retrieve their document from Firestore.
Otherwise, we'll just return an observable of null, which means the user's not Signed in.
The rest of this demo is compatible with any auth method in Firebase, but I'm just going to use anonymous auth because it requires the least amount of code to set up.
What this code here is doing is it's logging in the user anonymously, and then it's creating a document in Firestore when they sign in for the first time.
So all we have to do is bind this anonymous login method to a button click, and we'll get the user signed in without any additional work on our end.
The next thing we wanna do is Trigger a function when the user signs up.
So go into the index TS file in the functions directory, and then we'll initialize Firebase admin.
And we'll want to also initialize Stripe with our secret key that we set up in the environment earlier.
And these variables are set up globally in this function's file because they'll be shared throughout our 3 different Cloud Functions.
The first function is the easiest one to create.
Basically, we're just listening for a new user to sign up.
And when that happens, we'll take their Firebase user ID, use that to create a new user in Stripe, and then update the customer ID that we get back from Stripe on their Firestore document.
So we're just creating a one to one connection between the Firebase user and the Stripe user.
Authentication triggers in Firebase will include the Firebase user ID on the user record object.
Then we'll call Stripe customers create, And we'll set their Firebase user ID as metadata on the Stripe customer.
That part's technically optional, but it's generally a good idea to keep track of things between the two platforms.
Stripe will respond with an object of the newly created customer, and the only thing we actually need from that is the Stripe customer ID, which we can then use is to save on the Firestore document.
So that takes care of the first hurdle.
Now that we have a Stripe customer, the next thing we need to do is collect their payment source and then attach them to a specific subscription plan.
To handle that, we'll use Stripe Elements, which is the quickest and easiest way to set up a payment form in your front end UI.
The very first thing you'll do is go into your index HTML file and add the Stripe JS version 3 to the head of the document.
Then we can go into our payment form component.
And the first thing we'll wanna do is initialize Stripe elements, which really just operates outside the context of our component, so we'll just add it up here directly in the code.
This time, you initialize Stripe with your publishable key.
You don't want to expose your secret key in your front end code.
And then we'll say Stripe elements create card, which will eventually bind here to a DOM element.
In Angular, we can grab an element from the DOM by using view child, which we'll call our card form.
And we'll be using a callable function in this component, So we inject the AngularFire function service.
After the view is initialized, we'll call card dot mount, which will have Stripe elements do thing on this specific DOM element.
After the user fills out the form, we need to send the card details to Stripe, which will then respond with a token that we can use to attach the payment source to the user in our back end.
For that, we can call Stripe create token.
And I'm not showing it here, but you should also handle errors here as well.
But assuming we have a valid card, we can then call our callable function, which we'll name start subscription.
So this is an alternative to using the HTTP module in Angular.
Normally, we would have to set the authorization header for the logged in user and then decode it in our Cloud Function.
So the beauty of a callable function is that we don't have to do any of that.
We can just pass in the source that we get back from Stripe, and we'll already know the context of the user when this function gets triggered.
Then if we switch over to the HTML, all we have to do is set up a form and then we'll bind to the submit event on this form and trigger that handler that we just wrote.
The only other thing to do is set up a div for Stripe elements to attach to, which we can do with hash card form.
That takes care of the front end code.
Now we'll write the back end code for that callable function.
We can go ahead and say functions, https on call, And that gives us access to the data that we pass from the front end, which is the Stripe token that we need to use to attach to the user.
And, again, we have access to the caller of this function, which we can get with context dot authuid.
Now that we have this information, we can go ahead and pull that user's There's document from Firestore which contains the Stripe customer ID.
So now we have all the information we need to attach the payment token to the Stripe customer.
We make that happen by calling Stripe create source with the customer ID as well as the token that we passed through this callable function.
And while we're here, I'd like to point out that we handle errors a little bit differently than other HTTP functions.
Instead of sending an error response, we can just throw an error directly And the callable function will send that back down to the client.
But assuming that the payment source attaches successfully, the next step is to subscribe this user to our actual plan that we created in Stripe at the beginning of this process.
So we'll go ahead and call Stripe subscriptions create And pass in the Stripe user ID as well as the plan that we want to subscribe them to.
I'm just hard coding it here, but most likely you would Set that up as an environment variable or send it through the callable function.
And lastly, that will respond with some data And we'll use that data to update the Firestore document.
So at this point, we have a system where the user can submit their payment And it updates their document with the subscription information from Stripe.
The final thing we need to do is report usage to Stripe.
Otherwise, we're not gonna get paid for anything.
So in this app here, I've set it up so the user can create a hypothetical project, which is just creating a new document in Fire store that lives in the projects collection.
I'm not really gonna focus on the front end code here because it's really simple, just adding a document to Firestore, But you can find the full source code in the link in the description.
The interesting part here is our 3rd and final cloud function.
We'll call this the update usage function, And it will run whenever a new document is created in the projects collection.
And the process is pretty similar.
We have a user ID that's on that project document to associate it with the Firebase user.
So we can then pull their Firestore document information, which has the subscription information that we need to report usage to.
So we'll retrieve the user document like we did in previous functions And then we'll call Stripe usage records create, and we'll create a new usage record with the item ID on that subscription.
This can be kind of confusing because you might have multiple items on a single subscription.
For example, think about the way Firebase bills.
You have different quotas for storage, database functions, etcetera, and you're billed separately for each.
That's exactly the kind of stuff that Stripe Billing allows you to do.
You can send usage records to Stripe 1 at a time or you can aggregate them together and send a higher quantity based on the amount of volume that flows through your app.
You'll need to set a time stamp in unit seconds, So convert the JavaScript millisecond date into plain seconds.
Then it's always a good idea to set an item potency key, which you can do with the snapshot ID.
That'll just guarantee that the user's usage will be consistent even if this Cloud function gets invoked multiple times, which is possible.
Then the final thing we'll do is Update the user's record in Firestore just so we can show an estimated bill for them as well.
Now whenever you create a new document in Firestore, this user's bill will be updated and then Stripe will charge them for it at the end of the month.
I've been doing this for a while and it's pretty amazing that we can build a feature like this in a completely serverless way and at Zero cost for us initially when building our minimum viable product.
I'm gonna go and wrap things up there.
If this video helped you, please like subscribe, and don't forget to join us on Angular Academy today again at 1 PM Pacific Time.
And if you're not already a Pro member, make sure to Sign up to get access to all kinds of exclusive content designed to help you build and ship your app faster.
Thanks for watching, and I'll talk to you soon.

Speaker 0: Back in April, Stripe payments released a new billing platform that makes complex subscription payments easier than ever. To demonstrate this tool, we're to build a pretty ambitious feature. A subscription plan that doesn't get billed on a fixed rate, but rather based on the user's volume of usage within the app. The goal is to give you a foundation for building your own software as a service type application that has a pay as you go payment plan. If you're new here, make sure to like and And also a little later today at 1 pm Pacific Time or 7 pm GMT, I will be appearing on the Angular Academy show.

So make sure to register so you can live chat with myself and the world famous David East. To get started with this project, you'll need to have a Stripe account and we'll be making heavy Use of Firebase functions. There's a new tool in Firebase that makes a feature like this much easier to build than it was a few months ago, and that's thanks to callable functions. Basically, a callable function is just like an HTTP function, except that it sends the context for the authenticated user. This is extremely powerful because it means you don't have to set your own authorization headers in the front end or have to decode them on the back end, which means a lot less code to write and test.

We'll be writing 3 different Cloud Functions, so let's walk through this step by step. The first one is an auth function that happens after the user logs in and sets up their account with Stripe customer ID. After we have the customer ID set up, the next major milestone is to collect a payment source and sign up a user for the subscription plan. We'll implement Stripe Elements to collect and validate the credit card from the user. Then when they click the submit payment button, it will trigger our callable function with the auth context so we can securely attach that credit card to the user in our back end.

That signs the user up for the plan and writes a bunch of information to their Firestore user document. But at this point, their estimated bill is 0 because they haven't actually done anything in the app. In this particular app, we will charge the user $1 per month for every project that they create. If we click this create project button, it will create a document in Firestore which again triggers another Cloud function. This 3rd and final cloud function will report usage to Stripe, so we know what to bill them for a given month.

So if we create a couple more projects here, you'll see that our estimated bill jumps up to $3 per month. And we can also see this in the Stripe dashboard where we have an upcoming invoice for $3 for the subscriber. And we can inspect all the usage events, which again will get reported via our cloud function. Before we write any code, let's start with the fun part which is setting up the actual billing plan in Stripe. The first thing you'll do is set up your product, which is an entity that can hold multiple payment plans.

So for example, a pro subscription would be product and then I might have multiple plans for weekly, monthly, or quarterly. For this demo here, we'll just set up a single payment plan and we'll make sure to make it a metered Usage plan. There's a whole bunch of ways you can customize the plan. For example, you might have tiers for different levels of volume usage Or you might have different ways of aggregating the actual usage through the payment period. The whole idea behind Stripe Billing is to allow you, the developer, to build a complex payment system without having to write a whole bunch of code to maintain it.

When you're finished, you'll have a product ID and a plan The make a note of the plan ID because we'll need that later in the Cloud Function. Now we're going to switch gears into our Angular app and initialize Firebase Cloud Functions. You'll want to select the TypeScript option. Just go with the defaults and everything else, then cd into the functions directory and run npm install Stripe. Then the other thing we need to do is set up our Stripe secret key in the Cloud Functions environment.

You can find it on the Stripe dashboard, and I would recommend using that test data so you're not working with live payment information. Then run Firebase functions config set stripe dot secret with your secret key, And this will securely store it in our functions environment. At this point, we're going to be jumping back and forth between our front end and back end code, so I'll do my best to keep that clear, but the first thing we'll do is implement our front end user authentication code. I'm going to go over that quickly because I cover it in detail on episode 55, And this demo uses the same system with some slight modifications. I'd first like to point out that we have AngularFire 2 installed, and we have auth, Firestore, as well as the New AngularFire functions module.

So you wanna make sure you have an app module that looks something like this. And you'll also notice that I generated a payment form component and project manager component with the Angular CLI that we'll build out here in the following steps. But the first thing we'll do is quickly go through the auth service to get our user logged in to our Firebase app. One of the key differences from episode 55 is that we have additional properties on the user interface, mainly the Stripe customer ID as well as some information about the subscription itself. We have AngularFire 2 installed here, so we can inject AngularFire auth and Firestore in the constructor.

And then we'll represent our user as an observable of a Firestore document. If the user's authenticated, then we'll go ahead and retrieve their document from Firestore. Otherwise, we'll just return an observable of null, which means the user's not Signed in. The rest of this demo is compatible with any auth method in Firebase, but I'm just going to use anonymous auth because it requires the least amount of code to set up. What this code here is doing is it's logging in the user anonymously, and then it's creating a document in Firestore when they sign in for the first time.

So all we have to do is bind this anonymous login method to a button click, and we'll get the user signed in without any additional work on our end. The next thing we wanna do is Trigger a function when the user signs up. So go into the index TS file in the functions directory, and then we'll initialize Firebase admin. And we'll want to also initialize Stripe with our secret key that we set up in the environment earlier. And these variables are set up globally in this function's file because they'll be shared throughout our 3 different Cloud Functions.

The first function is the easiest one to create. Basically, we're just listening for a new user to sign up. And when that happens, we'll take their Firebase user ID, use that to create a new user in Stripe, and then update the customer ID that we get back from Stripe on their Firestore document. So we're just creating a one to one connection between the Firebase user and the Stripe user. Authentication triggers in Firebase will include the Firebase user ID on the user record object.

Then we'll call Stripe customers create, And we'll set their Firebase user ID as metadata on the Stripe customer. That part's technically optional, but it's generally a good idea to keep track of things between the two platforms. Stripe will respond with an object of the newly created customer, and the only thing we actually need from that is the Stripe customer ID, which we can then use is to save on the Firestore document. So that takes care of the first hurdle. Now that we have a Stripe customer, the next thing we need to do is collect their payment source and then attach them to a specific subscription plan.

To handle that, we'll use Stripe Elements, which is the quickest and easiest way to set up a payment form in your front end UI. The very first thing you'll do is go into your index HTML file and add the Stripe JS version 3 to the head of the document. Then we can go into our payment form component. And the first thing we'll wanna do is initialize Stripe elements, which really just operates outside the context of our component, so we'll just add it up here directly in the code. This time, you initialize Stripe with your publishable key.

You don't want to expose your secret key in your front end code. And then we'll say Stripe elements create card, which will eventually bind here to a DOM element. In Angular, we can grab an element from the DOM by using view child, which we'll call our card form. And we'll be using a callable function in this component, So we inject the AngularFire function service. After the view is initialized, we'll call card dot mount, which will have Stripe elements do thing on this specific DOM element.

After the user fills out the form, we need to send the card details to Stripe, which will then respond with a token that we can use to attach the payment source to the user in our back end. For that, we can call Stripe create token. And I'm not showing it here, but you should also handle errors here as well. But assuming we have a valid card, we can then call our callable function, which we'll name start subscription. So this is an alternative to using the HTTP module in Angular.

Normally, we would have to set the authorization header for the logged in user and then decode it in our Cloud Function. So the beauty of a callable function is that we don't have to do any of that. We can just pass in the source that we get back from Stripe, and we'll already know the context of the user when this function gets triggered. Then if we switch over to the HTML, all we have to do is set up a form and then we'll bind to the submit event on this form and trigger that handler that we just wrote. The only other thing to do is set up a div for Stripe elements to attach to, which we can do with hash card form.

That takes care of the front end code. Now we'll write the back end code for that callable function. We can go ahead and say functions, https on call, And that gives us access to the data that we pass from the front end, which is the Stripe token that we need to use to attach to the user. And, again, we have access to the caller of this function, which we can get with context dot authuid. Now that we have this information, we can go ahead and pull that user's There's document from Firestore which contains the Stripe customer ID.

So now we have all the information we need to attach the payment token to the Stripe customer. We make that happen by calling Stripe create source with the customer ID as well as the token that we passed through this callable function. And while we're here, I'd like to point out that we handle errors a little bit differently than other HTTP functions. Instead of sending an error response, we can just throw an error directly And the callable function will send that back down to the client. But assuming that the payment source attaches successfully, the next step is to subscribe this user to our actual plan that we created in Stripe at the beginning of this process.

So we'll go ahead and call Stripe subscriptions create And pass in the Stripe user ID as well as the plan that we want to subscribe them to. I'm just hard coding it here, but most likely you would Set that up as an environment variable or send it through the callable function. And lastly, that will respond with some data And we'll use that data to update the Firestore document. So at this point, we have a system where the user can submit their payment And it updates their document with the subscription information from Stripe. The final thing we need to do is report usage to Stripe.

Otherwise, we're not gonna get paid for anything. So in this app here, I've set it up so the user can create a hypothetical project, which is just creating a new document in Fire store that lives in the projects collection. I'm not really gonna focus on the front end code here because it's really simple, just adding a document to Firestore, But you can find the full source code in the link in the description. The interesting part here is our 3rd and final cloud function. We'll call this the update usage function, And it will run whenever a new document is created in the projects collection.

And the process is pretty similar. We have a user ID that's on that project document to associate it with the Firebase user. So we can then pull their Firestore document information, which has the subscription information that we need to report usage to. So we'll retrieve the user document like we did in previous functions And then we'll call Stripe usage records create, and we'll create a new usage record with the item ID on that subscription. This can be kind of confusing because you might have multiple items on a single subscription.

For example, think about the way Firebase bills. You have different quotas for storage, database functions, etcetera, and you're billed separately for each. That's exactly the kind of stuff that Stripe Billing allows you to do. You can send usage records to Stripe 1 at a time or you can aggregate them together and send a higher quantity based on the amount of volume that flows through your app. You'll need to set a time stamp in unit seconds, So convert the JavaScript millisecond date into plain seconds.

Then it's always a good idea to set an item potency key, which you can do with the snapshot ID. That'll just guarantee that the user's usage will be consistent even if this Cloud function gets invoked multiple times, which is possible. Then the final thing we'll do is Update the user's record in Firestore just so we can show an estimated bill for them as well. Now whenever you create a new document in Firestore, this user's bill will be updated and then Stripe will charge them for it at the end of the month. I've been doing this for a while and it's pretty amazing that we can build a feature like this in a completely serverless way and at Zero cost for us initially when building our minimum viable product.

I'm gonna go and wrap things up there. If this video helped you, please like subscribe, and don't forget to join us on Angular Academy today again at 1 PM Pacific Time. And if you're not already a Pro member, make sure to Sign up to get access to all kinds of exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
Back in April, Stripe payments released a new billing platform that makes complex subscription payments easier than ever. To demonstrate this tool, we're to build a pretty ambitious feature. A subscription plan that doesn't get billed on a fixed rate, but rather based on the user's volume of usage within the app. The goal is to give you a foundation for building your own software as a service type application that has a pay as you go payment plan. If you're new here, make sure to like and And also a little later today at 1 pm Pacific Time or 7 pm GMT, I will be appearing on the Angular Academy show. So make sure to register so you can live chat with myself and the world famous David East.
billing
theater
software development
To get started with this project, you'll need to have a Stripe account and we'll be making heavy Use of Firebase functions. There's a new tool in Firebase that makes a feature like this much easier to build than it was a few months ago, and that's thanks to callable functions. Basically, a callable function is just like an HTTP function, except that it sends the context for the authenticated user. This is extremely powerful because it means you don't have to set your own authorization headers in the front end or have to decode them on the back end, which means a lot less code to write and test.
We'll be writing 3 different Cloud Functions, so let's walk through this step by step. The first one is an auth function that happens after the user logs in and sets up their account with Stripe customer ID. After we have the customer ID set up, the next major milestone is to collect a payment source and sign up a user for the subscription plan. We'll implement Stripe Elements to collect and validate the credit card from the user. Then when they click the submit payment button, it will trigger our callable function with the auth context so we can securely attach that credit card to the user in our back end. That signs the user up for the plan and writes a bunch of information to their Firestore user document. But at this point, their estimated bill is 0 because they haven't actually done anything in the app. In this particular app, we will charge the user $1 per month for every project that they create. If we click this create project button, it will create a document in Firestore which again triggers another Cloud function. This 3rd and final cloud function will report usage to Stripe, so we know what to bill them for a given month. So if we create a couple more projects here, you'll see that our estimated bill jumps up to $3 per month. And we can also see this in the Stripe dashboard where we have an upcoming invoice for $3 for the subscriber. And we can inspect all the usage events, which again will get reported via our cloud function. Before we write any code, let's start with the fun part which is setting up the actual billing plan in Stripe. The first thing you'll do is set up your product, which is an entity that can hold multiple payment plans. So for example, a pro subscription would be product and then I might have multiple plans for weekly, monthly, or quarterly. For this demo here, we'll just set up a single payment plan and we'll make sure to make it a metered Usage plan. There's a whole bunch of ways you can customize the plan. For example, you might have tiers for different levels of volume usage Or you might have different ways of aggregating the actual usage through the payment period. The whole idea behind Stripe Billing is to allow you, the developer, to build a complex payment system without having to write a whole bunch of code to maintain it. When you're finished, you'll have a product ID and a plan The make a note of the plan ID because we'll need that later in the Cloud Function.
billing
customer support
taxes
purchasing
programming
Now we're going to switch gears into our Angular app and initialize Firebase Cloud Functions. You'll want to select the TypeScript option. Just go with the defaults and everything else, then cd into the functions directory and run npm install Stripe. Then the other thing we need to do is set up our Stripe secret key in the Cloud Functions environment. You can find it on the Stripe dashboard, and I would recommend using that test data so you're not working with live payment information.
Then run Firebase functions config set stripe dot secret with your secret key, And this will securely store it in our functions environment. At this point, we're going to be jumping back and forth between our front end and back end code, so I'll do my best to keep that clear, but the first thing we'll do is implement our front end user authentication code.
security
I'm going to go over that quickly because I cover it in detail on episode 55, And this demo uses the same system with some slight modifications. I'd first like to point out that we have AngularFire 2 installed, and we have auth, Firestore, as well as the New AngularFire functions module. So you wanna make sure you have an app module that looks something like this. And you'll also notice that I generated a payment form component and project manager component with the Angular CLI that we'll build out here in the following steps. But the first thing we'll do is quickly go through the auth service to get our user logged in to our Firebase app. One of the key differences from episode 55 is that we have additional properties on the user interface, mainly the Stripe customer ID as well as some information about the subscription itself. We have AngularFire 2 installed here, so we can inject AngularFire auth and Firestore in the constructor. And then we'll represent our user as an observable of a Firestore document. If the user's authenticated, then we'll go ahead and retrieve their document from Firestore. Otherwise, we'll just return an observable of null, which means the user's not Signed in. The rest of this demo is compatible with any auth method in Firebase, but I'm just going to use anonymous auth because it requires the least amount of code to set up. What this code here is doing is it's logging in the user anonymously, and then it's creating a document in Firestore when they sign in for the first time. So all we have to do is bind this anonymous login method to a button click, and we'll get the user signed in without any additional work on our end. The next thing we wanna do is Trigger a function when the user signs up. So go into the index TS file in the functions directory, and then we'll initialize Firebase admin. And we'll want to also initialize Stripe with our secret key that we set up in the environment earlier. And these variables are set up globally in this function's file because they'll be shared throughout our 3 different Cloud Functions. The first function is the easiest one to create. Basically, we're just listening for a new user to sign up. And when that happens, we'll take their Firebase user ID, use that to create a new user in Stripe, and then update the customer ID that we get back from Stripe on their Firestore document. So we're just creating a one to one connection between the Firebase user and the Stripe user. Authentication triggers in Firebase will include the Firebase user ID on the user record object.
Then we'll call Stripe customers create, And we'll set their Firebase user ID as metadata on the Stripe customer. That part's technically optional, but it's generally a good idea to keep track of things between the two platforms. Stripe will respond with an object of the newly created customer, and the only thing we actually need from that is the Stripe customer ID, which we can then use is to save on the Firestore document. So that takes care of the first hurdle. Now that we have a Stripe customer, the next thing we need to do is collect their payment source and then attach them to a specific subscription plan. To handle that, we'll use Stripe Elements, which is the quickest and easiest way to set up a payment form in your front end UI.
billing
customer support
customers
The very first thing you'll do is go into your index HTML file and add the Stripe JS version 3 to the head of the document. Then we can go into our payment form component. And the first thing we'll wanna do is initialize Stripe elements, which really just operates outside the context of our component, so we'll just add it up here directly in the code. This time, you initialize Stripe with your publishable key. You don't want to expose your secret key in your front end code. And then we'll say Stripe elements create card, which will eventually bind here to a DOM element. In Angular, we can grab an element from the DOM by using view child, which we'll call our card form. And we'll be using a callable function in this component, So we inject the AngularFire function service. After the view is initialized, we'll call card dot mount, which will have Stripe elements do thing on this specific DOM element. After the user fills out the form, we need to send the card details to Stripe, which will then respond with a token that we can use to attach the payment source to the user in our back end. For that, we can call Stripe create token. And I'm not showing it here, but you should also handle errors here as well. But assuming we have a valid card, we can then call our callable function, which we'll name start subscription. So this is an alternative to using the HTTP module in Angular. Normally, we would have to set the authorization header for the logged in user and then decode it in our Cloud Function. So the beauty of a callable function is that we don't have to do any of that. We can just pass in the source that we get back from Stripe, and we'll already know the context of the user when this function gets triggered. Then if we switch over to the HTML, all we have to do is set up a form and then we'll bind to the submit event on this form and trigger that handler that we just wrote. The only other thing to do is set up a div for Stripe elements to attach to, which we can do with hash card form.
That takes care of the front end code. Now we'll write the back end code for that callable function. We can go ahead and say functions, https on call, And that gives us access to the data that we pass from the front end, which is the Stripe token that we need to use to attach to the user. And, again, we have access to the caller of this function, which we can get with context dot authuid. Now that we have this information, we can go ahead and pull that user's There's document from Firestore which contains the Stripe customer ID. So now we have all the information we need to attach the payment token to the Stripe customer. We make that happen by calling Stripe create source with the customer ID as well as the token that we passed through this callable function. And while we're here, I'd like to point out that we handle errors a little bit differently than other HTTP functions.
billing
programming
customer support
Instead of sending an error response, we can just throw an error directly And the callable function will send that back down to the client.
But assuming that the payment source attaches successfully, the next step is to subscribe this user to our actual plan that we created in Stripe at the beginning of this process. So we'll go ahead and call Stripe subscriptions create And pass in the Stripe user ID as well as the plan that we want to subscribe them to. I'm just hard coding it here, but most likely you would Set that up as an environment variable or send it through the callable function. And lastly, that will respond with some data And we'll use that data to update the Firestore document. So at this point, we have a system where the user can submit their payment And it updates their document with the subscription information from Stripe. The final thing we need to do is report usage to Stripe.
billing
customer support
documentation
programming
Otherwise, we're not gonna get paid for anything. So in this app here, I've set it up so the user can create a hypothetical project, which is just creating a new document in Fire store that lives in the projects collection. I'm not really gonna focus on the front end code here because it's really simple, just adding a document to Firestore, But you can find the full source code in the link in the description. The interesting part here is our 3rd and final cloud function. We'll call this the update usage function, And it will run whenever a new document is created in the projects collection. And the process is pretty similar. We have a user ID that's on that project document to associate it with the Firebase user. So we can then pull their Firestore document information, which has the subscription information that we need to report usage to.
So we'll retrieve the user document like we did in previous functions And then we'll call Stripe usage records create, and we'll create a new usage record with the item ID on that subscription. This can be kind of confusing because you might have multiple items on a single subscription. For example, think about the way Firebase bills. You have different quotas for storage, database functions, etcetera, and you're billed separately for each. That's exactly the kind of stuff that Stripe Billing allows you to do. You can send usage records to Stripe 1 at a time or you can aggregate them together and send a higher quantity based on the amount of volume that flows through your app. You'll need to set a time stamp in unit seconds, So convert the JavaScript millisecond date into plain seconds.
billing
Then it's always a good idea to set an item potency key, which you can do with the snapshot ID.
That'll just guarantee that the user's usage will be consistent even if this Cloud function gets invoked multiple times, which is possible. Then the final thing we'll do is Update the user's record in Firestore just so we can show an estimated bill for them as well. Now whenever you create a new document in Firestore, this user's bill will be updated and then Stripe will charge them for it at the end of the month. I've been doing this for a while and it's pretty amazing that we can build a feature like this in a completely serverless way and at Zero cost for us initially when building our minimum viable product. I'm gonna go and wrap things up there. If this video helped you, please like subscribe, and don't forget to join us on Angular Academy today again at 1 PM Pacific Time. And if you're not already a Pro member, make sure to Sign up to get access to all kinds of exclusive content designed to help you build and ship your app faster.
billing
youtube
customer support
animation
Thanks for watching, and I'll talk to you soon.
Back in April, Stripe payments released a new billing platform that makes complex subscription payments easier than ever. To demonstrate this tool, we're to build a pretty ambitious feature. A subscription plan that doesn't get billed on a fixed rate, but rather based on the user's volume of usage within the app. The goal is to give you a foundation for building your own software as a service type application that has a pay as you go payment plan. If you're new here, make sure to like and And also a little later today at 1 pm Pacific Time or 7 pm GMT, I will be appearing on the Angular Academy show. So make sure to register so you can live chat with myself and the world famous David East. To get started with this project, you'll need to have a Stripe account and we'll be making heavy Use of Firebase functions. There's a new tool in Firebase that makes a feature like this much easier to build than it was a few months ago, and that's thanks to callable functions. Basically, a callable function is just like an HTTP function, except that it sends the context for the authenticated user. This is extremely powerful because it means you don't have to set your own authorization headers in the front end or have to decode them on the back end, which means a lot less code to write and test. We'll be writing 3 different Cloud Functions, so let's walk through this step by step. The first one is an auth function that happens after the user logs in and sets up their account with Stripe customer ID. After we have the customer ID set up, the next major milestone is to collect a payment source and sign up a user for the subscription plan. We'll implement Stripe Elements to collect and validate the credit card from the user. Then when they click the submit payment button, it will trigger our callable function with the auth context so we can securely attach that credit card to the user in our back end. That signs the user up for the plan and writes a bunch of information to their Firestore user document. But at this point, their estimated bill is 0 because they haven't actually done anything in the app. In this particular app, we will charge the user $1 per month for every project that they create. If we click this create project button, it will create a document in Firestore which again triggers another Cloud function. This 3rd and final cloud function will report usage to Stripe, so we know what to bill them for a given month. So if we create a couple more projects here, you'll see that our estimated bill jumps up to $3 per month. And we can also see this in the Stripe dashboard where we have an upcoming invoice for $3 for the subscriber. And we can inspect all the usage events, which again will get reported via our cloud function. Before we write any code, let's start with the fun part which is setting up the actual billing plan in Stripe. The first thing you'll do is set up your product, which is an entity that can hold multiple payment plans. So for example, a pro subscription would be product and then I might have multiple plans for weekly, monthly, or quarterly. For this demo here, we'll just set up a single payment plan and we'll make sure to make it a metered Usage plan. There's a whole bunch of ways you can customize the plan. For example, you might have tiers for different levels of volume usage Or you might have different ways of aggregating the actual usage through the payment period. The whole idea behind Stripe Billing is to allow you, the developer, to build a complex payment system without having to write a whole bunch of code to maintain it. When you're finished, you'll have a product ID and a plan The make a note of the plan ID because we'll need that later in the Cloud Function. Now we're going to switch gears into our Angular app and initialize Firebase Cloud Functions. You'll want to select the TypeScript option. Just go with the defaults and everything else, then cd into the functions directory and run npm install Stripe. Then the other thing we need to do is set up our Stripe secret key in the Cloud Functions environment. You can find it on the Stripe dashboard, and I would recommend using that test data so you're not working with live payment information. Then run Firebase functions config set stripe dot secret with your secret key, And this will securely store it in our functions environment. At this point, we're going to be jumping back and forth between our front end and back end code, so I'll do my best to keep that clear, but the first thing we'll do is implement our front end user authentication code. I'm going to go over that quickly because I cover it in detail on episode 55, And this demo uses the same system with some slight modifications. I'd first like to point out that we have AngularFire 2 installed, and we have auth, Firestore, as well as the New AngularFire functions module. So you wanna make sure you have an app module that looks something like this. And you'll also notice that I generated a payment form component and project manager component with the Angular CLI that we'll build out here in the following steps. But the first thing we'll do is quickly go through the auth service to get our user logged in to our Firebase app. One of the key differences from episode 55 is that we have additional properties on the user interface, mainly the Stripe customer ID as well as some information about the subscription itself. We have AngularFire 2 installed here, so we can inject AngularFire auth and Firestore in the constructor. And then we'll represent our user as an observable of a Firestore document. If the user's authenticated, then we'll go ahead and retrieve their document from Firestore. Otherwise, we'll just return an observable of null, which means the user's not Signed in. The rest of this demo is compatible with any auth method in Firebase, but I'm just going to use anonymous auth because it requires the least amount of code to set up. What this code here is doing is it's logging in the user anonymously, and then it's creating a document in Firestore when they sign in for the first time. So all we have to do is bind this anonymous login method to a button click, and we'll get the user signed in without any additional work on our end. The next thing we wanna do is Trigger a function when the user signs up. So go into the index TS file in the functions directory, and then we'll initialize Firebase admin. And we'll want to also initialize Stripe with our secret key that we set up in the environment earlier. And these variables are set up globally in this function's file because they'll be shared throughout our 3 different Cloud Functions. The first function is the easiest one to create. Basically, we're just listening for a new user to sign up. And when that happens, we'll take their Firebase user ID, use that to create a new user in Stripe, and then update the customer ID that we get back from Stripe on their Firestore document. So we're just creating a one to one connection between the Firebase user and the Stripe user. Authentication triggers in Firebase will include the Firebase user ID on the user record object. Then we'll call Stripe customers create, And we'll set their Firebase user ID as metadata on the Stripe customer. That part's technically optional, but it's generally a good idea to keep track of things between the two platforms. Stripe will respond with an object of the newly created customer, and the only thing we actually need from that is the Stripe customer ID, which we can then use is to save on the Firestore document. So that takes care of the first hurdle. Now that we have a Stripe customer, the next thing we need to do is collect their payment source and then attach them to a specific subscription plan. To handle that, we'll use Stripe Elements, which is the quickest and easiest way to set up a payment form in your front end UI. The very first thing you'll do is go into your index HTML file and add the Stripe JS version 3 to the head of the document. Then we can go into our payment form component. And the first thing we'll wanna do is initialize Stripe elements, which really just operates outside the context of our component, so we'll just add it up here directly in the code. This time, you initialize Stripe with your publishable key. You don't want to expose your secret key in your front end code. And then we'll say Stripe elements create card, which will eventually bind here to a DOM element. In Angular, we can grab an element from the DOM by using view child, which we'll call our card form. And we'll be using a callable function in this component, So we inject the AngularFire function service. After the view is initialized, we'll call card dot mount, which will have Stripe elements do thing on this specific DOM element. After the user fills out the form, we need to send the card details to Stripe, which will then respond with a token that we can use to attach the payment source to the user in our back end. For that, we can call Stripe create token. And I'm not showing it here, but you should also handle errors here as well. But assuming we have a valid card, we can then call our callable function, which we'll name start subscription. So this is an alternative to using the HTTP module in Angular. Normally, we would have to set the authorization header for the logged in user and then decode it in our Cloud Function. So the beauty of a callable function is that we don't have to do any of that. We can just pass in the source that we get back from Stripe, and we'll already know the context of the user when this function gets triggered. Then if we switch over to the HTML, all we have to do is set up a form and then we'll bind to the submit event on this form and trigger that handler that we just wrote. The only other thing to do is set up a div for Stripe elements to attach to, which we can do with hash card form. That takes care of the front end code. Now we'll write the back end code for that callable function. We can go ahead and say functions, https on call, And that gives us access to the data that we pass from the front end, which is the Stripe token that we need to use to attach to the user. And, again, we have access to the caller of this function, which we can get with context dot authuid. Now that we have this information, we can go ahead and pull that user's There's document from Firestore which contains the Stripe customer ID. So now we have all the information we need to attach the payment token to the Stripe customer. We make that happen by calling Stripe create source with the customer ID as well as the token that we passed through this callable function. And while we're here, I'd like to point out that we handle errors a little bit differently than other HTTP functions. Instead of sending an error response, we can just throw an error directly And the callable function will send that back down to the client. But assuming that the payment source attaches successfully, the next step is to subscribe this user to our actual plan that we created in Stripe at the beginning of this process. So we'll go ahead and call Stripe subscriptions create And pass in the Stripe user ID as well as the plan that we want to subscribe them to. I'm just hard coding it here, but most likely you would Set that up as an environment variable or send it through the callable function. And lastly, that will respond with some data And we'll use that data to update the Firestore document. So at this point, we have a system where the user can submit their payment And it updates their document with the subscription information from Stripe. The final thing we need to do is report usage to Stripe. Otherwise, we're not gonna get paid for anything. So in this app here, I've set it up so the user can create a hypothetical project, which is just creating a new document in Fire store that lives in the projects collection. I'm not really gonna focus on the front end code here because it's really simple, just adding a document to Firestore, But you can find the full source code in the link in the description. The interesting part here is our 3rd and final cloud function. We'll call this the update usage function, And it will run whenever a new document is created in the projects collection. And the process is pretty similar. We have a user ID that's on that project document to associate it with the Firebase user. So we can then pull their Firestore document information, which has the subscription information that we need to report usage to. So we'll retrieve the user document like we did in previous functions And then we'll call Stripe usage records create, and we'll create a new usage record with the item ID on that subscription. This can be kind of confusing because you might have multiple items on a single subscription. For example, think about the way Firebase bills. You have different quotas for storage, database functions, etcetera, and you're billed separately for each. That's exactly the kind of stuff that Stripe Billing allows you to do. You can send usage records to Stripe 1 at a time or you can aggregate them together and send a higher quantity based on the amount of volume that flows through your app. You'll need to set a time stamp in unit seconds, So convert the JavaScript millisecond date into plain seconds. Then it's always a good idea to set an item potency key, which you can do with the snapshot ID. That'll just guarantee that the user's usage will be consistent even if this Cloud function gets invoked multiple times, which is possible. Then the final thing we'll do is Update the user's record in Firestore just so we can show an estimated bill for them as well. Now whenever you create a new document in Firestore, this user's bill will be updated and then Stripe will charge them for it at the end of the month. I've been doing this for a while and it's pretty amazing that we can build a feature like this in a completely serverless way and at Zero cost for us initially when building our minimum viable product. I'm gonna go and wrap things up there. If this video helped you, please like subscribe, and don't forget to join us on Angular Academy today again at 1 PM Pacific Time. And if you're not already a Pro member, make sure to Sign up to get access to all kinds of exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
Back
back
in
in
April,
april
Stripe
stripe
payments
payments
released
released
a
a
new
new
billing
billing
platform
platform
that
that
makes
makes
complex
complex
subscription
subscription
payments
payments
easier
easier
than
than
ever.
ever
To
to
demonstrate
demonstrate
this
this
tool,
tool
we're
we're
to
to
build
build
a
a
pretty
pretty
ambitious
ambitious
feature.
feature
A
a
subscription
subscription
plan
plan
that
that
doesn't
doesn't
get
get
billed
billed
on
on
a
a
fixed
fixed
rate,
rate
but
but
rather
rather
based
based
on
on
the
the
user's
user's
volume
volume
of
of
usage
usage
within
within
the
the
app.
app
The
the
goal
goal
is
is
to
to
give
give
you
you
a
a
foundation
foundation
for
for
building
building
your
your
own
own
software
software
as
as
a
a
service
service
type
type
application
application
that
that
has
has
a
a
pay
pay
as
as
you
you
go
go
payment
payment
plan.
plan
If
if
you're
you're
new
new
here,
here
make
make
sure
sure
to
to
like
like
and
and
And
and
also
also
a
a
little
little
later
later
today
today
at
at
1
1
pm
pm
Pacific
pacific
Time
time
or
or
7
7
pm
pm
GMT,
gmt
I
i
will
will
be
be
appearing
appearing
on
on
the
the
Angular
angular
Academy
academy
show.
show
So
so
make
make
sure
sure
to
to
register
register
so
so
you
you
can
can
live
live
chat
chat
with
with
myself
myself
and
and
the
the
world
world
famous
famous
David
david
East.
east
To
to
get
get
started
started
with
with
this
this
project,
project
you'll
you'll
need
need
to
to
have
have
a
a
Stripe
stripe
account
account
and
and
we'll
we'll
be
be
making
making
heavy
heavy
Use
use
of
of
Firebase
firebase
functions.
functions
There's
there's
a
a
new
new
tool
tool
in
in
Firebase
firebase
that
that
makes
makes
a
a
feature
feature
like
like
this
this
much
much
easier
easier
to
to
build
build
than
than
it
it
was
was
a
a
few
few
months
months
ago,
ago
and
and
that's
that's
thanks
thanks
to
to
callable
callable
functions.
functions
Basically,
basically
a
a
callable
callable
function
function
is
is
just
just
like
like
an
an
HTTP
http
function,
function
except
except
that
that
it
it
sends
sends
the
the
context
context
for
for
the
the
authenticated
authenticated
user.
user
This
this
is
is
extremely
extremely
powerful
powerful
because
because
it
it
means
means
you
you
don't
don't
have
have
to
to
set
set
your
your
own
own
authorization
authorization
headers
headers
in
in
the
the
front
front
end
end
or
or
have
have
to
to
decode
decode
them
them
on
on
the
the
back
back
end,
end
which
which
means
means
a
a
lot
lot
less
less
code
code
to
to
write
write
and
and
test.
test
We'll
we'll
be
be
writing
writing
3
3
different
different
Cloud
cloud
Functions,
functions
so
so
let's
let's
walk
walk
through
through
this
this
step
step
by
by
step.
step
The
the
first
first
one
one
is
is
an
an
auth
auth
function
function
that
that
happens
happens
after
after
the
the
user
user
logs
logs
in
in
and
and
sets
sets
up
up
their
their
account
account
with
with
Stripe
stripe
customer
customer
ID.
id
After
after
we
we
have
have
the
the
customer
customer
ID
id
set
set
up,
up
the
the
next
next
major
major
milestone
milestone
is
is
to
to
collect
collect
a
a
payment
payment
source
source
and
and
sign
sign
up
up
a
a
user
user
for
for
the
the
subscription
subscription
plan.
plan
We'll
we'll
implement
implement
Stripe
stripe
Elements
elements
to
to
collect
collect
and
and
validate
validate
the
the
credit
credit
card
card
from
from
the
the
user.
user
Then
then
when
when
they
they
click
click
the
the
submit
submit
payment
payment
button,
button
it
it
will
will
trigger
trigger
our
our
callable
callable
function
function
with
with
the
the
auth
auth
context
context
so
so
we
we
can
can
securely
securely
attach
attach
that
that
credit
credit
card
card
to
to
the
the
user
user
in
in
our
our
back
back
end.
end
That
that
signs
signs
the
the
user
user
up
up
for
for
the
the
plan
plan
and
and
writes
writes
a
a
bunch
bunch
of
of
information
information
to
to
their
their
Firestore
firestore
user
user
document.
document
But
but
at
at
this
this
point,
point
their
their
estimated
estimated
bill
bill
is
is
0
0
because
because
they
they
haven't
haven't
actually
actually
done
done
anything
anything
in
in
the
the
app.
app
In
in
this
this
particular
particular
app,
app
we
we
will
will
charge
charge
the
the
user
user
$1
$1
per
per
month
month
for
for
every
every
project
project
that
that
they
they
create.
create
If
if
we
we
click
click
this
this
create
create
project
project
button,
button
it
it
will
will
create
create
a
a
document
document
in
in
Firestore
firestore
which
which
again
again
triggers
triggers
another
another
Cloud
cloud
function.
function
This
this
3rd
3rd
and
and
final
final
cloud
cloud
function
function
will
will
report
report
usage
usage
to
to
Stripe,
stripe
so
so
we
we
know
know
what
what
to
to
bill
bill
them
them
for
for
a
a
given
given
month.
month
So
so
if
if
we
we
create
create
a
a
couple
couple
more
more
projects
projects
here,
here
you'll
you'll
see
see
that
that
our
our
estimated
estimated
bill
bill
jumps
jumps
up
up
to
to
$3
$3
per
per
month.
month
And
and
we
we
can
can
also
also
see
see
this
this
in
in
the
the
Stripe
stripe
dashboard
dashboard
where
where
we
we
have
have
an
an
upcoming
upcoming
invoice
invoice
for
for
$3
$3
for
for
the
the
subscriber.
subscriber
And
and
we
we
can
can
inspect
inspect
all
all
the
the
usage
usage
events,
events
which
which
again
again
will
will
get
get
reported
reported
via
via
our
our
cloud
cloud
function.
function
Before
before
we
we
write
write
any
any
code,
code
let's
let's
start
start
with
with
the
the
fun
fun
part
part
which
which
is
is
setting
setting
up
up
the
the
actual
actual
billing
billing
plan
plan
in
in
Stripe.
stripe
The
the
first
first
thing
thing
you'll
you'll
do
do
is
is
set
set
up
up
your
your
product,
product
which
which
is
is
an
an
entity
entity
that
that
can
can
hold
hold
multiple
multiple
payment
payment
plans.
plans
So
so
for
for
example,
example
a
a
pro
pro
subscription
subscription
would
would
be
be
product
product
and
and
then
then
I
i
might
might
have
have
multiple
multiple
plans
plans
for
for
weekly,
weekly
monthly,
monthly
or
or
quarterly.
quarterly
For
for
this
this
demo
demo
here,
here
we'll
we'll
just
just
set
set
up
up
a
a
single
single
payment
payment
plan
plan
and
and
we'll
we'll
make
make
sure
sure
to
to
make
make
it
it
a
a
metered
metered
Usage
usage
plan.
plan
There's
there's
a
a
whole
whole
bunch
bunch
of
of
ways
ways
you
you
can
can
customize
customize
the
the
plan.
plan
For
for
example,
example
you
you
might
might
have
have
tiers
tiers
for
for
different
different
levels
levels
of
of
volume
volume
usage
usage
Or
or
you
you
might
might
have
have
different
different
ways
ways
of
of
aggregating
aggregating
the
the
actual
actual
usage
usage
through
through
the
the
payment
payment
period.
period
The
the
whole
whole
idea
idea
behind
behind
Stripe
stripe
Billing
billing
is
is
to
to
allow
allow
you,
you
the
the
developer,
developer
to
to
build
build
a
a
complex
complex
payment
payment
system
system
without
without
having
having
to
to
write
write
a
a
whole
whole
bunch
bunch
of
of
code
code
to
to
maintain
maintain
it.
it
When
when
you're
you're
finished,
finished
you'll
you'll
have
have
a
a
product
product
ID
id
and
and
a
a
plan
plan
The
the
make
make
a
a
note
note
of
of
the
the
plan
plan
ID
id
because
because
we'll
we'll
need
need
that
that
later
later
in
in
the
the
Cloud
cloud
Function.
function
Now
now
we're
we're
going
going
to
to
switch
switch
gears
gears
into
into
our
our
Angular
angular
app
app
and
and
initialize
initialize
Firebase
firebase
Cloud
cloud
Functions.
functions
You'll
you'll
want
want
to
to
select
select
the
the
TypeScript
typescript
option.
option
Just
just
go
go
with
with
the
the
defaults
defaults
and
and
everything
everything
else,
else
then
then
cd
cd
into
into
the
the
functions
functions
directory
directory
and
and
run
run
npm
npm
install
install
Stripe.
stripe
Then
then
the
the
other
other
thing
thing
we
we
need
need
to
to
do
do
is
is
set
set
up
up
our
our
Stripe
stripe
secret
secret
key
key
in
in
the
the
Cloud
cloud
Functions
functions
environment.
environment
You
you
can
can
find
find
it
it
on
on
the
the
Stripe
stripe
dashboard,
dashboard
and
and
I
i
would
would
recommend
recommend
using
using
that
that
test
test
data
data
so
so
you're
you're
not
not
working
working
with
with
live
live
payment
payment
information.
information
Then
then
run
run
Firebase
firebase
functions
functions
config
config
set
set
stripe
stripe
dot
dot
secret
secret
with
with
your
your
secret
secret
key,
key
And
and
this
this
will
will
securely
securely
store
store
it
it
in
in
our
our
functions
functions
environment.
environment
At
at
this
this
point,
point
we're
we're
going
going
to
to
be
be
jumping
jumping
back
back
and
and
forth
forth
between
between
our
our
front
front
end
end
and
and
back
back
end
end
code,
code
so
so
I'll
i'll
do
do
my
my
best
best
to
to
keep
keep
that
that
clear,
clear
but
but
the
the
first
first
thing
thing
we'll
we'll
do
do
is
is
implement
implement
our
our
front
front
end
end
user
user
authentication
authentication
code.
code
I'm
i'm
going
going
to
to
go
go
over
over
that
that
quickly
quickly
because
because
I
i
cover
cover
it
it
in
in
detail
detail
on
on
episode
episode
55,
55
And
and
this
this
demo
demo
uses
uses
the
the
same
same
system
system
with
with
some
some
slight
slight
modifications.
modifications
I'd
i'd
first
first
like
like
to
to
point
point
out
out
that
that
we
we
have
have
AngularFire
angularfire
2
2
installed,
installed
and
and
we
we
have
have
auth,
auth
Firestore,
firestore
as
as
well
well
as
as
the
the
New
new
AngularFire
angularfire
functions
functions
module.
module
So
so
you
you
wanna
wanna
make
make
sure
sure
you
you
have
have
an
an
app
app
module
module
that
that
looks
looks
something
something
like
like
this.
this
And
and
you'll
you'll
also
also
notice
notice
that
that
I
i
generated
generated
a
a
payment
payment
form
form
component
component
and
and
project
project
manager
manager
component
component
with
with
the
the
Angular
angular
CLI
cli
that
that
we'll
we'll
build
build
out
out
here
here
in
in
the
the
following
following
steps.
steps
But
but
the
the
first
first
thing
thing
we'll
we'll
do
do
is
is
quickly
quickly
go
go
through
through
the
the
auth
auth
service
service
to
to
get
get
our
our
user
user
logged
logged
in
in
to
to
our
our
Firebase
firebase
app.
app
One
one
of
of
the
the
key
key
differences
differences
from
from
episode
episode
55
55
is
is
that
that
we
we
have
have
additional
additional
properties
properties
on
on
the
the
user
user
interface,
interface
mainly
mainly
the
the
Stripe
stripe
customer
customer
ID
id
as
as
well
well
as
as
some
some
information
information
about
about
the
the
subscription
subscription
itself.
itself
We
we
have
have
AngularFire
angularfire
2
2
installed
installed
here,
here
so
so
we
we
can
can
inject
inject
AngularFire
angularfire
auth
auth
and
and
Firestore
firestore
in
in
the
the
constructor.
constructor
And
and
then
then
we'll
we'll
represent
represent
our
our
user
user
as
as
an
an
observable
observable
of
of
a
a
Firestore
firestore
document.
document
If
if
the
the
user's
user's
authenticated,
authenticated
then
then
we'll
we'll
go
go
ahead
ahead
and
and
retrieve
retrieve
their
their
document
document
from
from
Firestore.
firestore
Otherwise,
otherwise
we'll
we'll
just
just
return
return
an
an
observable
observable
of
of
null,
null
which
which
means
means
the
the
user's
user's
not
not
Signed
signed
in.
in
The
the
rest
rest
of
of
this
this
demo
demo
is
is
compatible
compatible
with
with
any
any
auth
auth
method
method
in
in
Firebase,
firebase
but
but
I'm
i'm
just
just
going
going
to
to
use
use
anonymous
anonymous
auth
auth
because
because
it
it
requires
requires
the
the
least
least
amount
amount
of
of
code
code
to
to
set
set
up.
up
What
what
this
this
code
code
here
here
is
is
doing
doing
is
is
it's
it's
logging
logging
in
in
the
the
user
user
anonymously,
anonymously
and
and
then
then
it's
it's
creating
creating
a
a
document
document
in
in
Firestore
firestore
when
when
they
they
sign
sign
in
in
for
for
the
the
first
first
time.
time
So
so
all
all
we
we
have
have
to
to
do
do
is
is
bind
bind
this
this
anonymous
anonymous
login
login
method
method
to
to
a
a
button
button
click,
click
and
and
we'll
we'll
get
get
the
the
user
user
signed
signed
in
in
without
without
any
any
additional
additional
work
work
on
on
our
our
end.
end
The
the
next
next
thing
thing
we
we
wanna
wanna
do
do
is
is
Trigger
trigger
a
a
function
function
when
when
the
the
user
user
signs
signs
up.
up
So
so
go
go
into
into
the
the
index
index
TS
ts
file
file
in
in
the
the
functions
functions
directory,
directory
and
and
then
then
we'll
we'll
initialize
initialize
Firebase
firebase
admin.
admin
And
and
we'll
we'll
want
want
to
to
also
also
initialize
initialize
Stripe
stripe
with
with
our
our
secret
secret
key
key
that
that
we
we
set
set
up
up
in
in
the
the
environment
environment
earlier.
earlier
And
and
these
these
variables
variables
are
are
set
set
up
up
globally
globally
in
in
this
this
function's
function's
file
file
because
because
they'll
they'll
be
be
shared
shared
throughout
throughout
our
our
3
3
different
different
Cloud
cloud
Functions.
functions
The
the
first
first
function
function
is
is
the
the
easiest
easiest
one
one
to
to
create.
create
Basically,
basically
we're
we're
just
just
listening
listening
for
for
a
a
new
new
user
user
to
to
sign
sign
up.
up
And
and
when
when
that
that
happens,
happens
we'll
we'll
take
take
their
their
Firebase
firebase
user
user
ID,
id
use
use
that
that
to
to
create
create
a
a
new
new
user
user
in
in
Stripe,
stripe
and
and
then
then
update
update
the
the
customer
customer
ID
id
that
that
we
we
get
get
back
back
from
from
Stripe
stripe
on
on
their
their
Firestore
firestore
document.
document
So
so
we're
we're
just
just
creating
creating
a
a
one
one
to
to
one
one
connection
connection
between
between
the
the
Firebase
firebase
user
user
and
and
the
the
Stripe
stripe
user.
user
Authentication
authentication
triggers
triggers
in
in
Firebase
firebase
will
will
include
include
the
the
Firebase
firebase
user
user
ID
id
on
on
the
the
user
user
record
record
object.
object
Then
then
we'll
we'll
call
call
Stripe
stripe
customers
customers
create,
create
And
and
we'll
we'll
set
set
their
their
Firebase
firebase
user
user
ID
id
as
as
metadata
metadata
on
on
the
the
Stripe
stripe
customer.
customer
That
that
part's
part's
technically
technically
optional,
optional
but
but
it's
it's
generally
generally
a
a
good
good
idea
idea
to
to
keep
keep
track
track
of
of
things
things
between
between
the
the
two
two
platforms.
platforms
Stripe
stripe
will
will
respond
respond
with
with
an
an
object
object
of
of
the
the
newly
newly
created
created
customer,
customer
and
and
the
the
only
only
thing
thing
we
we
actually
actually
need
need
from
from
that
that
is
is
the
the
Stripe
stripe
customer
customer
ID,
id
which
which
we
we
can
can
then
then
use
use
is
is
to
to
save
save
on
on
the
the
Firestore
firestore
document.
document
So
so
that
that
takes
takes
care
care
of
of
the
the
first
first
hurdle.
hurdle
Now
now
that
that
we
we
have
have
a
a
Stripe
stripe
customer,
customer
the
the
next
next
thing
thing
we
we
need
need
to
to
do
do
is
is
collect
collect
their
their
payment
payment
source
source
and
and
then
then
attach
attach
them
them
to
to
a
a
specific
specific
subscription
subscription
plan.
plan
To
to
handle
handle
that,
that
we'll
we'll
use
use
Stripe
stripe
Elements,
elements
which
which
is
is
the
the
quickest
quickest
and
and
easiest
easiest
way
way
to
to
set
set
up
up
a
a
payment
payment
form
form
in
in
your
your
front
front
end
end
UI.
ui
The
the
very
very
first
first
thing
thing
you'll
you'll
do
do
is
is
go
go
into
into
your
your
index
index
HTML
html
file
file
and
and
add
add
the
the
Stripe
stripe
JS
js
version
version
3
3
to
to
the
the
head
head
of
of
the
the
document.
document
Then
then
we
we
can
can
go
go
into
into
our
our
payment
payment
form
form
component.
component
And
and
the
the
first
first
thing
thing
we'll
we'll
wanna
wanna
do
do
is
is
initialize
initialize
Stripe
stripe
elements,
elements
which
which
really
really
just
just
operates
operates
outside
outside
the
the
context
context
of
of
our
our
component,
component
so
so
we'll
we'll
just
just
add
add
it
it
up
up
here
here
directly
directly
in
in
the
the
code.
code
This
this
time,
time
you
you
initialize
initialize
Stripe
stripe
with
with
your
your
publishable
publishable
key.
key
You
you
don't
don't
want
want
to
to
expose
expose
your
your
secret
secret
key
key
in
in
your
your
front
front
end
end
code.
code
And
and
then
then
we'll
we'll
say
say
Stripe
stripe
elements
elements
create
create
card,
card
which
which
will
will
eventually
eventually
bind
bind
here
here
to
to
a
a
DOM
dom
element.
element
In
in
Angular,
angular
we
we
can
can
grab
grab
an
an
element
element
from
from
the
the
DOM
dom
by
by
using
using
view
view
child,
child
which
which
we'll
we'll
call
call
our
our
card
card
form.
form
And
and
we'll
we'll
be
be
using
using
a
a
callable
callable
function
function
in
in
this
this
component,
component
So
so
we
we
inject
inject
the
the
AngularFire
angularfire
function
function
service.
service
After
after
the
the
view
view
is
is
initialized,
initialized
we'll
we'll
call
call
card
card
dot
dot
mount,
mount
which
which
will
will
have
have
Stripe
stripe
elements
elements
do
do
thing
thing
on
on
this
this
specific
specific
DOM
dom
element.
element
After
after
the
the
user
user
fills
fills
out
out
the
the
form,
form
we
we
need
need
to
to
send
send
the
the
card
card
details
details
to
to
Stripe,
stripe
which
which
will
will
then
then
respond
respond
with
with
a
a
token
token
that
that
we
we
can
can
use
use
to
to
attach
attach
the
the
payment
payment
source
source
to
to
the
the
user
user
in
in
our
our
back
back
end.
end
For
for
that,
that
we
we
can
can
call
call
Stripe
stripe
create
create
token.
token
And
and
I'm
i'm
not
not
showing
showing
it
it
here,
here
but
but
you
you
should
should
also
also
handle
handle
errors
errors
here
here
as
as
well.
well
But
but
assuming
assuming
we
we
have
have
a
a
valid
valid
card,
card
we
we
can
can
then
then
call
call
our
our
callable
callable
function,
function
which
which
we'll
we'll
name
name
start
start
subscription.
subscription
So
so
this
this
is
is
an
an
alternative
alternative
to
to
using
using
the
the
HTTP
http
module
module
in
in
Angular.
angular
Normally,
normally
we
we
would
would
have
have
to
to
set
set
the
the
authorization
authorization
header
header
for
for
the
the
logged
logged
in
in
user
user
and
and
then
then
decode
decode
it
it
in
in
our
our
Cloud
cloud
Function.
function
So
so
the
the
beauty
beauty
of
of
a
a
callable
callable
function
function
is
is
that
that
we
we
don't
don't
have
have
to
to
do
do
any
any
of
of
that.
that
We
we
can
can
just
just
pass
pass
in
in
the
the
source
source
that
that
we
we
get
get
back
back
from
from
Stripe,
stripe
and
and
we'll
we'll
already
already
know
know
the
the
context
context
of
of
the
the
user
user
when
when
this
this
function
function
gets
gets
triggered.
triggered
Then
then
if
if
we
we
switch
switch
over
over
to
to
the
the
HTML,
html
all
all
we
we
have
have
to
to
do
do
is
is
set
set
up
up
a
a
form
form
and
and
then
then
we'll
we'll
bind
bind
to
to
the
the
submit
submit
event
event
on
on
this
this
form
form
and
and
trigger
trigger
that
that
handler
handler
that
that
we
we
just
just
wrote.
wrote
The
the
only
only
other
other
thing
thing
to
to
do
do
is
is
set
set
up
up
a
a
div
div
for
for
Stripe
stripe
elements
elements
to
to
attach
attach
to,
to
which
which
we
we
can
can
do
do
with
with
hash
hash
card
card
form.
form
That
that
takes
takes
care
care
of
of
the
the
front
front
end
end
code.
code
Now
now
we'll
we'll
write
write
the
the
back
back
end
end
code
code
for
for
that
that
callable
callable
function.
function
We
we
can
can
go
go
ahead
ahead
and
and
say
say
functions,
functions
https
https
on
on
call,
call
And
and
that
that
gives
gives
us
us
access
access
to
to
the
the
data
data
that
that
we
we
pass
pass
from
from
the
the
front
front
end,
end
which
which
is
is
the
the
Stripe
stripe
token
token
that
that
we
we
need
need
to
to
use
use
to
to
attach
attach
to
to
the
the
user.
user
And,
and
again,
again
we
we
have
have
access
access
to
to
the
the
caller
caller
of
of
this
this
function,
function
which
which
we
we
can
can
get
get
with
with
context
context
dot
dot
authuid.
authuid
Now
now
that
that
we
we
have
have
this
this
information,
information
we
we
can
can
go
go
ahead
ahead
and
and
pull
pull
that
that
user's
user's
There's
there's
document
document
from
from
Firestore
firestore
which
which
contains
contains
the
the
Stripe
stripe
customer
customer
ID.
id
So
so
now
now
we
we
have
have
all
all
the
the
information
information
we
we
need
need
to
to
attach
attach
the
the
payment
payment
token
token
to
to
the
the
Stripe
stripe
customer.
customer
We
we
make
make
that
that
happen
happen
by
by
calling
calling
Stripe
stripe
create
create
source
source
with
with
the
the
customer
customer
ID
id
as
as
well
well
as
as
the
the
token
token
that
that
we
we
passed
passed
through
through
this
this
callable
callable
function.
function
And
and
while
while
we're
we're
here,
here
I'd
i'd
like
like
to
to
point
point
out
out
that
that
we
we
handle
handle
errors
errors
a
a
little
little
bit
bit
differently
differently
than
than
other
other
HTTP
http
functions.
functions
Instead
instead
of
of
sending
sending
an
an
error
error
response,
response
we
we
can
can
just
just
throw
throw
an
an
error
error
directly
directly
And
and
the
the
callable
callable
function
function
will
will
send
send
that
that
back
back
down
down
to
to
the
the
client.
client
But
but
assuming
assuming
that
that
the
the
payment
payment
source
source
attaches
attaches
successfully,
successfully
the
the
next
next
step
step
is
is
to
to
subscribe
subscribe
this
this
user
user
to
to
our
our
actual
actual
plan
plan
that
that
we
we
created
created
in
in
Stripe
stripe
at
at
the
the
beginning
beginning
of
of
this
this
process.
process
So
so
we'll
we'll
go
go
ahead
ahead
and
and
call
call
Stripe
stripe
subscriptions
subscriptions
create
create
And
and
pass
pass
in
in
the
the
Stripe
stripe
user
user
ID
id
as
as
well
well
as
as
the
the
plan
plan
that
that
we
we
want
want
to
to
subscribe
subscribe
them
them
to.
to
I'm
i'm
just
just
hard
hard
coding
coding
it
it
here,
here
but
but
most
most
likely
likely
you
you
would
would
Set
set
that
that
up
up
as
as
an
an
environment
environment
variable
variable
or
or
send
send
it
it
through
through
the
the
callable
callable
function.
function
And
and
lastly,
lastly
that
that
will
will
respond
respond
with
with
some
some
data
data
And
and
we'll
we'll
use
use
that
that
data
data
to
to
update
update
the
the
Firestore
firestore
document.
document
So
so
at
at
this
this
point,
point
we
we
have
have
a
a
system
system
where
where
the
the
user
user
can
can
submit
submit
their
their
payment
payment
And
and
it
it
updates
updates
their
their
document
document
with
with
the
the
subscription
subscription
information
information
from
from
Stripe.
stripe
The
the
final
final
thing
thing
we
we
need
need
to
to
do
do
is
is
report
report
usage
usage
to
to
Stripe.
stripe
Otherwise,
otherwise
we're
we're
not
not
gonna
gonna
get
get
paid
paid
for
for
anything.
anything
So
so
in
in
this
this
app
app
here,
here
I've
i've
set
set
it
it
up
up
so
so
the
the
user
user
can
can
create
create
a
a
hypothetical
hypothetical
project,
project
which
which
is
is
just
just
creating
creating
a
a
new
new
document
document
in
in
Fire
fire
store
store
that
that
lives
lives
in
in
the
the
projects
projects
collection.
collection
I'm
i'm
not
not
really
really
gonna
gonna
focus
focus
on
on
the
the
front
front
end
end
code
code
here
here
because
because
it's
it's
really
really
simple,
simple
just
just
adding
adding
a
a
document
document
to
to
Firestore,
firestore
But
but
you
you
can
can
find
find
the
the
full
full
source
source
code
code
in
in
the
the
link
link
in
in
the
the
description.
description
The
the
interesting
interesting
part
part
here
here
is
is
our
our
3rd
3rd
and
and
final
final
cloud
cloud
function.
function
We'll
we'll
call
call
this
this
the
the
update
update
usage
usage
function,
function
And
and
it
it
will
will
run
run
whenever
whenever
a
a
new
new
document
document
is
is
created
created
in
in
the
the
projects
projects
collection.
collection
And
and
the
the
process
process
is
is
pretty
pretty
similar.
similar
We
we
have
have
a
a
user
user
ID
id
that's
that's
on
on
that
that
project
project
document
document
to
to
associate
associate
it
it
with
with
the
the
Firebase
firebase
user.
user
So
so
we
we
can
can
then
then
pull
pull
their
their
Firestore
firestore
document
document
information,
information
which
which
has
has
the
the
subscription
subscription
information
information
that
that
we
we
need
need
to
to
report
report
usage
usage
to.
to
So
so
we'll
we'll
retrieve
retrieve
the
the
user
user
document
document
like
like
we
we
did
did
in
in
previous
previous
functions
functions
And
and
then
then
we'll
we'll
call
call
Stripe
stripe
usage
usage
records
records
create,
create
and
and
we'll
we'll
create
create
a
a
new
new
usage
usage
record
record
with
with
the
the
item
item
ID
id
on
on
that
that
subscription.
subscription
This
this
can
can
be
be
kind
kind
of
of
confusing
confusing
because
because
you
you
might
might
have
have
multiple
multiple
items
items
on
on
a
a
single
single
subscription.
subscription
For
for
example,
example
think
think
about
about
the
the
way
way
Firebase
firebase
bills.
bills
You
you
have
have
different
different
quotas
quotas
for
for
storage,
storage
database
database
functions,
functions
etcetera,
etcetera
and
and
you're
you're
billed
billed
separately
separately
for
for
each.
each
That's
that's
exactly
exactly
the
the
kind
kind
of
of
stuff
stuff
that
that
Stripe
stripe
Billing
billing
allows
allows
you
you
to
to
do.
do
You
you
can
can
send
send
usage
usage
records
records
to
to
Stripe
stripe
1
1
at
at
a
a
time
time
or
or
you
you
can
can
aggregate
aggregate
them
them
together
together
and
and
send
send
a
a
higher
higher
quantity
quantity
based
based
on
on
the
the
amount
amount
of
of
volume
volume
that
that
flows
flows
through
through
your
your
app.
app
You'll
you'll
need
need
to
to
set
set
a
a
time
time
stamp
stamp
in
in
unit
unit
seconds,
seconds
So
so
convert
convert
the
the
JavaScript
javascript
millisecond
millisecond
date
date
into
into
plain
plain
seconds.
seconds
Then
then
it's
it's
always
always
a
a
good
good
idea
idea
to
to
set
set
an
an
item
item
potency
potency
key,
key
which
which
you
you
can
can
do
do
with
with
the
the
snapshot
snapshot
ID.
id
That'll
that'll
just
just
guarantee
guarantee
that
that
the
the
user's
user's
usage
usage
will
will
be
be
consistent
consistent
even
even
if
if
this
this
Cloud
cloud
function
function
gets
gets
invoked
invoked
multiple
multiple
times,
times
which
which
is
is
possible.
possible
Then
then
the
the
final
final
thing
thing
we'll
we'll
do
do
is
is
Update
update
the
the
user's
user's
record
record
in
in
Firestore
firestore
just
just
so
so
we
we
can
can
show
show
an
an
estimated
estimated
bill
bill
for
for
them
them
as
as
well.
well
Now
now
whenever
whenever
you
you
create
create
a
a
new
new
document
document
in
in
Firestore,
firestore
this
this
user's
user's
bill
bill
will
will
be
be
updated
updated
and
and
then
then
Stripe
stripe
will
will
charge
charge
them
them
for
for
it
it
at
at
the
the
end
end
of
of
the
the
month.
month
I've
i've
been
been
doing
doing
this
this
for
for
a
a
while
while
and
and
it's
it's
pretty
pretty
amazing
amazing
that
that
we
we
can
can
build
build
a
a
feature
feature
like
like
this
this
in
in
a
a
completely
completely
serverless
serverless
way
way
and
and
at
at
Zero
zero
cost
cost
for
for
us
us
initially
initially
when
when
building
building
our
our
minimum
minimum
viable
viable
product.
product
I'm
i'm
gonna
gonna
go
go
and
and
wrap
wrap
things
things
up
up
there.
there
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
subscribe,
subscribe
and
and
don't
don't
forget
forget
to
to
join
join
us
us
on
on
Angular
angular
Academy
academy
today
today
again
again
at
at
1
1
PM
pm
Pacific
pacific
Time.
time
And
and
if
if
you're
you're
not
not
already
already
a
a
Pro
pro
member,
member
make
make
sure
sure
to
to
Sign
sign
up
up
to
to
get
get
access
access
to
to
all
all
kinds
kinds
of
of
exclusive
exclusive
content
content
designed
designed
to
to
help
help
you
you
build
build
and
and
ship
ship
your
your
app
app
faster.
faster
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The new Stripe billing platform allows complex subscription payments through a subscription plan based on usage volume. They demonstrate how to use the Cloud function in the Angular app to set up a payment plan and generate an invoice, and provide instructions on creating a payment plan and customizing billing plans. The process includes setting up a payment plan, creating a new customer ID, and updating a user's record in Fir analysis. The new Stripe platform also allows for payment sources and subscriptions for users, and provides instructions on how to update a user's record in Fir analysis.
Stripe Billing - Get Paid for your SaaS
Back in April, Stripe payments released a new billing platform that makes complex subscription payments easier than ever. To demonstrate this tool, we're to build a pretty ambitious feature. A subscription plan that doesn't get billed on a fixed rate, but rather based on the user's volume of usage within the app. The goal is to give you a foundation for building your own software as a service type application that has a pay as you go payment plan. If you're new here, make sure to like and And also a little later today at 1 pm Pacific Time or 7 pm GMT, I will be appearing on the Angular Academy show. So make sure to register so you can live chat with myself and the world famous David East. To get started with this project, you'll need to have a Stripe account and we'll be making heavy Use of Firebase functions. There's a new tool in Firebase that makes a feature like this much easier to build than it was a few months ago, and that's thanks to callable functions. Basically, a callable function is just like an HTTP function, except that it sends the context for the authenticated user. This is extremely powerful because it means you don't have to set your own authorization headers in the front end or have to decode them on the back end, which means a lot less code to write and test. We'll be writing 3 different Cloud Functions, so let's walk through this step by step. The first one is an auth function that happens after the user logs in and sets up their account with Stripe customer ID. After we have the customer ID set up, the next major milestone is to collect a payment source and sign up a user for the subscription plan. We'll implement Stripe Elements to collect and validate the credit card from the user. Then when they click the submit payment button, it will trigger our callable function with the auth context so we can securely attach that credit card to the user in our back end. That signs the user up for the plan and writes a bunch of information to their Firestore user document. But at this point, their estimated bill is 0 because they haven't actually done anything in the app. In this particular app, we will charge the user $1 per month for every project that they create. If we click this create project button, it will create a document in Firestore which again triggers another Cloud function. This 3rd and final cloud function will report usage to Stripe, so we know what to bill them for a given month. So if we create a couple more projects here, you'll see that our estimated bill jumps up to $3 per month. And we can also see this in the Stripe dashboard where we have an upcoming invoice for $3 for the subscriber. And we can inspect all the usage events, which again will get reported via our cloud function. Before we write any code, let's start with the fun part which is setting up the actual billing plan in Stripe. The first thing you'll do is set up your product, which is an entity that can hold multiple payment plans. So for example, a pro subscription would be product and then I might have multiple plans for weekly, monthly, or quarterly. For this demo here, we'll just set up a single payment plan and we'll make sure to make it a metered Usage plan. There's a whole bunch of ways you can customize the plan. For example, you might have tiers for different levels of volume usage Or you might have different ways of aggregating the actual usage through the payment period. The whole idea behind Stripe Billing is to allow you, the developer, to build a complex payment system without having to write a whole bunch of code to maintain it. When you're finished, you'll have a product ID and a plan The make a note of the plan ID because we'll need that later in the Cloud Function. Now we're going to switch gears into our Angular app and initialize Firebase Cloud Functions. You'll want to select the TypeScript option. Just go with the defaults and everything else, then cd into the functions directory and run npm install Stripe. Then the other thing we need to do is set up our Stripe secret key in the Cloud Functions environment. You can find it on the Stripe dashboard, and I would recommend using that test data so you're not working with live payment information. Then run Firebase functions config set stripe dot secret with your secret key, And this will securely store it in our functions environment. At this point, we're going to be jumping back and forth between our front end and back end code, so I'll do my best to keep that clear, but the first thing we'll do is implement our front end user authentication code. I'm going to go over that quickly because I cover it in detail on episode 55, And this demo uses the same system with some slight modifications. I'd first like to point out that we have AngularFire 2 installed, and we have auth, Firestore, as well as the New AngularFire functions module. So you wanna make sure you have an app module that looks something like this. And you'll also notice that I generated a payment form component and project manager component with the Angular CLI that we'll build out here in the following steps. But the first thing we'll do is quickly go through the auth service to get our user logged in to our Firebase app. One of the key differences from episode 55 is that we have additional properties on the user interface, mainly the Stripe customer ID as well as some information about the subscription itself. We have AngularFire 2 installed here, so we can inject AngularFire auth and Firestore in the constructor. And then we'll represent our user as an observable of a Firestore document. If the user's authenticated, then we'll go ahead and retrieve their document from Firestore. Otherwise, we'll just return an observable of null, which means the user's not Signed in. The rest of this demo is compatible with any auth method in Firebase, but I'm just going to use anonymous auth because it requires the least amount of code to set up. What this code here is doing is it's logging in the user anonymously, and then it's creating a document in Firestore when they sign in for the first time. So all we have to do is bind this anonymous login method to a button click, and we'll get the user signed in without any additional work on our end. The next thing we wanna do is Trigger a function when the user signs up. So go into the index TS file in the functions directory, and then we'll initialize Firebase admin. And we'll want to also initialize Stripe with our secret key that we set up in the environment earlier. And these variables are set up globally in this function's file because they'll be shared throughout our 3 different Cloud Functions. The first function is the easiest one to create. Basically, we're just listening for a new user to sign up. And when that happens, we'll take their Firebase user ID, use that to create a new user in Stripe, and then update the customer ID that we get back from Stripe on their Firestore document. So we're just creating a one to one connection between the Firebase user and the Stripe user. Authentication triggers in Firebase will include the Firebase user ID on the user record object. Then we'll call Stripe customers create, And we'll set their Firebase user ID as metadata on the Stripe customer. That part's technically optional, but it's generally a good idea to keep track of things between the two platforms. Stripe will respond with an object of the newly created customer, and the only thing we actually need from that is the Stripe customer ID, which we can then use is to save on the Firestore document. So that takes care of the first hurdle. Now that we have a Stripe customer, the next thing we need to do is collect their payment source and then attach them to a specific subscription plan. To handle that, we'll use Stripe Elements, which is the quickest and easiest way to set up a payment form in your front end UI. The very first thing you'll do is go into your index HTML file and add the Stripe JS version 3 to the head of the document. Then we can go into our payment form component. And the first thing we'll wanna do is initialize Stripe elements, which really just operates outside the context of our component, so we'll just add it up here directly in the code. This time, you initialize Stripe with your publishable key. You don't want to expose your secret key in your front end code. And then we'll say Stripe elements create card, which will eventually bind here to a DOM element. In Angular, we can grab an element from the DOM by using view child, which we'll call our card form. And we'll be using a callable function in this component, So we inject the AngularFire function service. After the view is initialized, we'll call card dot mount, which will have Stripe elements do thing on this specific DOM element. After the user fills out the form, we need to send the card details to Stripe, which will then respond with a token that we can use to attach the payment source to the user in our back end. For that, we can call Stripe create token. And I'm not showing it here, but you should also handle errors here as well. But assuming we have a valid card, we can then call our callable function, which we'll name start subscription. So this is an alternative to using the HTTP module in Angular. Normally, we would have to set the authorization header for the logged in user and then decode it in our Cloud Function. So the beauty of a callable function is that we don't have to do any of that. We can just pass in the source that we get back from Stripe, and we'll already know the context of the user when this function gets triggered. Then if we switch over to the HTML, all we have to do is set up a form and then we'll bind to the submit event on this form and trigger that handler that we just wrote. The only other thing to do is set up a div for Stripe elements to attach to, which we can do with hash card form. That takes care of the front end code. Now we'll write the back end code for that callable function. We can go ahead and say functions, https on call, And that gives us access to the data that we pass from the front end, which is the Stripe token that we need to use to attach to the user. And, again, we have access to the caller of this function, which we can get with context dot authuid. Now that we have this information, we can go ahead and pull that user's There's document from Firestore which contains the Stripe customer ID. So now we have all the information we need to attach the payment token to the Stripe customer. We make that happen by calling Stripe create source with the customer ID as well as the token that we passed through this callable function. And while we're here, I'd like to point out that we handle errors a little bit differently than other HTTP functions. Instead of sending an error response, we can just throw an error directly And the callable function will send that back down to the client. But assuming that the payment source attaches successfully, the next step is to subscribe this user to our actual plan that we created in Stripe at the beginning of this process. So we'll go ahead and call Stripe subscriptions create And pass in the Stripe user ID as well as the plan that we want to subscribe them to. I'm just hard coding it here, but most likely you would Set that up as an environment variable or send it through the callable function. And lastly, that will respond with some data And we'll use that data to update the Firestore document. So at this point, we have a system where the user can submit their payment And it updates their document with the subscription information from Stripe. The final thing we need to do is report usage to Stripe. Otherwise, we're not gonna get paid for anything. So in this app here, I've set it up so the user can create a hypothetical project, which is just creating a new document in Fire store that lives in the projects collection. I'm not really gonna focus on the front end code here because it's really simple, just adding a document to Firestore, But you can find the full source code in the link in the description. The interesting part here is our 3rd and final cloud function. We'll call this the update usage function, And it will run whenever a new document is created in the projects collection. And the process is pretty similar. We have a user ID that's on that project document to associate it with the Firebase user. So we can then pull their Firestore document information, which has the subscription information that we need to report usage to. So we'll retrieve the user document like we did in previous functions And then we'll call Stripe usage records create, and we'll create a new usage record with the item ID on that subscription. This can be kind of confusing because you might have multiple items on a single subscription. For example, think about the way Firebase bills. You have different quotas for storage, database functions, etcetera, and you're billed separately for each. That's exactly the kind of stuff that Stripe Billing allows you to do. You can send usage records to Stripe 1 at a time or you can aggregate them together and send a higher quantity based on the amount of volume that flows through your app. You'll need to set a time stamp in unit seconds, So convert the JavaScript millisecond date into plain seconds. Then it's always a good idea to set an item potency key, which you can do with the snapshot ID. That'll just guarantee that the user's usage will be consistent even if this Cloud function gets invoked multiple times, which is possible. Then the final thing we'll do is Update the user's record in Firestore just so we can show an estimated bill for them as well. Now whenever you create a new document in Firestore, this user's bill will be updated and then Stripe will charge them for it at the end of the month. I've been doing this for a while and it's pretty amazing that we can build a feature like this in a completely serverless way and at Zero cost for us initially when building our minimum viable product. I'm gonna go and wrap things up there. If this video helped you, please like subscribe, and don't forget to join us on Angular Academy today again at 1 PM Pacific Time. And if you're not already a Pro member, make sure to Sign up to get access to all kinds of exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
The new Stripe billing platform allows complex subscription payments through a subscription plan based on usage volume. They demonstrate how to use the Cloud function in the Angular app to set up a payment plan and generate an invoice, and provide instructions on creating a payment plan and customizing billing plans. The process includes setting up a payment plan, creating a new customer ID, and updating a user's record in Fir analysis. The new Stripe platform also allows for payment sources and subscriptions for users, and provides instructions on how to update a user's record in Fir analysis.