Full Code and Lesson: https://angularfirebase.com/lessons/angular-stripe-payments-part-3-sell-digital-content/

This is the third installment of Stripe Payments with Angular 4 and Firebase. Learn how to sell digital content, make atomic updates, and manage user balances. 

Get the book: https://leanpub.com/angularfirebase
2024-02-04T08:23:35.970Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
024d8071-4a08-4a7c-8c64-cb0d0aa819f9
82b89fd244700d8ad479aab33e9ad569dda5fcf79200f4d975d3f6ae1240af79
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Welcome to part 3 of Stripe payments with Angular and Firebase.
In the last two episodes, we integrated Stripe checkout and charged the card with Firebase Cloud Functions.
Functions.
In this 3rd episode, we're going to use that charge to enable the user to purchase digital content in our app.
In this example, we keep a balance on the user's account, which can be increased by making payments or decreased by purchasing content.
When a user has sufficient funds on their account, they can click a button that will bring up a modal window to confirm or cancel the purchase.
If they click confirm, their account balance is automatically updated with the new balance.
The database will be updated with a purchases collection, which tracks the user ID and the item IDs that they've purchased.
The user's current balance will be tracked on their actual account with a new property called balance, which takes a number.
Let's start by updating the cloud function.
We need it to update both the charge as well as the user's balance in the same operation.
We want it to be atomic, meaning if the charge fails, The user balance update will fail also and vice versa.
The first step is to create a balance variable that defaults to 0.
And then when we get the customer record, we'll update it with their existing balance.
When we get the Stripe charge back, we'll first check to make sure it exists, And we'll also check to make sure that it's actually paid.
If these conditions are met, we create an object where the key is a reference point in the database and the value is the data we wanna update.
This allows us to update multiple database locations at the same time.
But be careful, it performs a set operation, so Make sure you point to the very deepest node that you wanna update.
Now we can use the charge amount from Stripe to increase the user's balance And then send these updates together to the root of the database.
Back in the app, we can see the user's balance is updated by the Cloud Function when they make a payment.
Now we need to update the service to handle the payment process.
In order to get the user balance, We first need the auth user ID, so we'll use the switch map operator on the AngularFire auth observable.
We'll move this out into its own function and then subscribe to it in the constructor.
The balance itself will be emitted as an object, So we just want to map that object to its actual value, so we just get a number back in the observable.
From there, we need to determine if a user has already purchased a product, which we can do by seeing if that key exists under their purchases in the database.
This will also return an observable and will map it to a boolean value to get the true false value back instead of the entire object itself.
And the last step is to create a function that enables the user to actually make purchase.
It requires the unique ID of the item being purchased as well as the amount, and it records the timestamp from the Firebase server.
This will guarantee your time stamps are consistent, which would not be the case if you just use the JavaScript date object.
This function also needs to make an atomic update to update the balance as well as the purchase history in the same operation.
So we'll create another updates object and pass it the corresponding data.
The user balance gets decreased by the amount of the purchase and the purchase history gets the purchase object.
We can then pass these updates to the root of the database and call the update function.
Now let's create a new component called the buy now component.
It's designed to be reusable, so we'll take the buyable ID as well as the amount from the parent component.
The buyable ID just represents any item that can be purchased.
We also create a variable to toggle the visibility of the modal.
During ng on init, we define the variables for the user balance observable and the has purchased observable.
Then we create an event handler to change the visibility of the modal.
And the last function we need is for the user to actually confirm the purchase.
So this will just run the buy digital content function that we defined in the service.
When the purchase is complete, we close the modal.
And you could also consider adding a success message or confirmation at this point.
But before we get into the HTML, we're going to create a custom Stripe pipe to format the currency amounts.
This is strictly for the user, and it will turn the value into a string with the proper decimal amount.
Stripe amounts are 1 100th of the underlying currency, so 500 in Stripe equals 5 US dollars.
From a parent component, we passed the unique ID as well as the price to the buy now component.
In the component itself, we add the is active class when the Show modal variable is true.
This is specific to Bulma CSS.
We can unwrap the balance observable to see if the user has sufficient funds on their account to make the purchase.
If so, we'll show them the confirm or cancel buttons.
We can also show the user what their current balance is and what their balance will look like after the purchase.
The confirm button will actually make the purchase and the cancel button will just toggle the modal back to false.
If the user doesn't have enough money, we'll show different modal content that says insufficient funds with their current balance.
The last step is to create a button that will open the modal in the first place.
If the user has already purchased the item, then we'll go ahead and just Show button that says already purchased that's disabled.
Notice how we always unwrap the observables in parentheses using the async pipe and then call any logic outside those parenthesis.
Before we start using the system, let's also add some back end data security rules on Firebase.
When a purchase is made, we wanna make sure that user ID always matches the current auth user ID.
And we also wanna prevent purchases from being updated or deleted after they've been created.
So if the data exists, then we won't allow any write operations to take place.
Now going back to the app, we can take a look and make sure that everything is working as expected.
I currently have $5 on my account, which is insufficient to buy product.
So we'll add additional credits through Stripe, which should increase the account balance from $5 to 20 5 dollars.
And we'll see the account balance here update asynchronously once it's done processing in Stripe.
And now we have sufficient funds on the account, so we should be able to go ahead and buy the product.
That pulls up the confirmation screen.
If we click confirm, it should reduce the balance by $20, which it does.
So now we're back at $5 again, and we have access to the product.
That's it for Stripe Payments.
If this video helped you, please like and subscribe.
And if you want a free copy of that book, the Angular Firebase Survival Guide, Consider becoming a pro member for just $9 a month.
You'll get a free copy of that book, as well as access to our pro channel on Slack for 1 on 1 project consulting.
Thanks for watching, and I'll see you next time.

Speaker 0: Welcome to part 3 of Stripe payments with Angular and Firebase. In the last two episodes, we integrated Stripe checkout and charged the card with Firebase Cloud Functions. Functions. In this 3rd episode, we're going to use that charge to enable the user to purchase digital content in our app. In this example, we keep a balance on the user's account, which can be increased by making payments or decreased by purchasing content.

When a user has sufficient funds on their account, they can click a button that will bring up a modal window to confirm or cancel the purchase. If they click confirm, their account balance is automatically updated with the new balance. The database will be updated with a purchases collection, which tracks the user ID and the item IDs that they've purchased. The user's current balance will be tracked on their actual account with a new property called balance, which takes a number. Let's start by updating the cloud function.

We need it to update both the charge as well as the user's balance in the same operation. We want it to be atomic, meaning if the charge fails, The user balance update will fail also and vice versa. The first step is to create a balance variable that defaults to 0. And then when we get the customer record, we'll update it with their existing balance. When we get the Stripe charge back, we'll first check to make sure it exists, And we'll also check to make sure that it's actually paid.

If these conditions are met, we create an object where the key is a reference point in the database and the value is the data we wanna update. This allows us to update multiple database locations at the same time. But be careful, it performs a set operation, so Make sure you point to the very deepest node that you wanna update. Now we can use the charge amount from Stripe to increase the user's balance And then send these updates together to the root of the database. Back in the app, we can see the user's balance is updated by the Cloud Function when they make a payment.

Now we need to update the service to handle the payment process. In order to get the user balance, We first need the auth user ID, so we'll use the switch map operator on the AngularFire auth observable. We'll move this out into its own function and then subscribe to it in the constructor. The balance itself will be emitted as an object, So we just want to map that object to its actual value, so we just get a number back in the observable. From there, we need to determine if a user has already purchased a product, which we can do by seeing if that key exists under their purchases in the database.

This will also return an observable and will map it to a boolean value to get the true false value back instead of the entire object itself. And the last step is to create a function that enables the user to actually make purchase. It requires the unique ID of the item being purchased as well as the amount, and it records the timestamp from the Firebase server. This will guarantee your time stamps are consistent, which would not be the case if you just use the JavaScript date object. This function also needs to make an atomic update to update the balance as well as the purchase history in the same operation.

So we'll create another updates object and pass it the corresponding data. The user balance gets decreased by the amount of the purchase and the purchase history gets the purchase object. We can then pass these updates to the root of the database and call the update function. Now let's create a new component called the buy now component. It's designed to be reusable, so we'll take the buyable ID as well as the amount from the parent component.

The buyable ID just represents any item that can be purchased. We also create a variable to toggle the visibility of the modal. During ng on init, we define the variables for the user balance observable and the has purchased observable. Then we create an event handler to change the visibility of the modal. And the last function we need is for the user to actually confirm the purchase.

So this will just run the buy digital content function that we defined in the service. When the purchase is complete, we close the modal. And you could also consider adding a success message or confirmation at this point. But before we get into the HTML, we're going to create a custom Stripe pipe to format the currency amounts. This is strictly for the user, and it will turn the value into a string with the proper decimal amount.

Stripe amounts are 1 100th of the underlying currency, so 500 in Stripe equals 5 US dollars. From a parent component, we passed the unique ID as well as the price to the buy now component. In the component itself, we add the is active class when the Show modal variable is true. This is specific to Bulma CSS. We can unwrap the balance observable to see if the user has sufficient funds on their account to make the purchase.

If so, we'll show them the confirm or cancel buttons. We can also show the user what their current balance is and what their balance will look like after the purchase. The confirm button will actually make the purchase and the cancel button will just toggle the modal back to false. If the user doesn't have enough money, we'll show different modal content that says insufficient funds with their current balance. The last step is to create a button that will open the modal in the first place.

If the user has already purchased the item, then we'll go ahead and just Show button that says already purchased that's disabled. Notice how we always unwrap the observables in parentheses using the async pipe and then call any logic outside those parenthesis. Before we start using the system, let's also add some back end data security rules on Firebase. When a purchase is made, we wanna make sure that user ID always matches the current auth user ID. And we also wanna prevent purchases from being updated or deleted after they've been created.

So if the data exists, then we won't allow any write operations to take place. Now going back to the app, we can take a look and make sure that everything is working as expected. I currently have $5 on my account, which is insufficient to buy product. So we'll add additional credits through Stripe, which should increase the account balance from $5 to 20 5 dollars. And we'll see the account balance here update asynchronously once it's done processing in Stripe.

And now we have sufficient funds on the account, so we should be able to go ahead and buy the product. That pulls up the confirmation screen. If we click confirm, it should reduce the balance by $20, which it does. So now we're back at $5 again, and we have access to the product. That's it for Stripe Payments.

If this video helped you, please like and subscribe. And if you want a free copy of that book, the Angular Firebase Survival Guide, Consider becoming a pro member for just $9 a month. You'll get a free copy of that book, as well as access to our pro channel on Slack for 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
Welcome to part 3 of Stripe payments with Angular and Firebase. In the last two episodes, we integrated Stripe checkout and charged the card with Firebase Cloud Functions. Functions. In this 3rd episode, we're going to use that charge to enable the user to purchase digital content in our app. In this example, we keep a balance on the user's account, which can be increased by making payments or decreased by purchasing content. When a user has sufficient funds on their account, they can click a button that will bring up a modal window to confirm or cancel the purchase. If they click confirm, their account balance is automatically updated with the new balance. The database will be updated with a purchases collection, which tracks the user ID and the item IDs that they've purchased. The user's current balance will be tracked on their actual account with a new property called balance, which takes a number.
billing
purchasing
customers
banking
databases
finance
customer support
Let's start by updating the cloud function.
We need it to update both the charge as well as the user's balance in the same operation. We want it to be atomic, meaning if the charge fails, The user balance update will fail also and vice versa. The first step is to create a balance variable that defaults to 0. And then when we get the customer record, we'll update it with their existing balance. When we get the Stripe charge back, we'll first check to make sure it exists, And we'll also check to make sure that it's actually paid. If these conditions are met, we create an object where the key is a reference point in the database and the value is the data we wanna update. This allows us to update multiple database locations at the same time. But be careful, it performs a set operation, so Make sure you point to the very deepest node that you wanna update. Now we can use the charge amount from Stripe to increase the user's balance And then send these updates together to the root of the database. Back in the app, we can see the user's balance is updated by the Cloud Function when they make a payment. Now we need to update the service to handle the payment process.
databases
billing
data management
atomic physics
In order to get the user balance, We first need the auth user ID, so we'll use the switch map operator on the AngularFire auth observable.
We'll move this out into its own function and then subscribe to it in the constructor. The balance itself will be emitted as an object, So we just want to map that object to its actual value, so we just get a number back in the observable. From there, we need to determine if a user has already purchased a product, which we can do by seeing if that key exists under their purchases in the database.
data
This will also return an observable and will map it to a boolean value to get the true false value back instead of the entire object itself. And the last step is to create a function that enables the user to actually make purchase. It requires the unique ID of the item being purchased as well as the amount, and it records the timestamp from the Firebase server. This will guarantee your time stamps are consistent, which would not be the case if you just use the JavaScript date object. This function also needs to make an atomic update to update the balance as well as the purchase history in the same operation. So we'll create another updates object and pass it the corresponding data. The user balance gets decreased by the amount of the purchase and the purchase history gets the purchase object. We can then pass these updates to the root of the database and call the update function. Now let's create a new component called the buy now component. It's designed to be reusable, so we'll take the buyable ID as well as the amount from the parent component. The buyable ID just represents any item that can be purchased. We also create a variable to toggle the visibility of the modal. During ng on init, we define the variables for the user balance observable and the has purchased observable. Then we create an event handler to change the visibility of the modal. And the last function we need is for the user to actually confirm the purchase.
So this will just run the buy digital content function that we defined in the service. When the purchase is complete, we close the modal. And you could also consider adding a success message or confirmation at this point. But before we get into the HTML, we're going to create a custom Stripe pipe to format the currency amounts.
commerce
This is strictly for the user, and it will turn the value into a string with the proper decimal amount. Stripe amounts are 1 100th of the underlying currency, so 500 in Stripe equals 5 US dollars. From a parent component, we passed the unique ID as well as the price to the buy now component.
taxes
In the component itself, we add the is active class when the Show modal variable is true.
This is specific to Bulma CSS. We can unwrap the balance observable to see if the user has sufficient funds on their account to make the purchase. If so, we'll show them the confirm or cancel buttons. We can also show the user what their current balance is and what their balance will look like after the purchase.
banking
customers
customer support
finance
accounting
The confirm button will actually make the purchase and the cancel button will just toggle the modal back to false. If the user doesn't have enough money, we'll show different modal content that says insufficient funds with their current balance. The last step is to create a button that will open the modal in the first place. If the user has already purchased the item, then we'll go ahead and just Show button that says already purchased that's disabled. Notice how we always unwrap the observables in parentheses using the async pipe and then call any logic outside those parenthesis. Before we start using the system, let's also add some back end data security rules on Firebase. When a purchase is made, we wanna make sure that user ID always matches the current auth user ID. And we also wanna prevent purchases from being updated or deleted after they've been created.
So if the data exists, then we won't allow any write operations to take place. Now going back to the app, we can take a look and make sure that everything is working as expected. I currently have $5 on my account, which is insufficient to buy product. So we'll add additional credits through Stripe, which should increase the account balance from $5 to 20 5 dollars. And we'll see the account balance here update asynchronously once it's done processing in Stripe. And now we have sufficient funds on the account, so we should be able to go ahead and buy the product. That pulls up the confirmation screen. If we click confirm, it should reduce the balance by $20, which it does. So now we're back at $5 again, and we have access to the product. That's it for Stripe Payments. If this video helped you, please like and subscribe. And if you want a free copy of that book, the Angular Firebase Survival Guide, Consider becoming a pro member for just $9 a month. You'll get a free copy of that book, as well as access to our pro channel on Slack for 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
books
billing
finance
publishing
banking
purchasing
revenue
customer support
accounting
literature
youtube
documentary
reading
Welcome to part 3 of Stripe payments with Angular and Firebase. In the last two episodes, we integrated Stripe checkout and charged the card with Firebase Cloud Functions. Functions. In this 3rd episode, we're going to use that charge to enable the user to purchase digital content in our app. In this example, we keep a balance on the user's account, which can be increased by making payments or decreased by purchasing content. When a user has sufficient funds on their account, they can click a button that will bring up a modal window to confirm or cancel the purchase. If they click confirm, their account balance is automatically updated with the new balance. The database will be updated with a purchases collection, which tracks the user ID and the item IDs that they've purchased. The user's current balance will be tracked on their actual account with a new property called balance, which takes a number. Let's start by updating the cloud function. We need it to update both the charge as well as the user's balance in the same operation. We want it to be atomic, meaning if the charge fails, The user balance update will fail also and vice versa. The first step is to create a balance variable that defaults to 0. And then when we get the customer record, we'll update it with their existing balance. When we get the Stripe charge back, we'll first check to make sure it exists, And we'll also check to make sure that it's actually paid. If these conditions are met, we create an object where the key is a reference point in the database and the value is the data we wanna update. This allows us to update multiple database locations at the same time. But be careful, it performs a set operation, so Make sure you point to the very deepest node that you wanna update. Now we can use the charge amount from Stripe to increase the user's balance And then send these updates together to the root of the database. Back in the app, we can see the user's balance is updated by the Cloud Function when they make a payment. Now we need to update the service to handle the payment process. In order to get the user balance, We first need the auth user ID, so we'll use the switch map operator on the AngularFire auth observable. We'll move this out into its own function and then subscribe to it in the constructor. The balance itself will be emitted as an object, So we just want to map that object to its actual value, so we just get a number back in the observable. From there, we need to determine if a user has already purchased a product, which we can do by seeing if that key exists under their purchases in the database. This will also return an observable and will map it to a boolean value to get the true false value back instead of the entire object itself. And the last step is to create a function that enables the user to actually make purchase. It requires the unique ID of the item being purchased as well as the amount, and it records the timestamp from the Firebase server. This will guarantee your time stamps are consistent, which would not be the case if you just use the JavaScript date object. This function also needs to make an atomic update to update the balance as well as the purchase history in the same operation. So we'll create another updates object and pass it the corresponding data. The user balance gets decreased by the amount of the purchase and the purchase history gets the purchase object. We can then pass these updates to the root of the database and call the update function. Now let's create a new component called the buy now component. It's designed to be reusable, so we'll take the buyable ID as well as the amount from the parent component. The buyable ID just represents any item that can be purchased. We also create a variable to toggle the visibility of the modal. During ng on init, we define the variables for the user balance observable and the has purchased observable. Then we create an event handler to change the visibility of the modal. And the last function we need is for the user to actually confirm the purchase. So this will just run the buy digital content function that we defined in the service. When the purchase is complete, we close the modal. And you could also consider adding a success message or confirmation at this point. But before we get into the HTML, we're going to create a custom Stripe pipe to format the currency amounts. This is strictly for the user, and it will turn the value into a string with the proper decimal amount. Stripe amounts are 1 100th of the underlying currency, so 500 in Stripe equals 5 US dollars. From a parent component, we passed the unique ID as well as the price to the buy now component. In the component itself, we add the is active class when the Show modal variable is true. This is specific to Bulma CSS. We can unwrap the balance observable to see if the user has sufficient funds on their account to make the purchase. If so, we'll show them the confirm or cancel buttons. We can also show the user what their current balance is and what their balance will look like after the purchase. The confirm button will actually make the purchase and the cancel button will just toggle the modal back to false. If the user doesn't have enough money, we'll show different modal content that says insufficient funds with their current balance. The last step is to create a button that will open the modal in the first place. If the user has already purchased the item, then we'll go ahead and just Show button that says already purchased that's disabled. Notice how we always unwrap the observables in parentheses using the async pipe and then call any logic outside those parenthesis. Before we start using the system, let's also add some back end data security rules on Firebase. When a purchase is made, we wanna make sure that user ID always matches the current auth user ID. And we also wanna prevent purchases from being updated or deleted after they've been created. So if the data exists, then we won't allow any write operations to take place. Now going back to the app, we can take a look and make sure that everything is working as expected. I currently have $5 on my account, which is insufficient to buy product. So we'll add additional credits through Stripe, which should increase the account balance from $5 to 20 5 dollars. And we'll see the account balance here update asynchronously once it's done processing in Stripe. And now we have sufficient funds on the account, so we should be able to go ahead and buy the product. That pulls up the confirmation screen. If we click confirm, it should reduce the balance by $20, which it does. So now we're back at $5 again, and we have access to the product. That's it for Stripe Payments. If this video helped you, please like and subscribe. And if you want a free copy of that book, the Angular Firebase Survival Guide, Consider becoming a pro member for just $9 a month. You'll get a free copy of that book, as well as access to our pro channel on Slack for 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
Welcome
welcome
to
to
part
part
3
3
of
of
Stripe
stripe
payments
payments
with
with
Angular
angular
and
and
Firebase.
firebase
In
in
the
the
last
last
two
two
episodes,
episodes
we
we
integrated
integrated
Stripe
stripe
checkout
checkout
and
and
charged
charged
the
the
card
card
with
with
Firebase
firebase
Cloud
cloud
Functions.
functions
Functions.
functions
In
in
this
this
3rd
3rd
episode,
episode
we're
we're
going
going
to
to
use
use
that
that
charge
charge
to
to
enable
enable
the
the
user
user
to
to
purchase
purchase
digital
digital
content
content
in
in
our
our
app.
app
In
in
this
this
example,
example
we
we
keep
keep
a
a
balance
balance
on
on
the
the
user's
user's
account,
account
which
which
can
can
be
be
increased
increased
by
by
making
making
payments
payments
or
or
decreased
decreased
by
by
purchasing
purchasing
content.
content
When
when
a
a
user
user
has
has
sufficient
sufficient
funds
funds
on
on
their
their
account,
account
they
they
can
can
click
click
a
a
button
button
that
that
will
will
bring
bring
up
up
a
a
modal
modal
window
window
to
to
confirm
confirm
or
or
cancel
cancel
the
the
purchase.
purchase
If
if
they
they
click
click
confirm,
confirm
their
their
account
account
balance
balance
is
is
automatically
automatically
updated
updated
with
with
the
the
new
new
balance.
balance
The
the
database
database
will
will
be
be
updated
updated
with
with
a
a
purchases
purchases
collection,
collection
which
which
tracks
tracks
the
the
user
user
ID
id
and
and
the
the
item
item
IDs
ids
that
that
they've
they've
purchased.
purchased
The
the
user's
user's
current
current
balance
balance
will
will
be
be
tracked
tracked
on
on
their
their
actual
actual
account
account
with
with
a
a
new
new
property
property
called
called
balance,
balance
which
which
takes
takes
a
a
number.
number
Let's
let's
start
start
by
by
updating
updating
the
the
cloud
cloud
function.
function
We
we
need
need
it
it
to
to
update
update
both
both
the
the
charge
charge
as
as
well
well
as
as
the
the
user's
user's
balance
balance
in
in
the
the
same
same
operation.
operation
We
we
want
want
it
it
to
to
be
be
atomic,
atomic
meaning
meaning
if
if
the
the
charge
charge
fails,
fails
The
the
user
user
balance
balance
update
update
will
will
fail
fail
also
also
and
and
vice
vice
versa.
versa
The
the
first
first
step
step
is
is
to
to
create
create
a
a
balance
balance
variable
variable
that
that
defaults
defaults
to
to
0.
0
And
and
then
then
when
when
we
we
get
get
the
the
customer
customer
record,
record
we'll
we'll
update
update
it
it
with
with
their
their
existing
existing
balance.
balance
When
when
we
we
get
get
the
the
Stripe
stripe
charge
charge
back,
back
we'll
we'll
first
first
check
check
to
to
make
make
sure
sure
it
it
exists,
exists
And
and
we'll
we'll
also
also
check
check
to
to
make
make
sure
sure
that
that
it's
it's
actually
actually
paid.
paid
If
if
these
these
conditions
conditions
are
are
met,
met
we
we
create
create
an
an
object
object
where
where
the
the
key
key
is
is
a
a
reference
reference
point
point
in
in
the
the
database
database
and
and
the
the
value
value
is
is
the
the
data
data
we
we
wanna
wanna
update.
update
This
this
allows
allows
us
us
to
to
update
update
multiple
multiple
database
database
locations
locations
at
at
the
the
same
same
time.
time
But
but
be
be
careful,
careful
it
it
performs
performs
a
a
set
set
operation,
operation
so
so
Make
make
sure
sure
you
you
point
point
to
to
the
the
very
very
deepest
deepest
node
node
that
that
you
you
wanna
wanna
update.
update
Now
now
we
we
can
can
use
use
the
the
charge
charge
amount
amount
from
from
Stripe
stripe
to
to
increase
increase
the
the
user's
user's
balance
balance
And
and
then
then
send
send
these
these
updates
updates
together
together
to
to
the
the
root
root
of
of
the
the
database.
database
Back
back
in
in
the
the
app,
app
we
we
can
can
see
see
the
the
user's
user's
balance
balance
is
is
updated
updated
by
by
the
the
Cloud
cloud
Function
function
when
when
they
they
make
make
a
a
payment.
payment
Now
now
we
we
need
need
to
to
update
update
the
the
service
service
to
to
handle
handle
the
the
payment
payment
process.
process
In
in
order
order
to
to
get
get
the
the
user
user
balance,
balance
We
we
first
first
need
need
the
the
auth
auth
user
user
ID,
id
so
so
we'll
we'll
use
use
the
the
switch
switch
map
map
operator
operator
on
on
the
the
AngularFire
angularfire
auth
auth
observable.
observable
We'll
we'll
move
move
this
this
out
out
into
into
its
its
own
own
function
function
and
and
then
then
subscribe
subscribe
to
to
it
it
in
in
the
the
constructor.
constructor
The
the
balance
balance
itself
itself
will
will
be
be
emitted
emitted
as
as
an
an
object,
object
So
so
we
we
just
just
want
want
to
to
map
map
that
that
object
object
to
to
its
its
actual
actual
value,
value
so
so
we
we
just
just
get
get
a
a
number
number
back
back
in
in
the
the
observable.
observable
From
from
there,
there
we
we
need
need
to
to
determine
determine
if
if
a
a
user
user
has
has
already
already
purchased
purchased
a
a
product,
product
which
which
we
we
can
can
do
do
by
by
seeing
seeing
if
if
that
that
key
key
exists
exists
under
under
their
their
purchases
purchases
in
in
the
the
database.
database
This
this
will
will
also
also
return
return
an
an
observable
observable
and
and
will
will
map
map
it
it
to
to
a
a
boolean
boolean
value
value
to
to
get
get
the
the
true
true
false
false
value
value
back
back
instead
instead
of
of
the
the
entire
entire
object
object
itself.
itself
And
and
the
the
last
last
step
step
is
is
to
to
create
create
a
a
function
function
that
that
enables
enables
the
the
user
user
to
to
actually
actually
make
make
purchase.
purchase
It
it
requires
requires
the
the
unique
unique
ID
id
of
of
the
the
item
item
being
being
purchased
purchased
as
as
well
well
as
as
the
the
amount,
amount
and
and
it
it
records
records
the
the
timestamp
timestamp
from
from
the
the
Firebase
firebase
server.
server
This
this
will
will
guarantee
guarantee
your
your
time
time
stamps
stamps
are
are
consistent,
consistent
which
which
would
would
not
not
be
be
the
the
case
case
if
if
you
you
just
just
use
use
the
the
JavaScript
javascript
date
date
object.
object
This
this
function
function
also
also
needs
needs
to
to
make
make
an
an
atomic
atomic
update
update
to
to
update
update
the
the
balance
balance
as
as
well
well
as
as
the
the
purchase
purchase
history
history
in
in
the
the
same
same
operation.
operation
So
so
we'll
we'll
create
create
another
another
updates
updates
object
object
and
and
pass
pass
it
it
the
the
corresponding
corresponding
data.
data
The
the
user
user
balance
balance
gets
gets
decreased
decreased
by
by
the
the
amount
amount
of
of
the
the
purchase
purchase
and
and
the
the
purchase
purchase
history
history
gets
gets
the
the
purchase
purchase
object.
object
We
we
can
can
then
then
pass
pass
these
these
updates
updates
to
to
the
the
root
root
of
of
the
the
database
database
and
and
call
call
the
the
update
update
function.
function
Now
now
let's
let's
create
create
a
a
new
new
component
component
called
called
the
the
buy
buy
now
now
component.
component
It's
it's
designed
designed
to
to
be
be
reusable,
reusable
so
so
we'll
we'll
take
take
the
the
buyable
buyable
ID
id
as
as
well
well
as
as
the
the
amount
amount
from
from
the
the
parent
parent
component.
component
The
the
buyable
buyable
ID
id
just
just
represents
represents
any
any
item
item
that
that
can
can
be
be
purchased.
purchased
We
we
also
also
create
create
a
a
variable
variable
to
to
toggle
toggle
the
the
visibility
visibility
of
of
the
the
modal.
modal
During
during
ng
ng
on
on
init,
init
we
we
define
define
the
the
variables
variables
for
for
the
the
user
user
balance
balance
observable
observable
and
and
the
the
has
has
purchased
purchased
observable.
observable
Then
then
we
we
create
create
an
an
event
event
handler
handler
to
to
change
change
the
the
visibility
visibility
of
of
the
the
modal.
modal
And
and
the
the
last
last
function
function
we
we
need
need
is
is
for
for
the
the
user
user
to
to
actually
actually
confirm
confirm
the
the
purchase.
purchase
So
so
this
this
will
will
just
just
run
run
the
the
buy
buy
digital
digital
content
content
function
function
that
that
we
we
defined
defined
in
in
the
the
service.
service
When
when
the
the
purchase
purchase
is
is
complete,
complete
we
we
close
close
the
the
modal.
modal
And
and
you
you
could
could
also
also
consider
consider
adding
adding
a
a
success
success
message
message
or
or
confirmation
confirmation
at
at
this
this
point.
point
But
but
before
before
we
we
get
get
into
into
the
the
HTML,
html
we're
we're
going
going
to
to
create
create
a
a
custom
custom
Stripe
stripe
pipe
pipe
to
to
format
format
the
the
currency
currency
amounts.
amounts
This
this
is
is
strictly
strictly
for
for
the
the
user,
user
and
and
it
it
will
will
turn
turn
the
the
value
value
into
into
a
a
string
string
with
with
the
the
proper
proper
decimal
decimal
amount.
amount
Stripe
stripe
amounts
amounts
are
are
1
1
100th
100th
of
of
the
the
underlying
underlying
currency,
currency
so
so
500
500
in
in
Stripe
stripe
equals
equals
5
5
US
us
dollars.
dollars
From
from
a
a
parent
parent
component,
component
we
we
passed
passed
the
the
unique
unique
ID
id
as
as
well
well
as
as
the
the
price
price
to
to
the
the
buy
buy
now
now
component.
component
In
in
the
the
component
component
itself,
itself
we
we
add
add
the
the
is
is
active
active
class
class
when
when
the
the
Show
show
modal
modal
variable
variable
is
is
true.
true
This
this
is
is
specific
specific
to
to
Bulma
bulma
CSS.
css
We
we
can
can
unwrap
unwrap
the
the
balance
balance
observable
observable
to
to
see
see
if
if
the
the
user
user
has
has
sufficient
sufficient
funds
funds
on
on
their
their
account
account
to
to
make
make
the
the
purchase.
purchase
If
if
so,
so
we'll
we'll
show
show
them
them
the
the
confirm
confirm
or
or
cancel
cancel
buttons.
buttons
We
we
can
can
also
also
show
show
the
the
user
user
what
what
their
their
current
current
balance
balance
is
is
and
and
what
what
their
their
balance
balance
will
will
look
look
like
like
after
after
the
the
purchase.
purchase
The
the
confirm
confirm
button
button
will
will
actually
actually
make
make
the
the
purchase
purchase
and
and
the
the
cancel
cancel
button
button
will
will
just
just
toggle
toggle
the
the
modal
modal
back
back
to
to
false.
false
If
if
the
the
user
user
doesn't
doesn't
have
have
enough
enough
money,
money
we'll
we'll
show
show
different
different
modal
modal
content
content
that
that
says
says
insufficient
insufficient
funds
funds
with
with
their
their
current
current
balance.
balance
The
the
last
last
step
step
is
is
to
to
create
create
a
a
button
button
that
that
will
will
open
open
the
the
modal
modal
in
in
the
the
first
first
place.
place
If
if
the
the
user
user
has
has
already
already
purchased
purchased
the
the
item,
item
then
then
we'll
we'll
go
go
ahead
ahead
and
and
just
just
Show
show
button
button
that
that
says
says
already
already
purchased
purchased
that's
that's
disabled.
disabled
Notice
notice
how
how
we
we
always
always
unwrap
unwrap
the
the
observables
observables
in
in
parentheses
parentheses
using
using
the
the
async
async
pipe
pipe
and
and
then
then
call
call
any
any
logic
logic
outside
outside
those
those
parenthesis.
parenthesis
Before
before
we
we
start
start
using
using
the
the
system,
system
let's
let's
also
also
add
add
some
some
back
back
end
end
data
data
security
security
rules
rules
on
on
Firebase.
firebase
When
when
a
a
purchase
purchase
is
is
made,
made
we
we
wanna
wanna
make
make
sure
sure
that
that
user
user
ID
id
always
always
matches
matches
the
the
current
current
auth
auth
user
user
ID.
id
And
and
we
we
also
also
wanna
wanna
prevent
prevent
purchases
purchases
from
from
being
being
updated
updated
or
or
deleted
deleted
after
after
they've
they've
been
been
created.
created
So
so
if
if
the
the
data
data
exists,
exists
then
then
we
we
won't
won't
allow
allow
any
any
write
write
operations
operations
to
to
take
take
place.
place
Now
now
going
going
back
back
to
to
the
the
app,
app
we
we
can
can
take
take
a
a
look
look
and
and
make
make
sure
sure
that
that
everything
everything
is
is
working
working
as
as
expected.
expected
I
i
currently
currently
have
have
$5
$5
on
on
my
my
account,
account
which
which
is
is
insufficient
insufficient
to
to
buy
buy
product.
product
So
so
we'll
we'll
add
add
additional
additional
credits
credits
through
through
Stripe,
stripe
which
which
should
should
increase
increase
the
the
account
account
balance
balance
from
from
$5
$5
to
to
20
20
5
5
dollars.
dollars
And
and
we'll
we'll
see
see
the
the
account
account
balance
balance
here
here
update
update
asynchronously
asynchronously
once
once
it's
it's
done
done
processing
processing
in
in
Stripe.
stripe
And
and
now
now
we
we
have
have
sufficient
sufficient
funds
funds
on
on
the
the
account,
account
so
so
we
we
should
should
be
be
able
able
to
to
go
go
ahead
ahead
and
and
buy
buy
the
the
product.
product
That
that
pulls
pulls
up
up
the
the
confirmation
confirmation
screen.
screen
If
if
we
we
click
click
confirm,
confirm
it
it
should
should
reduce
reduce
the
the
balance
balance
by
by
$20,
$20
which
which
it
it
does.
does
So
so
now
now
we're
we're
back
back
at
at
$5
$5
again,
again
and
and
we
we
have
have
access
access
to
to
the
the
product.
product
That's
that's
it
it
for
for
Stripe
stripe
Payments.
payments
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
want
want
a
a
free
free
copy
copy
of
of
that
that
book,
book
the
the
Angular
angular
Firebase
firebase
Survival
survival
Guide,
guide
Consider
consider
becoming
becoming
a
a
pro
pro
member
member
for
for
just
just
$9
$9
a
a
month.
month
You'll
you'll
get
get
a
a
free
free
copy
copy
of
of
that
that
book,
book
as
as
well
well
as
as
access
access
to
to
our
our
pro
pro
channel
channel
on
on
Slack
slack
for
for
1
1
on
on
1
1
project
project
consulting.
consulting
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
see
see
you
you
next
next
time.
time
success
In this video, the speaker discusses how to update Stripe payments and user balances in an app. They explain how to create a balance variable, update the cloud function, and create a buy now component. The speaker also explains how to use the buy now function to reduce the user's balance and confirms a purchase. The video concludes with a recommendation to subscribe to the news and a promotion for a free book.
Selling Digital Content in Angular with Stripe Payments - Part 3
Welcome to part 3 of Stripe payments with Angular and Firebase. In the last two episodes, we integrated Stripe checkout and charged the card with Firebase Cloud Functions. Functions. In this 3rd episode, we're going to use that charge to enable the user to purchase digital content in our app. In this example, we keep a balance on the user's account, which can be increased by making payments or decreased by purchasing content. When a user has sufficient funds on their account, they can click a button that will bring up a modal window to confirm or cancel the purchase. If they click confirm, their account balance is automatically updated with the new balance. The database will be updated with a purchases collection, which tracks the user ID and the item IDs that they've purchased. The user's current balance will be tracked on their actual account with a new property called balance, which takes a number. Let's start by updating the cloud function. We need it to update both the charge as well as the user's balance in the same operation. We want it to be atomic, meaning if the charge fails, The user balance update will fail also and vice versa. The first step is to create a balance variable that defaults to 0. And then when we get the customer record, we'll update it with their existing balance. When we get the Stripe charge back, we'll first check to make sure it exists, And we'll also check to make sure that it's actually paid. If these conditions are met, we create an object where the key is a reference point in the database and the value is the data we wanna update. This allows us to update multiple database locations at the same time. But be careful, it performs a set operation, so Make sure you point to the very deepest node that you wanna update. Now we can use the charge amount from Stripe to increase the user's balance And then send these updates together to the root of the database. Back in the app, we can see the user's balance is updated by the Cloud Function when they make a payment. Now we need to update the service to handle the payment process. In order to get the user balance, We first need the auth user ID, so we'll use the switch map operator on the AngularFire auth observable. We'll move this out into its own function and then subscribe to it in the constructor. The balance itself will be emitted as an object, So we just want to map that object to its actual value, so we just get a number back in the observable. From there, we need to determine if a user has already purchased a product, which we can do by seeing if that key exists under their purchases in the database. This will also return an observable and will map it to a boolean value to get the true false value back instead of the entire object itself. And the last step is to create a function that enables the user to actually make purchase. It requires the unique ID of the item being purchased as well as the amount, and it records the timestamp from the Firebase server. This will guarantee your time stamps are consistent, which would not be the case if you just use the JavaScript date object. This function also needs to make an atomic update to update the balance as well as the purchase history in the same operation. So we'll create another updates object and pass it the corresponding data. The user balance gets decreased by the amount of the purchase and the purchase history gets the purchase object. We can then pass these updates to the root of the database and call the update function. Now let's create a new component called the buy now component. It's designed to be reusable, so we'll take the buyable ID as well as the amount from the parent component. The buyable ID just represents any item that can be purchased. We also create a variable to toggle the visibility of the modal. During ng on init, we define the variables for the user balance observable and the has purchased observable. Then we create an event handler to change the visibility of the modal. And the last function we need is for the user to actually confirm the purchase. So this will just run the buy digital content function that we defined in the service. When the purchase is complete, we close the modal. And you could also consider adding a success message or confirmation at this point. But before we get into the HTML, we're going to create a custom Stripe pipe to format the currency amounts. This is strictly for the user, and it will turn the value into a string with the proper decimal amount. Stripe amounts are 1 100th of the underlying currency, so 500 in Stripe equals 5 US dollars. From a parent component, we passed the unique ID as well as the price to the buy now component. In the component itself, we add the is active class when the Show modal variable is true. This is specific to Bulma CSS. We can unwrap the balance observable to see if the user has sufficient funds on their account to make the purchase. If so, we'll show them the confirm or cancel buttons. We can also show the user what their current balance is and what their balance will look like after the purchase. The confirm button will actually make the purchase and the cancel button will just toggle the modal back to false. If the user doesn't have enough money, we'll show different modal content that says insufficient funds with their current balance. The last step is to create a button that will open the modal in the first place. If the user has already purchased the item, then we'll go ahead and just Show button that says already purchased that's disabled. Notice how we always unwrap the observables in parentheses using the async pipe and then call any logic outside those parenthesis. Before we start using the system, let's also add some back end data security rules on Firebase. When a purchase is made, we wanna make sure that user ID always matches the current auth user ID. And we also wanna prevent purchases from being updated or deleted after they've been created. So if the data exists, then we won't allow any write operations to take place. Now going back to the app, we can take a look and make sure that everything is working as expected. I currently have $5 on my account, which is insufficient to buy product. So we'll add additional credits through Stripe, which should increase the account balance from $5 to 20 5 dollars. And we'll see the account balance here update asynchronously once it's done processing in Stripe. And now we have sufficient funds on the account, so we should be able to go ahead and buy the product. That pulls up the confirmation screen. If we click confirm, it should reduce the balance by $20, which it does. So now we're back at $5 again, and we have access to the product. That's it for Stripe Payments. If this video helped you, please like and subscribe. And if you want a free copy of that book, the Angular Firebase Survival Guide, Consider becoming a pro member for just $9 a month. You'll get a free copy of that book, as well as access to our pro channel on Slack for 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
In this video, the speaker discusses how to update Stripe payments and user balances in an app. They explain how to create a balance variable, update the cloud function, and create a buy now component. The speaker also explains how to use the buy now function to reduce the user's balance and confirms a purchase. The video concludes with a recommendation to subscribe to the news and a promotion for a free book.