So it's time to start working on this handler, and as you might have guessed, we're probably going
to have more than one handler, not just a receipt or payment, succeeded Handler.
We're probably going to have one for the virtual terminal and one for customers, but we'll take care
of dealing with the when I say customers, I mean people who are buying widgets.
So we'll take care of that after we get this thing working.
So first step is to create a customer at the point we actually get to this handler.
We already charged a credit card and we've pulled the necessary information from the post.
We've got the payment intent and the payment method from Stripe, and we're ready to actually create
a customer and save that customer to the database.
However, if you go back to the front end and I have the widget page in front of me by one widget,
we're capturing cardholder name, cardholder email, credit card.
We need these, we need this, this and everything in this field in order to charge your credit card.
But if you actually look at our database and I'll switch to that and we look at customers and I look
at the structure, we also have first name and last name.
Now, I suppose I could grab the cardholder name and split that on a space or something and try to save
that as first name, last name.
And that might work.
But in a lot of situations, your customers actually like a 14 year old kid buying something and the
credit card is actually mom's or dad's credit card.
So maybe it makes sense to change this form.
OK, so let's go back to our editor, our idee, and bring up from Web templates.
We want to buy ones page.
I'll bring that up and we'll just make some changes here.
So we already have cardholder name.
That is the inputted type text.
Let's copy that.
And let's put that as a first name and a last name.
So I pasted it twice.
So I'll call this first name and we'll call this first name and we'll change this ID to.
First name and the name of the field will be first underscore name, and the autocomplete has to be
unique.
So I'll just change this to first and we'll do the same thing here.
We'll make this last name for the four and we'll make this last name.
And this has to become last name, not new, and this has to become last underscore name, OK, and
instead of cardholder name, I'll put this as name on Kurt just to make it really clear.
And rather than having the email below that, just to make things a little more logically organized,
I'll move this up to here before the cardholder name and change this just to e-mail.
OK.
All right, now let's see what we have running here.
I have everything running, so I'm going to say make stop, make start.
I can use air, but I'm not making any more changes to the template right now, so this should be sufficient.
Let's go have a look at that.
Reload this page.
And now I have first name, last name, email, name on card.
And the credit card is perfect.
So obviously that means we need to make some changes to our handler.
So let's go look at this and go hide our terminal and go back to handlers.
Go and up here where I'm grabbing the information from the posted data, I have to add two more one
for first name, which is first underscore name and one for last name
and last underscore name.
I'm actually not doing anything with cardholder names, so I'm going to delete that entirely.
OK, so now we have first name and we have last name and we have everything we need.
So if we get down to the part where I say create a customer, let's create a customer, that's easy
enough.
So we already wrote the database method and it returns the new newly inserted customer ID and potentially
an error.
So customer ID and potentially an error are assigned the value of from app.
And I actually could call the database here directly, but I'm not going to I'm going to create a new
function called Save Customer for in the handlers.
And I'll explain why in a minute and I'll pass it the three bits of information I need.
First name.
Last name.
Try that again.
Last name and email and I'll check for an error.
If error is not equal to nil, then I will print it out after error.
Log print line.
I'll put the error and I'll just return.
You probably have something more sophisticated in your error handling, but that's sufficient for my
purposes right now.
And at the moment I'm just going to just to this will compile, I'll say after info log print line and
I'll just print out the customer ID.
So if I need to run this I can.
Now I've created this function or name this function, save customer.
Let's go down and build it.
So I'll put it right here and I'll explain why I'm having this as soon as I get it started.
So func and it will be of have the receiver of app pointer to application and I called it Save Customer
and it took three parameters, first name, last name and email and it returns an ID and potentially
an error.
OK, so what I'm going to do in here is create a customer, a model of customer.
So customer will be assigned the value of from models customer and I'll just fill in the necessary fields.
First name.
It's going to be first name,
last name will be the last name.
An email will be email, so that gives me a customer now I've called the database Idy error or assign
the value of and its app divi and the method we created was insert customer.
And it takes one argument, which is the customer.
And we check for an error, if error is not equal to nil, then will return, say, zero and the error.
So don't have a customer ID otherwise return ID, you know, and let's give this all these have to be
of type string returns and into an error on a bad day.
I guess that's better.
OK, let's give it its comment.
Save customer, saves a customer and returns it.
You might be asking yourself why didn't you just call the database directly?
Why didn't you put all of this stuff that's inside of this function right up in your handler?
Well, I could have.
And, you know, it would be actually not many fewer lines of code if I did it or not.
Many more lines of code.
It's about the same amount of code.
But the thing is, I might want to do more in my handlers in the save customer function than just insert
something into the database.
Maybe I want to fire off an email alerting someone that there's been a purchase.
Maybe I want to create an audit log and save every single transaction, all of the details associated
in the database.
The place for that is here in its own function, in my handlers, not at the database level.
So that's why I separated out this way.
OK, I'm going to do the same thing for everything else up here.
So here I see I have an area to get rid of.
Data cardholder.
I'll get rid of that.
OK, back up here and create a new customer.
Now, I've actually created the customer and I've saved it and I have the newly inserted customer.
So the next step is actually not creating a transaction.
You'll see why in a moment.
Or creating an order.
It's actually creating a transaction.
And the reason is that we need the transaction ID before we can save the order.
So let's create a new transaction.
So I'm going to need if you look at the models at the top or just look at the database.
If I go over the database, for example, and look at transactions, I need all of this information,
including the amount of the transaction.
Now I have the amount up here.
I pulled it in the posted data and it's called payment amount, but it's a string, so I need to convert
that into an IT.
OK, so we can do that easily enough amount and I will ignore the error and you shouldn't, but I'm
going to ignore it.
Just move things along and we'll call Sterkel of a two hour and we want to convert payment amount.
So now I have the amount that means I can create a transaction which I'll call taxon and that is a sign
the value of models dot transaction and we'll fill out its fields.
You scroll up and give us a bit of room here.
So it has the amount, which is amount, the one I just converted from a string that has the currency,
which is the payment currency I pulled from the posted form data last for which I got from Stripe just
up just before line sixty and I call the variable last for it also on the expiry month, which is an
expiry month.
Now let's see how smart this idea is because we actually get a unit.
Sixty four from Strib, I believe, an unsigned integer.
Sixty four bits and I just said into the database, so I'll put an expiry month and see what my ID does.
Yes.
And convert it to it in for me.
Perfect.
And the same thing for expiry year.
Expiry year, and we also want the bank return code, bank return code, and that I believe I grabbed
down here.
Yes, from our payment intent so I can grab that and paste it in here.
And the last thing we want is a transaction status.
Now, if we go look at the database, I pre populate it in the migration's.
I gave you transaction statuses and the content for this is cleared.
This is a clear transaction.
We're actually not storing declined, but you might at some point.
So we'll put in two for the transaction status idea of cleared, but is to like this is our transaction
now, just like I did above.
I'm not going to call the database directly here.
I'm going to get the transaction I.D. from the newly inserted RO in the database and potentially an
error.
And I'm going to get that from a functional right in a minute after and I'll just call the same transaction
and pass it my transaction, OK?
And we'll check for an error and I'll just copy and paste the stuff I used up here.
Paced and now let's go down and write that necessary function, save transaction, and I'll put it right
after Save Customer.
Actually, I'll just copy this and modify it, save some typing and we'll call it save transaction.
And it has one argument, which is a text of type models dot transaction.
This one's actually a little shorter, I can't even delete this stuff.
And this em and call up the DB insert transaction.
OK, and we'll fix our comment, saves a transaction and returns.
I do.
And again, I'm doing this as its own function because I might want to do something else here in the
handlers, not right now, but I might want to at some point in the future.
And since we're here anyway, we know we're going to have a save order.
So let's copy this and pasted and call the save order and the parameter will be called order and it
will be models ordered
and we're going to pass order to insert order.
And this inserts an order and it's called save order, copy and paste.
OK, now we can come back up here and we have a transaction in which we need when we create an order.
So to do that, let's create a variable which we'll call order and it will be of type models order.
And it has quite a few fields, but we'll fill them all over right here.
So we have our widget ID and we have that.
But again, it's not in the right format.
We grab that right up here where we get the actual we didn't we didn't grab it.
We probably should do that.
So let's go back to by once page and see what we called it there.
We have a hidden field in our form on Bydgoszcz once page dalgliesh html called product ID and its value
is going to be passed.
It's an integer, but it will be passed as a string and it's called product Dudi.
So let's go back to handlers and we'll just grab it.
So product we'll call it widget ID.
So we called it in our in our model widget ID.
And again I'm doing this with while ignoring the error and you shouldn't, but I just want to get this
in here and you know how to check for an error here.
We're doing a Astrachan store comp to I and we're going to get IRDA form, don't get product underscore
ID.
So now I have the widget.
So let's go down there and use it where we need it, where we're creating our order right here, widget
ID.
And the next thing we need from an order is the transactionally which we got in the previous step and
we got it on line eighty six and we called it an ID.
We also need the customer ready and that's called customer ID, which means I can get rid of this app
info print log.
OK, so we need the customer ID, we also need the status ID and this comes from a different place in
the database and it's one.
Let me show you where I got this.
And again, this is the sort of thing you would use in production.
I just called it statuses and the statuses are cleared refund or cancelled and ours is cleared in this
case.
So it's one which is why I put a one here.
So we need the status ID quantity.
We're only allowing people to buy one thing at a time so we can hard code a one here and amount and
the amount will be amount, which we grabbed a little bit earlier in this code.
Then we have created a which is time out now and updated at which is time, which apparently is not
important.
So let's do it that way.
That'll force it to import.
There and we'll call this updated of their let's format everything and now we'll call that function
we just created, which will be and this case, I don't care about the ID, so I'm going to ignore using
the blank identifier.
But I do care about checking for an error here.
And that's equal to app dot save order and we pass it the order variable we just created.
So at this point we should check for the error.
Selimi, copy this error checking code and paste it right here at this point when we run this transaction.
Now this will when we actually buy a widget from this page over here.
It should actually save a customer giving us first name, last name and email, then it should save
a transaction, then it should save an order.
That's if we got everything right.
So we'll run our first test on this in the next lecture and we'll keep going.