Creating Payments Controller
In this lesson, we're going to set up Stripe payment service
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the The newline Guide to Fullstack ASP.NET Core and React course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to The newline Guide to Fullstack ASP.NET Core and React with a single-time purchase.

[00:00 - 00:09] Let's create an endpoint now for our payments. So let's close this and inside API controllers, let's create a new payments controller.
[00:10 - 00:19] This will derive from our base controller like always. So here, that's right.
[00:20 - 00:24] Base controller. And now let's create a constructor.
[00:25 - 00:31] And pass payment service. So payment.
[00:32 - 00:45] And let's simply call it payment service. We also need store context.
[00:46 - 01:00] Let's simply call it context. And also, I mapper because from our controller, we need to pass basket.
[01:01 - 01:06] So let's write mapper. Let's import payment service using infrastructure service.
[01:07 - 01:22] Store context using infrastructure and I mapper using automapper. And now let's initialize field from parameter payment service for context and the mapper.
[01:23 - 01:28] Let's start creating the endpoints now. So let's start with the HTTP post request.
[01:29 - 01:46] We are creating a post request because we will be creating a new payment intent . Also, let's authorize this request because we want only the logged in users to be able to purchase the costs.
[01:47 - 01:53] Now let's start writing our method. This will simply return a basket DTO.
[01:54 - 02:07] So like always, let's write public async and it will return task of type. Action, served and basket DTO.
[02:08 - 02:21] Let's call this method payment intent async. Let's work on the imports using task using system threading tasks.
[02:22 - 02:32] Let's import action result using ASP net core at MBC. Let's import basket DTO and authorize using ASP net core authorization.
[02:33 - 02:53] We are returning the basket DTO because we want to store some information with the client because client secret information is not going to be able to use it. We want to store some information with the client because client secret information will be used to make the payment without interacting with the API which is inside our server .
[02:54 - 03:03] And first of all, we need the basket. So let's write basket and to extract the basket, we will have to use the same extract basket method.
[03:04 - 03:16] So let's go back to basket controller and use the extract basket method. Let's copy it from here and paste it below.
[03:17 - 03:28] Now import basket using entity. We need include and also we need order by using system.link.
[03:29 - 03:45] Now our basket will be equal to await extract basket which takes the user name so we can use user.link. User.identity.name.
[03:46 - 03:52] We know the user is available because the method is authorized. So we don't need to make it optional.
[03:53 - 04:00] But the basket can be empty. And if it is empty, we will return an error.
[04:01 - 04:11] So let's check if basket is null. If basket is null, we will return not found error.
[04:12 - 04:30] So not found and inside we will use the new API response class that we created new API response. And we will simply pass the status 404 and let's import the API response using API.error response.
[04:31 - 04:45] Let's start getting the intent now for which we can use the payment service. So here let's write our intent is equal to payment service and we will use the payment intent async method which takes the basket.
[04:46 - 05:03] And if you remember our payment service is responsible for getting the intent and that's what we are getting from here. Now if the intent is null, so let's check if intent is null.
[05:04 - 05:17] If intent is null, that means the payment service is giving us an error. So in this case we can return bad request and again let's use a new API response.
[05:18 - 05:34] And we can pass the status 400 with a message which will say problem creating payment intent. And let's pass semicolon.
[05:35 - 05:42] And it should be problem creating the payment intent. And with the basket we want to return the payment intent ID.
[05:43 - 05:55] So we can write basket dot payment intent ID. So if it has it already, we will simply use this.
[05:56 - 06:06] And if it is null, we can use one from the intent. So I can write intent dot ID because this is basically an intent ID.
[06:07 - 06:12] We see this error because we forgot to mention await here. Now this will resolve it.
[06:13 - 06:22] The same way we will check if the basket has client secret. And let's copy it.
[06:23 - 06:34] If it does, we will use it. Otherwise, if it is null, we can use intent dot client secret.
[06:35 - 06:47] Now let's update the basket using context dot update and let's pass the basket. Let's take it a bit up.
[06:48 - 07:04] Now let's check if the saving was successful. So what we can do is we can put result is equal to and we can use context dot save changes async if it is more than zero.
[07:05 - 07:15] And of course, it should be a wait. Now if the result is not successful, which means if it is zero or false, we want to return again an error.
[07:16 - 07:29] So return bad request. And the same way we will use new API response with the same status 400.
[07:30 - 07:35] And the error title can be problem. Updating.
[07:36 - 07:55] Basket with intent. Finally, if everything is successful, let's return the basket and we'll have to use auto mapper.
[07:56 - 08:09] So let's use mapper dot map. You want to map it from basket to basket TTO and pass the basket here.
[08:10 - 08:21] We also need to make changes to the basket TTO. So let's go to basket TTO because now we are also returning payment intent ID and the client secret.
[08:22 - 08:34] So let's mention it here. First of all, string and it should be payment intent ID and the client secret.
[08:35 - 08:44] So string client secret. Now what we can do is to make this API endpoint available.
[08:45 - 09:00] Let's shut the server and rerun it. We can now open postman and inside module 11, we can make the payment request.
[09:01 - 09:12] And as we see unauthorized, which means the endpoint is available, we just need token in our request header. So what we can do is we can try to log in as a user.
[09:13 - 09:21] So let's run this request and it should be a post request. So let's run it again.
[09:22 - 09:41] And what we need to do is simply copy this token and let's close it and here and inside header, we need to pass authorization. And as a value, we will mention bearer followed by the token.
[09:42 - 09:52] Now, if we try to make this request, we see an error which says problem updating basket with intent. Let's go back to the code to see what happened.
[09:53 - 10:06] So it returns problem updating basket with intent and we are checking it the opposite way we want to check if result is false. Then we want to pass this response.
[10:07 - 10:27] Now, let's open postman again and let's make this request again. Now, as you can see, we also have payment intent ID and the client secret with the response, which means our endpoint is working as expected.
[10:28 - 10:48] Not just that if he opens, so let's open and if we click on payments, we can see incomplete payment with the cost. And if we click on this, we will see all the details related to our payment and we can see it here.
[10:49 - 11:09] And our payment ID will match the payment intent ID. So if we see this and if he open postman and compare this, they both will be seen. And I would just have to use our client to complete this payment. So let's take a look at that next.