WEBVTT 00:00.960 --> 00:05.880 So it's time to start working on this handler, and as you might have guessed, we're probably going 00:05.880 --> 00:10.690 to have more than one handler, not just a receipt or payment, succeeded Handler. 00:10.860 --> 00:15.060 We're probably going to have one for the virtual terminal and one for customers, but we'll take care 00:15.060 --> 00:19.410 of dealing with the when I say customers, I mean people who are buying widgets. 00:20.430 --> 00:22.620 So we'll take care of that after we get this thing working. 00:22.800 --> 00:28.190 So first step is to create a customer at the point we actually get to this handler. 00:28.200 --> 00:33.600 We already charged a credit card and we've pulled the necessary information from the post. 00:34.050 --> 00:39.870 We've got the payment intent and the payment method from Stripe, and we're ready to actually create 00:39.870 --> 00:42.270 a customer and save that customer to the database. 00:42.660 --> 00:48.960 However, if you go back to the front end and I have the widget page in front of me by one widget, 00:49.500 --> 00:52.890 we're capturing cardholder name, cardholder email, credit card. 00:52.890 --> 00:58.680 We need these, we need this, this and everything in this field in order to charge your credit card. 00:59.250 --> 01:05.640 But if you actually look at our database and I'll switch to that and we look at customers and I look 01:05.640 --> 01:08.570 at the structure, we also have first name and last name. 01:08.670 --> 01:16.080 Now, I suppose I could grab the cardholder name and split that on a space or something and try to save 01:16.080 --> 01:17.810 that as first name, last name. 01:17.940 --> 01:19.020 And that might work. 01:19.500 --> 01:24.960 But in a lot of situations, your customers actually like a 14 year old kid buying something and the 01:24.960 --> 01:27.660 credit card is actually mom's or dad's credit card. 01:28.230 --> 01:30.720 So maybe it makes sense to change this form. 01:30.900 --> 01:38.280 OK, so let's go back to our editor, our idee, and bring up from Web templates. 01:38.310 --> 01:39.990 We want to buy ones page. 01:40.200 --> 01:42.410 I'll bring that up and we'll just make some changes here. 01:42.930 --> 01:44.820 So we already have cardholder name. 01:44.820 --> 01:46.620 That is the inputted type text. 01:46.690 --> 01:47.790 Let's copy that. 01:50.070 --> 01:54.030 And let's put that as a first name and a last name. 01:54.030 --> 01:55.200 So I pasted it twice. 01:55.200 --> 02:06.330 So I'll call this first name and we'll call this first name and we'll change this ID to. 02:08.880 --> 02:15.840 First name and the name of the field will be first underscore name, and the autocomplete has to be 02:15.840 --> 02:16.230 unique. 02:16.230 --> 02:20.850 So I'll just change this to first and we'll do the same thing here. 02:20.880 --> 02:26.520 We'll make this last name for the four and we'll make this last name. 02:29.660 --> 02:41.150 And this has to become last name, not new, and this has to become last underscore name, OK, and 02:41.150 --> 02:47.750 instead of cardholder name, I'll put this as name on Kurt just to make it really clear. 02:48.590 --> 02:54.560 And rather than having the email below that, just to make things a little more logically organized, 02:55.430 --> 03:00.600 I'll move this up to here before the cardholder name and change this just to e-mail. 03:01.050 --> 03:01.340 OK. 03:03.490 --> 03:06.070 All right, now let's see what we have running here. 03:06.100 --> 03:11.110 I have everything running, so I'm going to say make stop, make start. 03:13.050 --> 03:17.410 I can use air, but I'm not making any more changes to the template right now, so this should be sufficient. 03:17.760 --> 03:18.640 Let's go have a look at that. 03:19.710 --> 03:20.700 Reload this page. 03:21.480 --> 03:24.510 And now I have first name, last name, email, name on card. 03:24.510 --> 03:26.010 And the credit card is perfect. 03:26.850 --> 03:29.700 So obviously that means we need to make some changes to our handler. 03:29.700 --> 03:35.400 So let's go look at this and go hide our terminal and go back to handlers. 03:35.640 --> 03:44.490 Go and up here where I'm grabbing the information from the posted data, I have to add two more one 03:44.490 --> 03:51.210 for first name, which is first underscore name and one for last name 03:53.970 --> 03:57.660 and last underscore name. 03:58.460 --> 04:01.860 I'm actually not doing anything with cardholder names, so I'm going to delete that entirely. 04:02.190 --> 04:05.750 OK, so now we have first name and we have last name and we have everything we need. 04:06.480 --> 04:11.010 So if we get down to the part where I say create a customer, let's create a customer, that's easy 04:11.010 --> 04:11.340 enough. 04:12.450 --> 04:19.470 So we already wrote the database method and it returns the new newly inserted customer ID and potentially 04:19.470 --> 04:19.810 an error. 04:19.830 --> 04:25.470 So customer ID and potentially an error are assigned the value of from app. 04:25.890 --> 04:30.630 And I actually could call the database here directly, but I'm not going to I'm going to create a new 04:30.630 --> 04:33.650 function called Save Customer for in the handlers. 04:33.810 --> 04:37.920 And I'll explain why in a minute and I'll pass it the three bits of information I need. 04:38.670 --> 04:39.300 First name. 04:40.050 --> 04:40.800 Last name. 04:41.040 --> 04:41.700 Try that again. 04:42.360 --> 04:46.590 Last name and email and I'll check for an error. 04:46.890 --> 04:54.420 If error is not equal to nil, then I will print it out after error. 04:54.420 --> 04:56.160 Log print line. 04:58.860 --> 05:00.540 I'll put the error and I'll just return. 05:00.990 --> 05:05.310 You probably have something more sophisticated in your error handling, but that's sufficient for my 05:05.310 --> 05:06.300 purposes right now. 05:06.900 --> 05:13.450 And at the moment I'm just going to just to this will compile, I'll say after info log print line and 05:13.540 --> 05:14.910 I'll just print out the customer ID. 05:15.690 --> 05:16.980 So if I need to run this I can. 05:17.550 --> 05:20.850 Now I've created this function or name this function, save customer. 05:20.880 --> 05:21.690 Let's go down and build it. 05:22.260 --> 05:26.910 So I'll put it right here and I'll explain why I'm having this as soon as I get it started. 05:27.360 --> 05:35.010 So func and it will be of have the receiver of app pointer to application and I called it Save Customer 05:35.430 --> 05:43.020 and it took three parameters, first name, last name and email and it returns an ID and potentially 05:43.020 --> 05:43.380 an error. 05:44.480 --> 05:49.170 OK, so what I'm going to do in here is create a customer, a model of customer. 05:49.190 --> 05:56.580 So customer will be assigned the value of from models customer and I'll just fill in the necessary fields. 05:57.300 --> 05:57.900 First name. 06:00.190 --> 06:01.450 It's going to be first name, 06:04.360 --> 06:06.790 last name will be the last name. 06:09.730 --> 06:17.470 An email will be email, so that gives me a customer now I've called the database Idy error or assign 06:17.470 --> 06:23.140 the value of and its app divi and the method we created was insert customer. 06:23.740 --> 06:25.810 And it takes one argument, which is the customer. 06:28.270 --> 06:35.270 And we check for an error, if error is not equal to nil, then will return, say, zero and the error. 06:35.480 --> 06:44.920 So don't have a customer ID otherwise return ID, you know, and let's give this all these have to be 06:44.920 --> 06:49.840 of type string returns and into an error on a bad day. 06:49.850 --> 06:51.280 I guess that's better. 06:51.310 --> 06:52.990 OK, let's give it its comment. 06:56.680 --> 07:01.110 Save customer, saves a customer and returns it. 07:02.260 --> 07:05.890 You might be asking yourself why didn't you just call the database directly? 07:05.890 --> 07:10.150 Why didn't you put all of this stuff that's inside of this function right up in your handler? 07:10.300 --> 07:11.110 Well, I could have. 07:11.440 --> 07:16.990 And, you know, it would be actually not many fewer lines of code if I did it or not. 07:16.990 --> 07:18.100 Many more lines of code. 07:18.100 --> 07:19.330 It's about the same amount of code. 07:19.850 --> 07:26.170 But the thing is, I might want to do more in my handlers in the save customer function than just insert 07:26.170 --> 07:27.220 something into the database. 07:27.430 --> 07:31.150 Maybe I want to fire off an email alerting someone that there's been a purchase. 07:31.150 --> 07:38.290 Maybe I want to create an audit log and save every single transaction, all of the details associated 07:38.290 --> 07:39.070 in the database. 07:39.400 --> 07:44.680 The place for that is here in its own function, in my handlers, not at the database level. 07:44.830 --> 07:46.710 So that's why I separated out this way. 07:46.810 --> 07:51.400 OK, I'm going to do the same thing for everything else up here. 07:51.580 --> 07:54.160 So here I see I have an area to get rid of. 07:54.160 --> 07:55.120 Data cardholder. 07:55.150 --> 07:55.800 I'll get rid of that. 07:56.440 --> 08:00.150 OK, back up here and create a new customer. 08:00.160 --> 08:06.040 Now, I've actually created the customer and I've saved it and I have the newly inserted customer. 08:06.770 --> 08:09.720 So the next step is actually not creating a transaction. 08:09.740 --> 08:10.750 You'll see why in a moment. 08:10.870 --> 08:11.650 Or creating an order. 08:11.650 --> 08:12.970 It's actually creating a transaction. 08:14.170 --> 08:18.340 And the reason is that we need the transaction ID before we can save the order. 08:18.850 --> 08:21.760 So let's create a new transaction. 08:22.330 --> 08:26.530 So I'm going to need if you look at the models at the top or just look at the database. 08:26.530 --> 08:31.420 If I go over the database, for example, and look at transactions, I need all of this information, 08:31.540 --> 08:34.620 including the amount of the transaction. 08:34.720 --> 08:37.210 Now I have the amount up here. 08:37.240 --> 08:43.540 I pulled it in the posted data and it's called payment amount, but it's a string, so I need to convert 08:43.540 --> 08:45.010 that into an IT. 08:45.310 --> 08:51.160 OK, so we can do that easily enough amount and I will ignore the error and you shouldn't, but I'm 08:51.160 --> 08:51.790 going to ignore it. 08:52.660 --> 08:58.510 Just move things along and we'll call Sterkel of a two hour and we want to convert payment amount. 08:59.980 --> 09:05.380 So now I have the amount that means I can create a transaction which I'll call taxon and that is a sign 09:05.380 --> 09:09.930 the value of models dot transaction and we'll fill out its fields. 09:10.170 --> 09:11.760 You scroll up and give us a bit of room here. 09:12.940 --> 09:19.540 So it has the amount, which is amount, the one I just converted from a string that has the currency, 09:20.050 --> 09:27.640 which is the payment currency I pulled from the posted form data last for which I got from Stripe just 09:27.640 --> 09:36.880 up just before line sixty and I call the variable last for it also on the expiry month, which is an 09:36.880 --> 09:37.830 expiry month. 09:37.870 --> 09:41.980 Now let's see how smart this idea is because we actually get a unit. 09:41.980 --> 09:45.310 Sixty four from Strib, I believe, an unsigned integer. 09:45.940 --> 09:53.230 Sixty four bits and I just said into the database, so I'll put an expiry month and see what my ID does. 09:54.010 --> 09:54.400 Yes. 09:54.400 --> 09:55.770 And convert it to it in for me. 09:55.780 --> 09:56.230 Perfect. 09:56.590 --> 09:58.570 And the same thing for expiry year. 10:03.640 --> 10:13.300 Expiry year, and we also want the bank return code, bank return code, and that I believe I grabbed 10:13.300 --> 10:13.830 down here. 10:13.840 --> 10:18.790 Yes, from our payment intent so I can grab that and paste it in here. 10:21.250 --> 10:23.760 And the last thing we want is a transaction status. 10:24.520 --> 10:29.080 Now, if we go look at the database, I pre populate it in the migration's. 10:29.080 --> 10:34.050 I gave you transaction statuses and the content for this is cleared. 10:34.090 --> 10:35.640 This is a clear transaction. 10:35.800 --> 10:38.290 We're actually not storing declined, but you might at some point. 10:38.300 --> 10:47.290 So we'll put in two for the transaction status idea of cleared, but is to like this is our transaction 10:48.490 --> 10:50.250 now, just like I did above. 10:50.260 --> 10:52.450 I'm not going to call the database directly here. 10:52.600 --> 10:58.150 I'm going to get the transaction I.D. from the newly inserted RO in the database and potentially an 10:58.150 --> 10:58.480 error. 10:58.870 --> 11:03.400 And I'm going to get that from a functional right in a minute after and I'll just call the same transaction 11:04.060 --> 11:08.690 and pass it my transaction, OK? 11:08.710 --> 11:11.920 And we'll check for an error and I'll just copy and paste the stuff I used up here. 11:17.040 --> 11:23.730 Paced and now let's go down and write that necessary function, save transaction, and I'll put it right 11:23.730 --> 11:24.690 after Save Customer. 11:25.050 --> 11:31.740 Actually, I'll just copy this and modify it, save some typing and we'll call it save transaction. 11:33.690 --> 11:43.290 And it has one argument, which is a text of type models dot transaction. 11:45.070 --> 11:47.640 This one's actually a little shorter, I can't even delete this stuff. 11:49.870 --> 11:56.620 And this em and call up the DB insert transaction. 11:57.430 --> 12:04.870 OK, and we'll fix our comment, saves a transaction and returns. 12:04.890 --> 12:05.340 I do. 12:05.530 --> 12:09.970 And again, I'm doing this as its own function because I might want to do something else here in the 12:09.970 --> 12:13.060 handlers, not right now, but I might want to at some point in the future. 12:14.500 --> 12:17.260 And since we're here anyway, we know we're going to have a save order. 12:17.260 --> 12:29.710 So let's copy this and pasted and call the save order and the parameter will be called order and it 12:29.710 --> 12:31.840 will be models ordered 12:35.110 --> 12:40.180 and we're going to pass order to insert order. 12:41.650 --> 12:46.720 And this inserts an order and it's called save order, copy and paste. 12:46.750 --> 12:53.800 OK, now we can come back up here and we have a transaction in which we need when we create an order. 12:54.040 --> 12:59.790 So to do that, let's create a variable which we'll call order and it will be of type models order. 13:00.550 --> 13:03.190 And it has quite a few fields, but we'll fill them all over right here. 13:03.670 --> 13:10.080 So we have our widget ID and we have that. 13:10.090 --> 13:11.830 But again, it's not in the right format. 13:11.830 --> 13:19.030 We grab that right up here where we get the actual we didn't we didn't grab it. 13:19.060 --> 13:20.140 We probably should do that. 13:20.140 --> 13:22.900 So let's go back to by once page and see what we called it there. 13:23.980 --> 13:32.080 We have a hidden field in our form on Bydgoszcz once page dalgliesh html called product ID and its value 13:32.080 --> 13:32.920 is going to be passed. 13:33.700 --> 13:37.230 It's an integer, but it will be passed as a string and it's called product Dudi. 13:37.240 --> 13:39.990 So let's go back to handlers and we'll just grab it. 13:40.270 --> 13:45.380 So product we'll call it widget ID. 13:45.430 --> 13:49.210 So we called it in our in our model widget ID. 13:49.420 --> 13:55.090 And again I'm doing this with while ignoring the error and you shouldn't, but I just want to get this 13:55.090 --> 13:57.650 in here and you know how to check for an error here. 13:57.690 --> 14:05.020 We're doing a Astrachan store comp to I and we're going to get IRDA form, don't get product underscore 14:05.020 --> 14:05.440 ID. 14:06.010 --> 14:06.820 So now I have the widget. 14:07.210 --> 14:14.740 So let's go down there and use it where we need it, where we're creating our order right here, widget 14:14.740 --> 14:15.130 ID. 14:16.210 --> 14:22.360 And the next thing we need from an order is the transactionally which we got in the previous step and 14:22.360 --> 14:25.150 we got it on line eighty six and we called it an ID. 14:26.860 --> 14:35.640 We also need the customer ready and that's called customer ID, which means I can get rid of this app 14:35.770 --> 14:37.000 info print log. 14:37.450 --> 14:45.370 OK, so we need the customer ID, we also need the status ID and this comes from a different place in 14:45.370 --> 14:46.540 the database and it's one. 14:46.540 --> 14:47.710 Let me show you where I got this. 14:48.850 --> 14:51.370 And again, this is the sort of thing you would use in production. 14:51.370 --> 14:57.070 I just called it statuses and the statuses are cleared refund or cancelled and ours is cleared in this 14:57.070 --> 14:57.370 case. 14:57.370 --> 14:59.350 So it's one which is why I put a one here. 14:59.740 --> 15:02.110 So we need the status ID quantity. 15:02.860 --> 15:08.920 We're only allowing people to buy one thing at a time so we can hard code a one here and amount and 15:08.920 --> 15:13.810 the amount will be amount, which we grabbed a little bit earlier in this code. 15:14.320 --> 15:22.840 Then we have created a which is time out now and updated at which is time, which apparently is not 15:22.840 --> 15:23.350 important. 15:23.350 --> 15:24.400 So let's do it that way. 15:24.400 --> 15:25.690 That'll force it to import. 15:27.430 --> 15:35.290 There and we'll call this updated of their let's format everything and now we'll call that function 15:35.290 --> 15:40.420 we just created, which will be and this case, I don't care about the ID, so I'm going to ignore using 15:40.420 --> 15:41.470 the blank identifier. 15:41.470 --> 15:43.420 But I do care about checking for an error here. 15:43.840 --> 15:50.920 And that's equal to app dot save order and we pass it the order variable we just created. 15:51.850 --> 15:54.330 So at this point we should check for the error. 15:54.340 --> 16:01.940 Selimi, copy this error checking code and paste it right here at this point when we run this transaction. 16:01.960 --> 16:07.630 Now this will when we actually buy a widget from this page over here. 16:10.010 --> 16:15.590 It should actually save a customer giving us first name, last name and email, then it should save 16:16.190 --> 16:19.180 a transaction, then it should save an order. 16:19.220 --> 16:20.480 That's if we got everything right. 16:20.870 --> 16:25.400 So we'll run our first test on this in the next lecture and we'll keep going.