README

applyze_payment

Applyze Payment Service

Table of Contents


Summary

Directories Description
Contexts Database contexts are here. Currently MongoDB Context is here.
Controllers Default folder of MVC for Controllers. Controller Versions are seperated by folders like V1, V2 etc.
Dtos Includes Data Transfer Objects inside. They're grouped by Request and Response.
Extensions Includes Classes with Extension Methods.
Helpers Includes helper class to make things easier.
Middleware Includes stuffs which handles and works for all requests. Like Auth., Exceptions etc.
Models Default folder of MVC for Models. Includes database models and service models.
Repositories Includes queries of database. It's an access layer to database.
Services Includes connections of services. It's an access layer to other services. Like Payment, Tenant etc.

Constants

Constants.cs is ignored by default. This may have sensitive datas. You should use your own Constants class locally. Create a Constants.cs to your local and add following constants:

    public class Constants
    {
#if DEBUG

        public const string TENANT_BASE_URL = "";
        public const string ECOMMERCE_BASE_URL = "";
        public const string SECRET_KEY = "";        
        public const string CALLBACK_BASE_BASE_URL = "";
        //DEBUG PARAMETERS HERE
        
#else   //------------------------------------

        public const string TENANT_BASE_URL =  "";
        public const string ECOMMERCE_BASE_URL = "";
        public const string SECRET_KEY = "";
        public const string CALLBACK_BASE_BASE_URL = "";
        //RELEASE PARAMETERS HERE

#endif
    }

Midlewares

Authorization

All requests to this API must have api-Key and app-key in header. These are handled in Middleware.Authenticator.

And it's configured on startup with app.UseAuthenticator(); in Configure() method.

Authentication

Authentication is provided by Applyze Tenant Microservice. Communication between services are providing by HTTP.

Services.Abstraction.ITenantService is called to connect Tenenat Service and this interface implemented to Services.Concrate.TenantService.

All proccess are handled in Middleware.Authenticator. After authentication, App data added to HttpContext.Items, it can be used from anywhere until request finishes.

Filters

Filters allows to define some requirements to Controllers or actions.

  • SecretKeyRequiredAttribute is to validate user to modify sensitive datas.
[SecretKeyRequired] //  < --- This endpoint requires secret key in header.
public IActionResult Get()
{
        //do something...
}
  • ConfigurationRequiredAttribute is to get app's payment configurations from eCommerce Service for payment endpoints. Endpoints without this attribute, won't try to get configuration from eCommerce Service.
[ConfigurationRequired] //  < --- This endpoint requires payment configurations.
public IActionResult Get()
{
    //do something...
}

Exception Handler & Logging

All Exceptions are handling and logging in Middleware.ExceptionHandler . It's configured on startup with app.ConfigureExceptionHandler() Also logger can be sent to ExceptionHandler to logging exceptions.

Project use GrayLog. Its configured at Program.cs with ConfigureLogging(). And it's parameters are can be changed from appsettings.json.

When an exception handled, 500 Internal Server Error returns.

To return 400 Bad Request response, you can throw CustomException with message.

 //Exception handler returns 400 Bad Request
 throw new CustomException("name parameter is invalid!");  

Controllers

Controllers are seperated by Api Versions. Naming is like Controllers.V (Controllers.V1).

  • To manage all controllers from one point, There is BaseController under Controllers folder. This provides to reach Authenticated App data from Controller via calling App property in any controller inherits BaseController.
        
            //---- in a controller which inherits from BaseController.---
            //...
            if (!ModelState.IsValid)
                return GetBadRequest(ModelState);       

                            //Example: App from here comes from BaseController.
            await paymentRepository.AddAsync(App.id, payment); // < ----
            //...      

  • Also BaseController has some ready response message methods to standardize all responses. All Endpoints response with ApiResult model:
ApiResult {
    Result  : boolean
    Message : string
    Data    : object
}

IPaymentService

IPaymentService Interface is located in Services.Abstraction. This interface includes all payment functionalities and controllers are using this. To import more than one payment classes into system; just implement this interface to new class and configure on Startup.cs like:

            // **Payment Injection to IPaymentService**
            services.AddPayment<IyzicoService>();       // < --- One of Payment Service
            services.AddPayment<PayUService>();         // < --- One of Payment Service
            //services.AddPayment<YourNewService>();    // < --- Add new Payment Services
            //...
            services.BuildPayment<IPaymentService>();   // < --- Interface to Inject

AddPayment method configured in Helpers.PaymentProviderFactory.

Then, to call a payment provider;

        private readonly Func<string, IPaymentService> paymentAccessor;

        public PaymentsController(Func<string, IPaymentService> paymentAccessor) //Constructor
        {
            this.paymentAccessor = paymentAccessor;
        }

And, to use:

            //to get one service's interface
            IPaymentService paymentService = paymentAccessor("iyzico");
            IPaymentService paymentService = paymentAccessor("payu");
            //...

            //or directly pass parameters:
            var response = await paymentAccessor(provider).PayAsync(dto);

Payment ErrorCodes

Payment error codes are standardized by Enum. You can find codes from State and StateCode in any Payment Request response data. You can see enum and codes following block:

StateCode State Description
0 None Successful
800 NOT_SUFFICIENT_FUNDS Balance is not enough
801 DO_NOT_HONOUR Process did not approved
900 INVALID_PAYMENT_INFO Card Info is not correct
901 LOST_OR_STOLEN_CARD Lost or stolen card. Keep the card.
902 EXPIRED_CARD Date is expired of card
903 INVALID_CVC2 Invalid Cvc
904 DEBIT_CARDS_REQUIRES_3DS This process requires 3D Secure
905 DEBIT_CARDS_INSTALLMENT_NOT_ALLOWED Installment can't be applied with Debit card
906 TOO_MANY_INVALID_ATTEMPTS Too many invalid attempts
907 NOT_ENOUGH_LIMIT Limit is not enough for this amount
1000 Other Any other errors
1100 INVALID_ENUM invalid an enum like Currency, Locale or RefundReason
1101 ALREADY_DONE_BEFORE The proccess done before

To be continued...