Giter Site home page Giter Site logo

epay-integration's Introduction

EPAY-Integration

Simple EPAY Integration with ASP.NET Core WebAPI, Razor Pages

alt text

Configuration

  1. Configuration model EPAY.EPAYConfiguration.cs:
public class EPAYConfiguration
{
    public string Username { get; set; }

    public string Password { get; set; }

    public string ServiceId { get; set; }

    public string SecretKey { get; set; }
}
  1. Configuration sub-section in appsettings.json:
"EPAYConfiguration": {
  "Username": "",
  "Password": "",
  "ServiceId": "",
  "SecretKey": ""
}
  1. Registered configuration in Startup.cs's ConfigureServices method:
services.Configure<EPAYConfiguration>(Configuration.GetSection(nameof(EPAYConfiguration)));

Integration

  1. HTTP GET Request model EPAY.EPAYRequest.cs:
public class EPAYRequest
{
    [BindProperty(Name = "OP")]
    public string OP { get; set; }

    [BindProperty(Name = "USERNAME")]
    public string Username { get; set; }

    [BindProperty(Name = "PASSWORD")]
    public string Password { get; set; }

    [BindProperty(Name = "CUSTOMER_ID")]
    public string CustomerId { get; set; }

    [BindProperty(Name = "SERVICE_ID")]
    public string ServiceId { get; set; }

    [BindProperty(Name = "PAY_AMOUNT")]
    public int PayAmount { get; set; }

    [BindProperty(Name = "PAY_SRC")]
    public string PaySource { get; set; }

    [BindProperty(Name = "PAYMENT_ID")]
    public string PaymentId { get; set; }

    [BindProperty(Name = "EXTRA_INFO")]
    public string ExtraInfo { get; set; }

    [BindProperty(Name = "HASH_CODE")]
    public string HashCode { get; set; }
}
  1. WebAPI Implementation
[Route("api/[controller]")]
[ApiController]
public class EPAYController : ControllerBase
{
    private readonly EPAYConfiguration _epayConfig;
    private readonly ApplicationDbContext _context;

    public EPAYController(IOptions<EPAYConfiguration> options
        //, ApplicationDbContext context
        )
    {
        _epayConfig = options.Value;
        //_context = context;
    }

    [HttpGet]
    public async Task<IActionResult> Get([FromQuery]EPAYRequest epayRequest)
    {
        // NOTE: Some validations are missing, you can implement them on your own. (e.g ResponseStatusCode.QueryParameterMissing, ResponseStatusCode.QueryParameterValueInvalid, etc)

        if (!EPAYHelper.IsValidEPAYRequest(HttpContext.Request, epayRequest, _epayConfig, out string responseContent))
        {
            return Content(responseContent);
        }

        if (!Enum.TryParse(epayRequest.OP, true, out OperationType operationType))
        {
            throw new NotSupportedException(epayRequest.OP.ToString());
        }

        if (operationType == OperationType.PING)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK));
        }

        // EPAYRequest.CUSTOMER_ID is Customer Mobile or Email
        var customer = await _context.Customers.SingleOrDefaultAsync(s => s.Mobile == epayRequest.CustomerId || s.Email.ToUpper() == epayRequest.CustomerId.ToUpper());

        if (customer == null)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.CustomerNotFound));
        }

        if (operationType == OperationType.VERIFY)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK));
        }

        if (operationType == OperationType.DEBT)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK, EPAYHelper.ConvertGELToEPAYAmount(customer.Balance), customer.FirstName, customer.LastName));
        }

        if (operationType == OperationType.PAY)
        {
            var duplicatePayment = await _context.Payments.SingleOrDefaultAsync(s => s.ExternalId == epayRequest.PaymentId);
            if (duplicatePayment != null)
            {
                return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.InvalidPaymentIdNonUnique));
            }

            var payment = new Payment
            {
                ExternalId = epayRequest.PaymentId,
                ExternalAadditionalInformation = epayRequest.ExtraInfo,
                Amount = EPAYHelper.ConvertEPAYAmountToGEL(epayRequest.PayAmount),
                CustomerId = customer.Id
            };
            await _context.Payments.AddAsync(payment);

            customer.Balance += payment.Amount;

            await _context.SaveChangesAsync();

            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK, receiptId: payment.Id));
        }

        return BadRequest();
    }
}
  1. Razor Page Implementation /Pages/EPAY/Index.cshtml.cs:
[BindProperties(SupportsGet = true)]
public class IndexModel : PageModel
{
    private readonly EPAYConfiguration _epayConfig;
    private readonly ApplicationDbContext _context;

    public IndexModel(IOptions<EPAYConfiguration> options
        //, ApplicationDbContext context
        )
    {
        _epayConfig = options.Value;
        //_context = context;
    }

    public EPAYRequest EPAYRequest { get; set; }

    public async Task<IActionResult> OnGetAsync()
    {
        // NOTE: Some validations are missing, you can implement them on your own. (e.g. ResponseStatusCode.QueryParameterMissing, ResponseStatusCode.QueryParameterValueInvalid, etc.)

        if (!EPAYHelper.IsValidEPAYRequest(HttpContext.Request, EPAYRequest, _epayConfig, out string responseContent))
        {
            return Content(responseContent);
        }

        if (!Enum.TryParse(EPAYRequest.OP, true, out OperationType operationType))
        {
            throw new NotSupportedException(EPAYRequest.OP.ToString());
        }

        if (operationType == OperationType.PING)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK));
        }

        // EPAYRequest.CustomerId is Customer Mobile or Email
        var customer = await _context.Customers.SingleOrDefaultAsync(s => s.Mobile == EPAYRequest.CustomerId || s.Email.ToUpper() == EPAYRequest.CustomerId.ToUpper());

        if (customer == null)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.CustomerNotFound));
        }

        if (operationType == OperationType.VERIFY)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK));
        }

        if (operationType == OperationType.DEBT)
        {
            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK, EPAYHelper.ConvertGELToEPAYAmount(customer.Balance), customer.FirstName, customer.LastName));
        }

        if (operationType == OperationType.PAY)
        {
            var duplicatePayment = await _context.Payments.SingleOrDefaultAsync(s => s.ExternalId == EPAYRequest.PaymentId);
            if(duplicatePayment != null)
            {
                return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.InvalidPaymentIdNonUnique));
            }

            var payment = new Payment
            {
                ExternalId = EPAYRequest.PaymentId,
                ExternalAadditionalInformation = EPAYRequest.ExtraInfo,
                Amount = EPAYHelper.ConvertEPAYAmountToGEL(EPAYRequest.PayAmount),
                CustomerId = customer.Id
            };
            await _context.Payments.AddAsync(payment);

            customer.Balance += payment.Amount;

            await _context.SaveChangesAsync();

            return Content(EPAYHelper.BuildResponseContent(ResponseStatusCode.OK, receiptId: payment.Id));
        }

        return BadRequest();
    }
}

epay-integration's People

Contributors

dmamulashvili avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.