Ruby on Rails #6 Stripe API - Stripe with Devise, Create Stripe API records from Rails

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
👍︎︎ 1 👤︎︎ u/yarotheking 📅︎︎ Mar 30 2021 🗫︎ replies
Captions
hello and welcome so previously we have worked on this basic application where we have a list of products and their prices and we have this buy now button when we press this buy now button we are directed to a stripe checkout page where a user can input his email address his credit card now i'm inputting a valid test credit card input his name on the code and press pay and stripe will validate this credit card and try to receive the payment and if stripe manages to successfully receive the payment from this credit card through that hooks the sales count of this specific product will be increased by one and now we're going to continue working on this application now if i go into our web hooks and so on we can see what actually happened on the stripe side let's try going to our webhooks for example and have a look at the logs so here we have all these webhook attempts that have succeeded and let's have a look at the last four web hooks that happened just now so we had a new customer that was created because we don't have any customers registered in the application at the moment and in the checkout we did not define a customer so if i go to the checkout page in the checkout we did not define a customer that's why we created a new stripe customer then there was a payment intent created for this customer to buy products for a specific amount then a charge has succeeded and the after the charge has succeeded the checkout session was completed and then the checkout session was completed stripe sent a post request into our ruby on rails application into the webhooks controller the create action and it was decrypted and we have this checkout session completed and here we basically get this web hook with this json data and we get the product from this json data we just find the product by the amount that was paid so the price was 6900 cents and we just find a product that has the price 6900 cents and we increase the sales count by one now they have a few things that are kind of wrong in this approach first of all we find the product just by the price and we will definitely have problem if we had a few products with the same price and also we create a new customer for each checkout session so we do not have a customer defined now we are going to do we are going to tackle both problems one by one first we are going to not have to create a new customer for each checkout session there are two ways we can do it the first way is we will create one stripe customer and we will be assigning all the payments to this one customer it's not the best approach either the second is we're going to allow users to log into our application and when a user logs into the application he will be automatically assigned a stripe customer id and all his purchases will be assigned to his customer id now let's have a look once again so if we go to developer web hooks we'll go to the logs i will have a look at this checkout session completed and it was done for this customer if we open the customer we see that he has paid 69 dollars for some kind of product i have this payment intent i will open it and inside i see that there are a few line items so one of the items is for a product named nokia brick phone and the price was 69 dollars so here i open this product and i see this product doesn't have any price at the moment but we can add a price for it now what we are going to do now is we are going to install the gem device and automatically when a user registers in the application he'll be assigned a stripe customer id so let's go and install the gem device let's go to the docs github gem device and install it okay i found the gem device i will add it to our gem file on the bottom and run bundle next i'm going to run rails generate device install and there are a few things we need to do so i will add this in our development.rb i'm going to go to config environments development rb add this command okay next we already have a root then we are going to add these two lines to our application html view so fuse layouts html application html okay and we're going to run rails generate device model now we are going to have device for users so we will run rails generate device user [Music] and railsdb migrate now i will say rail server and now users will be able to log in but we will also make it so that the application is available only to logged in users so we will go to our application controller and here we will say before action authenticate user so now a user has to be logged in to view the contents of the application they're going to sign up they'll add some kind of random email random password password confirmation and welcome we have signed up oh you see actually we have this notification here twice that's not really nice but it doesn't matter for now also we can add the user information to our navbar so somewhere here i have saved the a basic navbar for device let's find it i'm going to find it in my blog okay memo on navigation links when using gem device so if we have a current user it will have a link to the current user email and to log out otherwise they're going to have willing to log in and register very straightforward i will also add these to our application html just like this okay so we have our products i also added a link to the github page of this application we have our email and we have a log out button so we have basically installed the gem device and that's it for now i'm going to save our changes get status get add all git commit main install gem device okay and now we are going to associate our users when they are created with a stripe customer so for this we are going to create a new stripe customer for each new user that we create and they are going to assign the stripe customer id to the user so for this we are going to add the a column to our users table named stripe customer id rails generate migration add stripe customer id to users stripe customer id integer okay let's have a look at our migration db migrate let's try customer id to users and it's actually not going to be integer because stripe doesn't keep their kind of ids in as integers they look like this they are strings so it's going to be not an integer it's going to be a string yes this is really important and we are going to run rails db migrate now i will start the server and i will refresh and we can also try to display the user stripe customer id if the user has one so we will say equals current user dot stripe customer id if he has one but this current user doesn't have a stripe customer id so now what are we going to do we're going to run the command to create a stripe customer for this user with this email after the user is created and they are going to do it in the user model so we are going to go to our models user.rb and we're going to actually first we'll add def to s email end and we're going to run add a callback after create do okay and we're going to say customer equals stripe customer dot create and we will say that the email is the user's email and we are going to update the user's column update stripe customer id with the customer dot id let's see if this works i will try to create a new customer a new user i will log out i will sign up with a new account and you see the user was assigned a stripe customer id now let's see what happened on the stripe side i will go to developer and logs now did anything happen let's see yes so you see just now we had a post for customers create and we created a customer with the same email address as the currently logged in user here's the email address so this works now whenever a new user signs up to our application he is assigned a stripe customer id let's save our changes so i will say git status what have we done we've added a column stripe customer id to users run the migration and we added the a callback in user rb after the user is created he is assigned a stripe customer id so git add all get comment main and we will say uh user is assigned type customer id after create and git push we will also push to haruku so get push heruku main and john the migrations and try scene if it works on heroku okay you see i get this rejected i failed to push because the current pro current branch is behind so i will just say git push hero command force and i'll be back when they finish pushing to heruko for now i'll pause the video okay i have pushed the application to herruku and john herruko railsdb migrate let's see if it works i'm refreshing and i need to sign in okay i will sign up he has my email he has my password done and you see i was also assigned a unique customer id this one is different from the other one now if i create another account so sign up i will also have a unique customer id and what is it for this is for us not to have to create a new customer for each checkout and for us to be able to trace all the sales all the payments to the same customer so now let's go back and see to it that when we create a new checkout will not create a new customer each time and maybe we won't have to actually input the email address now i will start the server yeah the button isn't working because i don't have the server running okay i'll refresh i'll press buy now and i want this sale to automatically be assigned to this customer so how are we going to do it well we are going to define the customer in the checkout session i will go to controllers check out controller and here we can also say that the customer is the current user dot stripe customer id let's see if this works i'll press buy now and you see we already have the email set here by default if i log out and log in with the another user and press buy now i will have the email of this user so this way basically stripe is telling us that we have a user created and a customer created to which we assign the sale but you see here we do not have an email why is it so well because this specific customer this specific user was created before we added the function to add a stripe customer id after creating the user so i will just not use this user i will go to the other user that has a stripe customer id and try to create a payment i will pay for this iphone x i don't need to input my email anymore because i am logged in so i put in some kind of card details i pay and let's have a look at how it looks from the stripe side so the payment is still processing okay i will now refresh this page and here are the latest logs but i actually really like looking at them in the web hooks it shows a more easily readable format i would say so what happened at the five o'clock we had the a payment intent that was created so for the iphone that cost 999 dollars then the customer it is this customer viq the one that is logged in then we had a checkout session completed and a charge succeeded so as you can see we assigned this charge to the existing stripe customer works nice so now we can save our changes what have we done we've done a really simple thing get status we have assigned the checkout to a specific customer to the current user with a specific stripe customer id so git add all git commit and assign checkout to current user.stripe customer id okay looks nice okay go into the next step here i have three products one of them is nokia brick phone let's try to buy it and see our logs once again here we have our existing customer i put in a code some kind of dates and process the payment and after the payment is processed we will have a look at our logs ok success so i will refresh our web hooks you can of course do it not in-depth but in logs okay so we had a payment intent created succeeded checkout session completed and charged succeeded let's have a look at the payment intent i will open the payment intent so it is 59 from this customer we can actually also see the customer and see all his payments the ones that were completed or incompleted anyway going back here if we go to the bottom we see the product the product was a nokia brick phone what if you press this product we see we cannot actually do any actions with it it is in an archived state why is it so because the product was created just for this specific transaction because this isn't a product that we created in stripe and we don't have the product from our database associated with stripe here in our products we don't have this product so now we are going to associate our products from our database with stripe products how we going to do it also we are going to add a product to a stripe product id to all our products in the database so let's do it i will check get status no changes to add get of rails generate migration add stripe product id to products stripe product id stream okay let's have a look at our migration here it is so i will run rails db migrate and rail server let's also display the stripe product id in the products so i'm going to go to products index and here we are going to display the stripe id stripe product id we have the product name price and we'll have product dot stripe product id and as we see all these products are not associated with a stripe product so we're going to do it now now we're going to try this scenario first we create a product in our database and from our database we create a product inside stride and we can also have a look at the stripe documentation and here instruct docs payments accepting a payment if we go down we have this information on creating products and prices up front so with such a call we can create a striped product and with such a call we can create a stripe price associated with a product a product can have many prices so let's try creating a stripe product in our console rails console we will create the stripe product enter if i call the product here i get this product and here is the id of the product that we created and i can also try creating a stripe price but i will need to associate the price with this product so i will say price equals try price create and i have product and here i will put this id of the product then we need unit amount currency and that's it so unit amount is going to be the price in cents let's say edition is going to cost 15 dollars so 15 0 0 and we have currency is going to be usd okay close and the price was created i will call the price and here it is okay and now we managed to create a product and the price from our console we can also view them in our products i will refresh the page refreshing the page and here we have a new t-shirt created with the price 15 now we can even associate more than one price with this product so here we have this t-shirt for 15 dollars let's make it 80 blm or euro eur okay i will refresh and see if we see that this t-shirt has multiple prices not only one price in the loss so you see two prices okay now we are going to associate a stripe price and stripe product with our products created in the database so we are going to do it a similar way as we did with users we are going to have a before of an after create callback we will say after create do we will have product equal stripe product dot create and the name will be the name of the product and we are going to have a price price equals stripe price dot create and i'm just going to copy some of this text so we're going to have the product it will be this product then unit amount is going to be the product price so it's going to be uh price and the currency well in our case we are going to have just the currency usd but you can also add an additional currency field to your products table and also assign the currency to the stripe product and we're going to update the stripe uh price of or product id now the name it's product or price let's just check we're going to update the stripe product id with the product dot id so let's see if it works i'm going to create a new product i will name it a cool microphone yeah because i really need to update my microphone i will say the price is 150 dollars create product okay prices require a unit amount or unit amount decimal parameter to be set so we did not do this correctly let's go back and see so going here i will just add self dot price and see if it works int amount equals self.price okay and i will create a new product i will name it the cool microphone 150 100 cents and the product was created i will go back and you see it was assigned a stripe product id now if i go to our products you see we had a product cool microphone just now created with the price 150 usd and it also has a price that is 150 usd so now when creating a product and a price in our oh when creating a product in our ruby on rails application we have a product and a price created in the stripe api and associated with our local product looks nice let us save our changes i will say git status so what have we done we have added stripe product id to our products and when a product is created the associated product and price are created in stripe get add all get commit main and we'll say add stripe product id to products okay looks good okay so now we have a stripe product id associated with our rails database table named products and what we want to do now it will go to our checkouts controller here we have our uh line items and we are passing the name as the product name the amount as the product price and the currency dollars and quantity one but we can do it in a more efficient way and more kind of correct way so if we go to the stripe docs we see that we can actually just pass the id of a stripe price so here instead of passing in the currency the name and the amount of the product we will just pass the id of a price so here we will just say price equals product dot stripe price id so that when we create this uh checkout and payment intent and when we create a sale the sale is associated with the actual an existing indescribed database product and price but the problem here is that we only have the stripe product id not the stripe price id uh associated with our local table of products so we will also want to add the stripe price id to our products i will go and say rails generate migration add stripe price id to products stripe price id stream now going to db migrate here we have this strike price id so railsdb migrate and when we create a product we will also also say update stripe price id with the price dot id and let's also make the strike price id visible in our views so in products index i will say stripe price id and here i will say product dot stripe price id so you see in stripe we have keeping in two separate tables products and prices a product has many prices but for this example in our local database we have products that have specific prices and i will create a new product and say uh [Music] disney name movie price will be 10 dollars okay i will go back and i see we have an associated stripe product id and stripe price id so now going to our checkout controller we can say that the price will be the product dot stripe price id let's try i will press buy now and we are redirected to the stripe checkout and here we have disney movie so you see we didn't didn't manually pass in the name the currency and the price we just passed in the stripe price id and it knows that it is a disney movie that costs 10 dollars so i will update the called information the month the year the cvc code the name and so on we will proceed with this payment and have a look at our logs afterwards you see stripe can take actually quite a while to validate the payment but it's done i will go to developer again i will go to webhooks not to just logs and here what do i see now they are all failed because i'm doing it in the development environment and i did not connect the web hooks to the development environment only to their production environment on heruku but what do we have payment intent created charge succeeded payment intent succeeded and checkout session completed let's have a look payment intent succeeded i will open this payment intent it has one item a disney movie and we can see this product so looks good and this is actually an active product it is not an archived product so this is a product that we actually have and can use so what have we done now we've just added the stripe price id to our existing products table and then we go to our checkout we check out for a specific price so we find the stripe price id and we pay for this product now it will not work for all of our other products that do not have a stripe price id and the stripe product id but that is the post and we're moving into the future so we have to have all our users all our users have to have a stripe customer id and all their products have to have a stripe product id and more importantly a stripe price id for our case so now let's save our changes i will say okay get status git add all get comment main and i will say add stripe price id to products and checkout session for a specific product okay now [Music] really good let's push to haruko git push heruko main okay so i have pushed the changes to heruko and i'm going to see how it works so i will create a new product you see i already have a striped customer new product let's say a new laptop i will say the price is one thousand five hundred dollars create product the product was created i can see that it was assigned the striped product and the stripe price i pressed the buy now again i will input a card you see the price and the uh product name were inputted correctly and actually we can try also adding a logo later on an image of the product or you know we can actually even add the image now i will go to stripe here i see this new laptop i will open this new laptop product i will go to edit product i will upload an image so here i have a laptop save product and i will refresh the checkout session and see if the product image was attached so you see the product image was attached now i can input my card information uh month and the year a cvv code a name and see if everything works in the meantime i will go to developer web hooks i will go to my production endpoint and see okay we have quite some webhooks i'll refresh once again and you see the sales count was not increased by one so we get a failure why is it so let's uh see i will open one of the webhooks and it says you need to sign up or sign in before continuing so you see in our application controller we said before action authenticate user and because of this stripe is sending a post request to the webhooks controller create action but it doesn't pass through because the application stops it at the you need to be logged in so we are going to skip before uh action authenticate user for our webhooks controller so we will say skip before action authenticate user something like this okay now let's save our changes git status git add now i will add this webhooks controller get commit main and skip device authentication or web hooks controller okay now i'm pushing to github and we'll see if it works okay so i have pushed to heruko and let's uh try to resend the webhooks so i'll press resend resend resend and now i will yeah actually i don't really have to refresh you see the books started succeeding so i can try to refresh this page and you see the sales count has increased by one because the web hook has succeeded so looks nice what have we done we have added the possibility for users to log in and when a user is logged in he is assigned a stripe customer also the products that we create are assigned stripe products and stripe price ids and when we press buy now button a product is found from the striped products and the sale is made for this product and the web hooks work with device so looks quite nice this is it for this lesson and we will continue later thank you and please like this video
Info
Channel: SupeRails
Views: 991
Rating: undefined out of 5
Keywords: tutorial, ruby on rails, screencast, rails, programming, ruby
Id: lqDJ-ko9GO4
Channel Id: undefined
Length: 39min 6sec (2346 seconds)
Published: Wed Mar 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.