Skip to content
/ xpay Public

xPay is a digital wallet backend built with Go. It provides a secure foundation for digital financial transactions, including user-auth service, wallet service, card service and multiple payment gateway integrations.

Notifications You must be signed in to change notification settings

ashtishad/xpay

Repository files navigation

xPay: Digital Wallet

Table of Contents

Quick Start

This project supports two environments: Production and Development. Docker Desktop is required to run the application.

Clone the repository:

git clone git@github.com:ashtishad/xpay.git && cd xpay

Production

For users who want to run the project and interact with the API (no code changes):

make setup-prod-env  # Set up the environment
make up              # Run the application

### More Commands
make down            # Stop the application
make down-data       # Stop and remove postgres data

Development

For developers who intend to modify the code and contribute to the project:

make setup-dev-env   # Set up the environment
make up              # Required for starting the postgres docker service
make watch           # Run with live reload

### More Commands
make run             # Run normally
make down            # Stop the application
make down-data       # Stop and remove postgres data
make test            # Run tests
make lint            # Run linter
make swagger         # Generate Swagger docs
make migrate-create name=your_migration_name  # Create a new migration

Note: setup-prod-env and setup-dev-env copy appropriate configurations and set up necessary tools for each environment.

For all available commands, see the Makefile in the project root.

For detailed guide on various aspects of the project, refer to the wiki

Tech Stack

Skills

Core Libraries: Gin, pgx, golang-migrate, golang-jwt, viper, swaggo/swag, golangci-lint, and testify.

Progress

✅ Implemented | 🔄 In Progress/Planned

Area Features and Best Practices Status
API Design & Architecture • Domain Driven Design, Clean Architecure
• RESTful API
• Event streaming with Apache Kafka
• OpenAPI 2.0 specifications


🔄
Security • JWT-ES256 with ECDSA asymmetric key pairs
• AES-256-GCM for card data encryption
• SQL injection prevention with parameterized sql queries
• Role based access control (RBAC)
• DTO for controlled data to the client
• User input and query param validation
• IP-Based Rate limiting with Token Bucket algorithm






Database • ACID transactions with appropriate isolation levels
• Raw SQL for performance
• Connection pooling with pgx, exposing standard *sql.DB
• Optimized indexing and unique constraints
• Version-controlled schema changes with migrations




Core Operations & Observability • Custom AppError interface for error handling
• Centralized configuration management with Viper
• Structured logging with slog
• Context with timeout for each request
• Comprehensive test coverage
• Code quality with golangci-lint





Payment Gateways • Idempotent payment processing
• Stripe integration
• PayPal integration
• Webhook handling for asynchronous events
🔄
🔄
🔄
🔄
Deployment & Monitoring • Multi-stage Docker builds for minimal image size
• GitHub Actions CI pipeline
• AWS RDS with PostgreSQL
• ECS Fargate for serverless container deployment
• Prometheus metrics and Grafana dashboards


🔄
🔄
🔄

Back to Top

Architecture and Request Flow:

The project follows domain-driven design, loosely coupled clean architecture, suited for large codebase.


┌─────────┐    JSON    ┌───────────────┐   Domain   ┌─────────────┐
│ Client  ├───────────►│   Handlers    ├───────────►│ Repositories│
└─────────┘    (DTO)   └───────────────┘   Models   └─────────────┘
                              │                           │
                              │                           │
                              │          Domain           │
                              │          Models           │
                              │                           │
┌─────────┐    JSON    ┌───────────────┐   Domain   ┌─────────────┐
│ Client   ◄───────────┤   Handlers     ◄───────────┤Repositories │
└─────────┘    (DTO)   └───────────────┘   Models   └─────────────┘

Example: Create a wallet

wallet.go (model) -> wallet_repository.go -> wallet_handlers.go (using DTOs)

  1. Domain Models: internal/domain/*.go
  2. Repositories: internal/domain/*_repository.go
  3. HTTP Handlers: internal/server/handlers/*.go
  4. DTOs: internal/server/dto/*.go
  5. Routes: internal/server/routes/*.go

Back to Top

Directory Structure

command: tree -a -I '.git|.DS_Store|.gitignore|.idea|.vscode|docs'

├── .github
│   └── workflows
│       └── test.yaml                 # CI/CD pipeline for running tests
├── internal
│   ├── domain
│   │   ├── card.go                   # Card domain model
│   │   ├── card_repository.go        # Card repository interface, database interactions
│   │   ├── helpers.go                # Domain-specific helper functions
│   │   ├── user.go                   # User domain model
│   │   ├── user_repository.go        # User repository interface, database interactions
│   │   ├── wallet.go                 # Wallet domain model
│   │   └── wallet_repository.go      # Wallet repository interface, database interactions
│   ├── secure
│   │   ├── card_aes.go               # Card AES-256 with GCM mode, Validate, Encrypt and Decrypt
│   │   ├── jwt.go                    # JWT token handling, generate and validate tokens
│   │   ├── password.go               # Password hashing and verification with bcrypt
│   │   └── password_test.go          # Password utility tests
│   │   ├── rbac
│   │   │   ├── policy.json          # RBAC policies for the API
│   │   │   ├── policy.go            # Loading policy from policy.json
│   │   │   ├── rbac.go              # Core logic of RBAC
│   │   │   └── rbac_test.go         # Unit tests
│   ├── server
│   │   ├── handlers
│   │   │   ├── auth.go               # Login, Register handlers
│   │   │   ├── card.go               # Card http handlers
│   │   │   ├── helpers.go            # Handlers helper functions
│   │   │   ├── user.go               # User HTTP handlers
│   │   │   └── wallet.go             # Wallet HTTP handlers
│   │   ├── middlewares
│   │   │   ├── auth.go               # Auth middleware (Validate token, Set Authorized user in req context)
│   │   │   ├── cors.go               # CORS middleware
│   │   │   ├── gin_logger.go         # Custom Logging middleware for gin
│   │   │   ├── middlewares.go        # Core Middleware setup
│   │   │   ├── rate_limiter.go       # IP-Based rate limiter with token bucket algorithm
│   │   │   └── request_id.go         # Request ID middleware, sets X-Request-ID header
│   │   ├── routes
│   │   │   ├── auth.go               # Authentication routes
│   │   │   ├── card.go               # Card routes
│   │   │   ├── routes.go             # Core routes setup
│   │   │   ├── user.go               # User  routes
│   │   │   └── wallet.go             # Wallet routes
│   │   ├── dto
│   │   │   ├── auth.go               # Authentication-related DTOs/REST API Request Response Structurers
│   │   │   ├── card.go               # Card dto
│   │   │   ├── shared.go             # Shared dto
│   │   │   ├── user.go               # User  dto
│   │   │   └── wallet.go             # Wallet routes
│   │   └── server.go                 # HTTP server setup with gin
│   ├── infra
│   │   ├── postgres
│   │   │   ├── postgres_connection.go    # Postgres connection setup with pgx, returns *sql.DB
│   │   │   └── postgres_migrations.go    # Database migration handling with golang-migrate/v4
│   │   ├── kafka
│   │   │   └── sample.md                 # Placeholder for Kafka integration
│   ├── common
│   │   ├── app_errs.go               # Custom error types
│   │   ├── config.go                 # Configuration management
│   │   ├── constants.go              # Global constants
│   │   ├── context_keys.go           # Context key definitions
│   │   ├── custom_err_messages.go    # Error message definitions
│   │   ├── slog_config.go            # Structured logging configuration
│   │   └── timeouts.go               # Context timeout constants
├── migrations
│   ├── 000001_create_users_table.down.sql   # User table rollback
│   ├── 000001_create_users_table.up.sql     # User table creation
│   ├── 000002_create_wallets_table.down.sql # Wallet table rollback
│   └── 000002_create_wallets_table.up.sql   # Wallet table creation
│   ├── 000003_create_cards_table.down.sql   # Cards table rollback
│   └── 000003_create_cards_table.up.sql     # Cards table creation
├── scripts/
│   ├── pre-push                      # Git pre-push hook (runs tests and lint before every push)
│   ├── setup-dev-env.sh              # Script to set up development environment
│   └── setup-prod-env.sh             # Script to set up production environment
├── env-configs/
│   ├── dev.Makefile                  # Makefile for development environment
│   ├── prod.Makefile                 # Makefile for production environment
│   ├── compose.dev.yaml              # Docker Compose file for development
│   ├── compose.prod.yaml             # Docker Compose file for production
│   └── config.example.yaml           # Example configuration file
├── config.yaml                       # Application configuration
├── main.go                           # Application entry point
├── Makefile                          # Development commands and shortcuts
├── Dockerfile                        # Docker file with multi stage builds
├── .dockerignore                     # Directories to ignore in the Docker builds
├── README.md                         # Project documentation
├── compose.yaml                      # Docker Compose configuration
├── go.mod                            # Go module definition
├── go.sum                            # Go module checksums
└── .air.toml                         # Live reload configuration with air

Back to Top

API Documentation

Authentication Endpoints

Register User

  • URL: /api/v1/register
  • Method: POST
  • Description: Registers a new user with hashed password, generates JWT tokens, sets an HTTP-only cookie and X-Request-Id header.
  • Access: Public
  • Request Body:
    {
      "fullName": "John Doe",
      "email": "someone@example.com",
      "password": "samplepass"
    }
  • Success Response: 201 Created
  • Error Responses: 400 Bad Request, 409 Conflict, 500 Internal Server Error

Login

  • URL: /api/v1/login
  • Method: POST
  • Description: Authenticate a user, verifies password, generates JWT token, sets an HTTP-only cookie and X-Request-Id header.
  • Access: Public
  • Request Body:
    {
      "email": "someone@example.com",
      "password": "samplepass"
    }
  • Success Response: 200 OK
  • Error Responses: 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error

User Management Endpoints

Create User with Specific Role

  • URL: /api/v1/users
  • Method: POST
  • Description: Creates a new user with a specific role.
  • Access: Admin (can create any role), Agent (can create user or merchant roles)
  • Authentication: Required (Bearer Token)
  • Request Body:
    {
      "fullName": "Keanu Reeves",
      "email": "keanu@example.com",
      "password": "keanupass",
      "role": "admin"
    }
  • Success Response: 201 Created
  • Error Responses: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 409 Conflict, 500 Internal Server Error

Wallet Endpoints

Create a New Wallet

  • URL: /api/v1/users/{user_uuid}/wallets
  • Method: POST
  • Access: Admin, Merchant, User
  • Authentication: Required (Bearer Token)
  • Request Body:
    {
      "currency": "USD"
    }
  • Success Response: 201 Created
  • Error Responses: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 409 Conflict, 500 Internal Server Error

Get Wallet Balance

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/balance
  • Method: GET
  • Access: Admin, Agent, Merchant, User (own wallet only)
  • Authentication: Required (Bearer Token)
  • Success Response: 200 OK
  • Error Responses: 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

Update Wallet Status

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/status
  • Method: PATCH
  • Access: Admin, Agent, Merchant, User (own wallet only)
  • Authentication: Required (Bearer Token)
  • Request Body:
    {
      "status": "inactive"
    }
  • Success Response: 200 OK
  • Error Responses: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

Card Endpoints

Add a New Card to Wallet

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards
  • Method: POST
  • Access: Admin, Merchant, User (own wallet only)
  • Authentication: Required (Bearer Token)
  • Request Body:
    {
      "cardNumber": "4111111111111111",
      "provider": "visa",
      "type": "credit",
      "expiryDate": "12/25",
      "cvv": "123"
    }
  • Success Response: 201 Created
  • Error Responses: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 500 Internal Server Error

Get Card Details

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards/{card_uuid}
  • Method: GET
  • Access: Admin, Agent (read-only), Merchant, User (own cards only)
  • Authentication: Required (Bearer Token)
  • Success Response: 200 OK
  • Error Responses: 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

Update Card Details

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards/{card_uuid}
  • Method: PATCH
  • Access: Admin, Merchant, User (own cards only)
  • Authentication: Required (Bearer Token)
  • Request Body:
    {
      "expiryDate": "12/26",
      "status": "inactive"
    }
  • Success Response: 200 OK
  • Error Responses: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

Delete Card

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards/{card_uuid}
  • Method: DELETE
  • Access: Admin, Merchant, User (own cards only)
  • Authentication: Required (Bearer Token)
  • Success Response: 200 OK
  • Error Responses: 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

List Cards

  • URL: /api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards
  • Method: GET
  • Access: Admin, Agent (read-only), Merchant, User (own wallet only)
  • Authentication: Required (Bearer Token)
  • Query Parameters:
    • provider (optional): Filter by card provider
    • status (optional): Filter by card status
  • Success Response: 200 OK
  • Error Responses: 401 Unauthorized, 403 Forbidden, 500 Internal Server Error

Back to Top

About

xPay is a digital wallet backend built with Go. It provides a secure foundation for digital financial transactions, including user-auth service, wallet service, card service and multiple payment gateway integrations.

Topics

Resources

Stars

Watchers

Forks