Giter Club home page Giter Club logo

simple-psp's Introduction

Simple PSP

A dead simple payment service Provider API to illustrate how transactions are processed and how money becomes available to the merchants.

Architecture

This simplified payment service provider has two main responsabilites: to process card transactions and to settle customer's payables when they are due. In this context, throughput, consistency, and reliability are really important. With this in mind, the architecture here leverages async communication through messaging queues (SQS), and consistency using a SQL database (Postgres, supports database transactions, complex access patterns). When a transaction is received, it gets persisted in the database, and then it will be eventually processed and settled in the background by queue workers. The overall flow in a nutshell is:

  1. HTTP server receives a request to create a transaction
  2. Server persisted it in the database (Postgres)
  3. Server enqueues a message into SQS for further background processing
  4. Workers consume SQS queues. In particular, the payables creation queue is consumed and payables are created for that specific transaction.

drawing

Lastly, when a payable is due, it should be marked it as paid as well as the original transaction. For this, there are batch jobs that queries the database for payables and transactions so that they can be settled.

Directory structure

Inspired by Netflix article on hexagonal architecture.

src // Application code
├── config              // Configuration files.
├── data-sources        // Handles communications with data sources, like databases, messaging queues, and other APIs.
│   ├── postgres
│   │   ├── migrations
│   │   └── models
│   └── sqs
├── lib                 // Utilities reused throughout the codebase.
│   └── errors
├── repositories        // Abstracts data source specific operations from business logic.
├── services            // Where actual business logic is, orchestrates actions.
├── transporters        //  Triggers an interactor to perform business logic. We treat it as an input for our system.
│   ├── jobs            // One-off tasks, batch jobs
│   ├── rest            // Rest HTTP 1.1 server
│   │   ├── controllers
│   │   └── middlewares
│   └── sqs             // SQS queue consumers
│       └── workers
└── validators          // Schemas and validators for business entities and payloads
infrastructure // Terraform code

This structure has a two main advantages that I find particularly interesting:

  • Swapping data sources (like databases) is easier
  • Business actions can be executed/initiated from many differents entrypoints and protocols, such as HTTP, GRPC, messaging queues, CLI, cron jobs, etc.

Tech stack

The Simple PSP project is written in Node.JS and its infrastructure is built as code using Terraform. Here's a complete list of the tech stack used to build the entire project:

  • Node.JS (Express, Sequelize, AWS SDK, Ava, Supertest )
  • Terraform + AWS (RDS, SQS, ECS Fargate, Parameter Storage, ALB, CloudWatch alarms and dashboard)
  • Docker & Docker Compose
  • Github Actions

Local setup

Clone the repository:

git clone [email protected]:0xkalvin/simple-psp.git

cd simple-psp

To start the application just run:

make

This will initialize the necessary infrastructure (Postgres and localstack containers), as well as the PSP API itself.

API

This section describes the resources that make up the API

POST /transactions

Request

curl -XPOST "http://localhost:3000/transactions" --header "Content-Type: application/json" --header "x-customer-id: 123"  --data '{
    "description": "Lightsaber",
    "amount": "2500",
    "payment_method": "credit_card",
    "card_number": "4111111111111111",
    "card_holder_name": "Luke Skywalker",
    "card_expiration_date": "10/25",
    "card_verification_code": "123" }'

Response

201 status code

{
  "id": "24e249f8-ca37-430a-afe9-bf05d9cd5688",
  "description": "Lightsaber",
  "customer_id":"123",
  "amount": 2500,
  "payment_method": "credit_card",
  "card_holder_name": "Luke Skywalker",
  "card_expiration_date": "2025-10-01T00:00:00.000Z",
  "card_verification_code": "123",
  "card_last_four_numbers": "1111",
  "updated_at": "2020-07-19T22:26:23.693Z",
  "created_at": "2020-07-19T22:26:23.693Z"
}

GET /transactions

Request

curl http://localhost:3000/transactions --header "x-customer-id: 123"

Response

200 status code

[
  {
    "id": "24e249f8-ca37-430a-afe9-bf05d9cd5688",
    "customer_id":"123",
    "description": "Lightsaber",
    "amount": 2500,
    "payment_method": "credit_card",
    "card_holder_name": "Luke Skywalker",
    "card_expiration_date": "2025-10-01T00:00:00.000Z",
    "card_verification_code": "123",
    "card_last_four_numbers": "1111",
    "updated_at": "2020-07-19T22:26:23.693Z",
    "created_at": "2020-07-19T22:26:23.693Z"
  }
]

GET /payables

Request

curl http://localhost:3000/payables --header "x-customer-id: 123"

Response

200 status code

[
  {
    "id": "4833e715-fb9b-4c60-8b8f-5bab65ea11e5",
    "customer_id":"123",
    "status": "waiting_funds",
    "payment_date": "2020-08-18T22:26:23.693Z",
    "fee": 5,
    "receivable_amount": 2375,
    "created_at": "2020-07-19T22:26:23.701Z",
    "updated_at": "2020-07-19T22:26:23.701Z",
    "transaction_id": "24e249f8-ca37-430a-afe9-bf05d9cd5688"
  }
]

simple-psp's People

Contributors

0xkalvin avatar dependabot[bot] avatar

Watchers

James Cloos 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.