PaymentGateway is a payment API application built on top of .Net 6 letting the consumer able to submit payments and then read the transactions status through different endpoints, one by applying the transactionId filter and another by applying the MerchantId filter.
The project structure follows the Clean Architecture design, separating layers into ring levels as shown below:
Domain: It is the center of the application which is not referencing any other project. It contains the domain model, value objects and domain exceptions.Command.Application: It's responsible to submit the payment through commands & events into the database. It is also exposing interfaces implemented by the infrastructure. It's referencing the Domain layer and referenced by the Api & Infrastructure layers.Query.Application: It's responsible to query the transactions from database through the query handler. It is also exposing interfaces implemented by the infrastructure. It's referencing the Domain layer and referenced by the Api & Infrastructure layers.Infrastructure: It's exposing concrete infrastructure implementations as write & read repositories, telemetries...Api: It's exposing the Payments and Transactions Api, the first for write operations and the second for the read ones.
The PaymentGateway has been implemented following the CQRS pattern:
The main benefit is in handling high performance applications. The above design allows you to separate the load from reads and writes allowing you to deploy and scale each application independently based on their needs.
In order to build and run the application the following are some pre-requirements:
- .Net 6 installed in the hosting machine in order to be able to build and run the application from your favourite IDE.
- Docker installed in order to be able to run the application from container.
Both you run from IDE or from Docker you will be able to play with the application endpoints by using the Swagger UI as below
In order to run the application from your favourite IDE, the Checkout.Api needs to be set as default starting project, then F5 or click start from UI as shown below for Visual Studio or Rider:
- Rider:
- Visual Studio:
The application should launch the browser at page https://localhost:5001/swagger/index.html
In order to run the application from Docker, these are the steps to follow:
- Move to the main root where the
Solutionand theDockerfileare placed. - Run the command:
docker build -t checkout-api -f Dockerfile .It should take some seconds to pull all the dependencies and then:
docker run -ti --rm -p 8080:80 checkout-apiThe above command will run your application in interactive mode, mapping it to port 8080 so you should be able to navigate to the swagger page at http://localhost:8080/swagger/index.html and start playing with the endpoints.
Each endpoint exposes its request/response schema.
- Submit one or more payments through the
/api/beta/transactionsendpoint. (use card numbers from Checkout Test card numbers for valid ones). - Use the transactionId from previous response to invoke the
/api/beta/transactions/{id}/and fetch the transaction detail. - Use the merchantId from the previous response to invoke the
/api/beta/merchants/{id}/transactionsand fetch all the transactions against the given merchant. - After playng around with above endpoints, you can try out and have a look at metrics recorder by
Prometheusat the endpoint/api/beta/metrics
The application metrics have being recorded during the Api utilization by Prometheus and available at the endpoint /api/beta/metrics as shown below:
The fake validation has been implemented by running checks against the submitted amounts as the following table. Inspiration taken from Checkout documentation - Soft decline
| Amount ends with | Code | Description |
| 05 | 20005 | Declined - Do not honour |
| 12 | 20012 | Invalid transaction |
| 14 | 20014 | Invalid card number |
| 51 | 20051 | Insufficient funds |
| 54 | 20087 | Bad track data |
| 62 | 20062 | Restricted card |
| 63 | 20063 | Security violation |
| 9998 | 20068 | Response received too late / timeout |
| 150 | 20150 | Card not 3D Secure enabled |
| 6900 | 20150 | Unable to specify if card is 3D Secure enabled |
| 5000 | 20153 | 3D Secure system malfunction |
| 5029 | 20153 | 3D Secure system malfunction |
| 6510 | 20154 | 3D Secure Authentication Required |
| 6520 | 20154 | 3D Secure Authentication Required |
| 6530 | 20154 | 3D Secure Authentication Required |
| 6540 | 20154 | 3D Secure Authentication Required |
| 33 | 30033 | Expired card - Pick up |
| 4001 | 40101 | Payment blocked due to risk |
| 4008 | 40108 | Gateway Reject – Post code failed |
| 2011 | 200R1 | Issuer initiated a stop payment (revocation order) for this authorization |
| 2013 | 200R3 | Issuer initiated a stop payment (revocation order) for all payments |
- Metrics recording through `Prometheus'.
- Dockerization
- Add and manage Idempotency-key on payments post requests
- Using 2 storages or collection/tables, one for the append-only domain events and one for the current state of the domain or aggregate root