Skip to content

hamsheed-salamut/checkout.com-paymentgateway-api

Repository files navigation

Checkout.com - Payment Gateway API

Bank-Payment-Merchant ASP.Net Core 2.1 With C#.Net, EF Core and SQL Server


Introduction

This is an ASP.NET Core Application that allows a merchant to process a payment through a secure payment gateway. The payment gateway communicates with an issuing bank (simulator) to perform payment transactions requested by the client.

Application Architecture

The diagram illustrates the flow of the application as follows:

  • Client: The client submits an order for an item on an online store
  • Online Store: The online store contacts the payment gateway, which in turn requests the client to authenticate himself with his credentials.
  • Payment Gateway: Once the authentication is completed, the payment gateway requires the client to confirm and pay for the order
  • Issuing Bank: The payment gateway confirms the transaction through an issuing bank, which in turns credit the merchant’s account and debit the client’s account checkout_1

Design of Application

  • Onion Architecture

onion_arch

Security: JWT Token Based Authentication

JWT Token based authentication is implementated to secure the WebApi for the Payment Gateway. When the user logins to the payment gateway, the gateway issues a valid token after validating the user credentials. The API Gateway sends the token to the client. The client app uses the token for the subsequent request.

checkout_3

In the appsettings.json file, the secret key has been defined as follows:

{
  "AppSettings": {
    "Secret": "Checkout.com helps your business to offer more payment methods and currencies"
  },

Development Environment

Technologies

  • C# NET
  • ASP.NET Core 2.1 Web API

Tools

  • Entity Framework Core (For Data Access)
  • Swash Buckle (For API Documentation)
  • xUnit (For Unit Testing)
  • Fluent Validations in ASP.NET Core Web API (For API validations)
  • NLogging (For Application Logging)
  • ASP.NET Core Dependency Injection
  • Moq Unit Test (For configuring test-time-only mock versions of dependencies)
  • RestSharp Library (For consuming REST APIs)

Web Api Endpoints

End points configured and accessible through Issuing Bank (Bank Simulator) API

  1. Uri: "api/bank" [HttpPost] - To perform debit and credit transactions

End points configured and accessible through Payment Gateway API

  1. Uri: "api/payment/authenticate" [HttpPost] - To authenticate user and issue a valid token
  2. Uri: "api/payment" [HttpPost] - To process payment through gateway
  3. Uri: "api/payment" [HttpGet("{id}")] - To retrieve all transactions by passing a merchant unique identifier as parameter

Solution Structure

checkout_4

Swagger API Documentation

Swashbuckle Nuget package added to the "Payment.WebApi" and Swagger Middleware configured in the startup.cs for API documentation. when running the WebApi service, the swagger UI can be accessed through the swagger endpoint "/swagger".

public void ConfigureServices(IServiceCollection services)
{            
       services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "Payment API", Version = "V1" });
        });
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory log)
{           
     app.UseSwagger();
     app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "post API v1"); });        
}

checkout_5

Testing Fluent Validation

  • Configure Fluent Validation

In the startup.cs, the following configurations are added:

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddFluentValidation();

            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = (context) =>
                {
                    var errors = context.ModelState.Values.SelectMany(x => x.Errors.Select(e => e.ErrorMessage)).ToList();

                    var result = new
                    {
                        Code = "00009",
                        Message = "Validation Errors",
                        Errors = errors
                    };

                    return new BadRequestObjectResult(result);
                };
            });
        }
  • Testing the custom validator with Postman

checkout_11

Application Logging: NLogging

The NLogging Nuget package has been added to the Payment Gateway project for monitoring. The logs are stored in the C:\Users\Public\checkout\ folder.

  <targets>
    <target name="logfile" xsi:type="File" fileName="C:/Users/Public/checkout/LOG/${shortdate}_log.txt" layout="${longdate} ${level:uppercase=true} ${message}"/>
  </targets>

How to run the Application

  1. Download the BAK SQL files from the repo.
  2. Restore the BAK files against SQL server to create the necessary tables and sample data
  3. Open the solution (.sln) in Visual Studio 2017 or later version
  4. Configure the SQL connection string in Bank.WebApi -> appsettings.json and Payment.WebApi -> appsettings.json
  5. Run the following projects in the solution:
  • Bank.WebApi
  • Payment.WebApi
  • Merchant.UI by setting multiple startups projects in the solution's properties

Sample data to test

Email Password User Type
[email protected] test shopper

Demo: Merchant Portal and Gateway Client

  • Merchant Portal checkout_6

  • Payment Gateway Authentication checkout_7

  • Payment Gateway Payment Confirmation checkout_8

  • Payment Successful checkout_9

Unit Testing in ASP.NET Core

  • xUnit Project: Payment.Test

Configure the PaymentTestController to mock the dependencies of the PaymentController in the Payment.WebApi to carry out the unit testing.

Example:

public class PaymentTestController
    {
        private readonly Mock<IUserService> _userService;
        private readonly Mock<ICardService> _cardService;
        private readonly Mock<ITransactService> _transactService;
        private Mock<Common.Logger.ILogger> _logger;
     
        public PaymentTestController()
        {
            _userService = new Mock<IUserService>();
            _cardService = new Mock<ICardService>();
            _transactService = new Mock<ITransactService>();
            _logger = new Mock<Common.Logger.ILogger>();

        }

        [Fact]
        public void User_Pay_OkObjectResult()
        {
            var controller = new PaymentController(_userService.Object, _cardService.Object,  _transactService.Object,  _logger.Object);
            var pay = new Payments()
            {
                AccountNumber = 2,
                Amount = 100,
                CardNumber = 4261392791756353,
                Cvv = 812,
                ExpiryDate = DateTime.Now.AddDays(5),
                Token = "token",
                MerchantAccountNumber = 3
            };

            var data = controller.Post(pay);

            Assert.IsType<OkObjectResult>(data);
        }
  • Unit Tests Execution in Text Explorer checkout_10

About

Bank-Payment-Merchant

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published