AbdelrahmanRadwan / paymentGateway

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Summary

Question Answer
Time Spent for design and implementation 2 hours, 47 minutes
Technologies Java17, Spring Boot, PostgreSQL, Hibernate
Features 1. Store Card.
2. Retrieve Cards information by merchant and userId
3. Process payment.
4. Retrieve payments using user and merchant
5. Pull latest payment status updates
Run Docker, Docker Compose, or manual DB creation with app running.
Mock Bank Bank is mocked through another API running locally.
Main Missing Components 1. Authorization and Authentication roles
2. Data Encryption of Card information.
3. Request Validatoin
4. Unit and Integration tests.
5. Async communication to allow bank updates coming from the banks.
6. Delete/Update endpoint to update/delete cards.
7. Error handling of different cases in the endpoints.
8. Generate a unique API key for each merchant.
7. Use UUIDs instead of sequential IDs to prevent malicious reverse engineering

High Level Async Design

This is the design I would implement in real life to make sure that the updated payment status is accessible from the merchant easily.

High Level System Architecture View on LucidChart

For the sake of simplicity, There is no queue integration in the current implementation. However, there is a simple mocked response that is being sent through a mockBank API which is requested through a Callable

High Level System Architecture View on LucidChart


Motivation

This is a payment gateway that helps to collect money for merchants, store cards information, and keep track of payments history.


Requirements

  1. Store card information.
  2. Retrieve card information.
  3. Process a payment through the gateway.
  4. Retrieve payments.

Setup

Easy Setup

  • Just run docker-compose up, and it will spin up the app service and the postgres service.
  • The service will be running on http://localhost:8080/

Alternative Setup

  1. Create the database:
sudo docker run --name payments -p 5432:5432 -e POSTGRES_USER=test -e POSTGRES_PASSWORD=test -d postgres

Output:

CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                    NAMES
32e7a0f07ba8   postgres   "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes   0.0.0.0:5432->5432/tcp   payments
  1. Run the service through running PaymentGatewayApplication

Payment Gateway API

Card Operations

  1. Get the stored cards for a specific user in a specific merchant:
GET http://localhost:8080/api/card/merchant/{merchantId}/user/{userId}

Return:

[
    {
        "cardId":652,
        "userId":"123",
        "merchantId":"1234",
        "displayCardNumber":"**** **** **** 8765",
        "createdAt":1675531493858,
        "updatedAt":1675531493859
    }
]
  1. Add a card for a specific user in a specific merchant:
POST http://localhost:8080/api/card/merchant/{merchantId}/user/{userId}

Request Body:

{
	"cardNumber": "1234 5678 4321 8765",
	"displayName": "Addy",
	"expMonth": 1,
	"expYear": 25,
	"cvv": 123
}		

Return:

{
    "cardId": 702,
    "userId": "123",
    "merchantId": "1234",
    "displayCardNumber": "**** **** **** 8765",
    "createdAt": 1675540931248,
    "updatedAt": 1675540931248
}

Payment Operations

  1. Get the payment history for a specific user in a specific merchant:
GET http://localhost:8080/api/payment/merchant/{merchantId}/user/{userId}

Return:

[
    {
        "paymentId":652,
        "cardId":503,
        "merchantId":"1234",
        "userId":"123",
        "paymentStatus":"PROCESSING",
        "createdAt":1675534050928,
        "updatedAt":1675534055027
    },
    {
        "paymentId":752,
        "cardId":652,
        "merchantId":"1234",
        "userId":"123",
        "paymentStatus":"SUCCESSFUL",
        "createdAt":1675538891083,
        "updatedAt":1675538905975
    }
]
  1. Make a payment for a specific user in a specific merchant using a specific payment card:
POST http://localhost:8080/api/payment/merchant/{merchantId}/user/{userId}

Request Body:

{
  "cardId": 652,
  "amount": 550.89,
  "currency": "USD"
}

Return:

{
    "paymentId": 802,
    "cardId": 652,
    "merchantId": "1234",
    "userId": "123",
    "paymentStatus": "PROCESSING",
    "createdAt": 1675541283655,
    "updatedAt": 1675541283655
}
  1. Get the payment status
GET http://localhost:8080/api/payment/merchant/{merchantId}/user/{userId}/payment/{paymentId}

Return:

{
    "paymentId":752,
    "cardId":652,
    "merchantId":"1234",
    "userId":"123",
    "paymentStatus":"SUCCESSFUL",
    "createdAt":1675538891083,
    "updatedAt":1675538905975
}

Mock Bank API

The mock bank API has two endpoints.

  1. Process a payment
POST http://localhost:8080/mockBank/processPayment
  1. Get updated payment status
GET http://localhost:8080/mockBank/paymentStatus/merchant/{merchantId}/user/{userId}/payment/{paymentId}

Sequence Diagram

High Level Sequence Diagram

View Sequence Diagram on LucidChart


About


Languages

Language:Java 94.3%Language:Kotlin 5.2%Language:Dockerfile 0.4%