{"id":15968876,"url":"https://github.com/ashtishad/xpay","last_synced_at":"2026-04-09T10:38:00.914Z","repository":{"id":258196675,"uuid":"868614643","full_name":"ashtishad/xpay","owner":"ashtishad","description":"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.","archived":false,"fork":false,"pushed_at":"2025-03-01T17:22:41.000Z","size":222,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T04:31:42.518Z","etag":null,"topics":["aws","docker","domain-driven-design","go","golang","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ashtishad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-06T20:30:39.000Z","updated_at":"2025-03-01T17:22:45.000Z","dependencies_parsed_at":"2024-10-18T00:48:27.700Z","dependency_job_id":"243b04ec-a191-4bd1-927c-107aaa19d413","html_url":"https://github.com/ashtishad/xpay","commit_stats":null,"previous_names":["ashtishad/xpay"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashtishad%2Fxpay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashtishad%2Fxpay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashtishad%2Fxpay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashtishad%2Fxpay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ashtishad","download_url":"https://codeload.github.com/ashtishad/xpay/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245702590,"owners_count":20658642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","docker","domain-driven-design","go","golang","postgresql"],"created_at":"2024-10-07T19:04:21.874Z","updated_at":"2026-04-09T10:37:55.864Z","avatar_url":"https://github.com/ashtishad.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## xPay: Digital Wallet\n\u003ca name=\"top\"\u003e\u003c/a\u003e\n\n## Table of Contents\n- [Quick Start](#quick-start)\n- [Tech Stack](#tech-stack)\n- [Progress](#progress)\n- [Architecture and Request Flow](#architecture-and-request-flow)\n- [Directory Structure](#directory-structure)\n- [API Documentation](#api-documentation)\n\n## Quick Start\n\nThis project supports two environments: Production and Development. Docker Desktop is required to run the application.\n\nClone the repository:\n```bash\ngit clone git@github.com:ashtishad/xpay.git \u0026\u0026 cd xpay\n```\n\n### Production\nFor users who want to run the project and interact with the API (no code changes):\n```bash\nmake setup-prod-env  # Set up the environment\nmake up              # Run the application\n\n### More Commands\nmake down            # Stop the application\nmake down-data       # Stop and remove postgres data\n```\n\n### Development\nFor developers who intend to modify the code and contribute to the project:\n```bash\nmake setup-dev-env   # Set up the environment\nmake up              # Required for starting the postgres docker service\nmake watch           # Run with live reload\n\n### More Commands\nmake run             # Run normally\nmake down            # Stop the application\nmake down-data       # Stop and remove postgres data\nmake test            # Run tests\nmake lint            # Run linter\nmake swagger         # Generate Swagger docs\nmake migrate-create name=your_migration_name  # Create a new migration\n```\n\n\u003e **Note:** `setup-prod-env` and `setup-dev-env` copy appropriate configurations and set up necessary tools for each environment.\n\n\u003e **For all available commands, see the `Makefile` in the project root.**\n\n\u003e **For detailed guide on various aspects of the project, refer to the [wiki](https://github.com/ashtishad/xpay/wiki)**\n\n\n## Tech Stack\n\n\u003cp align=\"left\"\u003e\n  \u003ca href=\"https://www.linkedin.com/in/ashef/\"\u003e\n    \u003cimg src=\"https://skillicons.dev/icons?i=go,docker,kubernetes,postgresql,aws,kafka\u0026theme=light\" alt=\"Skills\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n**Core Libraries:** [Gin](https://github.com/gin-gonic/gin), [pgx](https://github.com/jackc/pgx),  [golang-migrate](https://github.com/golang-migrate/migrate), [golang-jwt](https://github.com/golang-jwt/jwt/), [viper](https://github.com/spf13/viper), [swaggo/swag](https://github.com/swaggo/swag), [golangci-lint](https://golangci-lint.run/), and [testify](https://github.com/stretchr/testify).\n\n## Progress\n\n✅ Implemented | 🔄 In Progress/Planned\n\n| Area | Features and Best Practices | Status |\n|------|------------------------------|--------|\n| API Design \u0026 Architecture | • Domain Driven Design, Clean Architecure \u003cbr\u003e• RESTful API\u003cbr\u003e• Event streaming with Apache Kafka\u003cbr\u003e• OpenAPI 2.0 specifications | ✅\u003cbr\u003e✅\u003cbr\u003e🔄\u003cbr\u003e✅ |\n| Security | • JWT-ES256 with ECDSA asymmetric key pairs\u003cbr\u003e• AES-256-GCM for card data encryption\u003cbr\u003e• SQL injection prevention with parameterized sql queries\u003cbr\u003e• Role based access control (RBAC) \u003cbr\u003e• DTO for controlled data to the client\u003cbr\u003e• User input and query param validation\u003cbr\u003e• IP-Based Rate limiting with Token Bucket algorithm | ✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅ |\n| Database | • ACID transactions with appropriate isolation levels\u003cbr\u003e• Raw SQL for performance\u003cbr\u003e• Connection pooling with pgx, exposing standard *sql.DB\u003cbr\u003e• Optimized indexing and unique constraints\u003cbr\u003e• Version-controlled schema changes with migrations | ✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅ |\n| Core Operations \u0026 Observability | • Custom AppError interface for error handling\u003cbr\u003e• Centralized configuration management with Viper\u003cbr\u003e• Structured logging with slog\u003cbr\u003e• Context with timeout for each request \u003cbr\u003e• Comprehensive test coverage\u003cbr\u003e• Code quality with golangci-lint | ✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅\u003cbr\u003e✅ |\n| Payment Gateways | • Idempotent payment processing\u003cbr\u003e• Stripe integration\u003cbr\u003e• PayPal integration\u003cbr\u003e• Webhook handling for asynchronous events | 🔄\u003cbr\u003e🔄\u003cbr\u003e🔄\u003cbr\u003e🔄 |\n| Deployment \u0026 Monitoring | • Multi-stage Docker builds for minimal image size \u003cbr\u003e• GitHub Actions CI pipeline\u003cbr\u003e• AWS RDS with PostgreSQL\u003cbr\u003e• ECS Fargate for serverless container deployment\u003cbr\u003e• Prometheus metrics and Grafana dashboards | ✅\u003cbr\u003e✅\u003cbr\u003e🔄\u003cbr\u003e🔄\u003cbr\u003e🔄 |\n\n\u003ca href=\"#top\"\u003eBack to Top\u003c/a\u003e\n\n## Architecture and Request Flow:\n\nThe project follows domain-driven design, loosely coupled clean architecture, suited for large codebase.\n\n```\n\n┌─────────┐    JSON    ┌───────────────┐   Domain   ┌─────────────┐\n│ Client  ├───────────►│   Handlers    ├───────────►│ Repositories│\n└─────────┘    (DTO)   └───────────────┘   Models   └─────────────┘\n                              │                           │\n                              │                           │\n                              │          Domain           │\n                              │          Models           │\n                              │                           │\n┌─────────┐    JSON    ┌───────────────┐   Domain   ┌─────────────┐\n│ Client   ◄───────────┤   Handlers     ◄───────────┤Repositories │\n└─────────┘    (DTO)   └───────────────┘   Models   └─────────────┘\n\n```\nExample: Create a wallet\n\nwallet.go (model) -\u003e wallet_repository.go -\u003e wallet_handlers.go (using DTOs)\n\n1. Domain Models: `internal/domain/*.go`\n2. Repositories: `internal/domain/*_repository.go`\n3. HTTP Handlers: `internal/server/handlers/*.go`\n4. DTOs: `internal/server/dto/*.go`\n5. Routes: `internal/server/routes/*.go`\n\n\u003ca href=\"#top\"\u003eBack to Top\u003c/a\u003e\n\n## Directory Structure\n\ncommand: `tree -a -I '.git|.DS_Store|.gitignore|.idea|.vscode|docs'`\n\n```bash\n├── .github\n│   └── workflows\n│       └── test.yaml                 # CI/CD pipeline for running tests\n├── internal\n│   ├── domain\n│   │   ├── card.go                   # Card domain model\n│   │   ├── card_repository.go        # Card repository interface, database interactions\n│   │   ├── helpers.go                # Domain-specific helper functions\n│   │   ├── user.go                   # User domain model\n│   │   ├── user_repository.go        # User repository interface, database interactions\n│   │   ├── wallet.go                 # Wallet domain model\n│   │   └── wallet_repository.go      # Wallet repository interface, database interactions\n│   ├── secure\n│   │   ├── card_aes.go               # Card AES-256 with GCM mode, Validate, Encrypt and Decrypt\n│   │   ├── jwt.go                    # JWT token handling, generate and validate tokens\n│   │   ├── password.go               # Password hashing and verification with bcrypt\n│   │   └── password_test.go          # Password utility tests\n│   │   ├── rbac\n│   │   │   ├── policy.json          # RBAC policies for the API\n│   │   │   ├── policy.go            # Loading policy from policy.json\n│   │   │   ├── rbac.go              # Core logic of RBAC\n│   │   │   └── rbac_test.go         # Unit tests\n│   ├── server\n│   │   ├── handlers\n│   │   │   ├── auth.go               # Login, Register handlers\n│   │   │   ├── card.go               # Card http handlers\n│   │   │   ├── helpers.go            # Handlers helper functions\n│   │   │   ├── user.go               # User HTTP handlers\n│   │   │   └── wallet.go             # Wallet HTTP handlers\n│   │   ├── middlewares\n│   │   │   ├── auth.go               # Auth middleware (Validate token, Set Authorized user in req context)\n│   │   │   ├── cors.go               # CORS middleware\n│   │   │   ├── gin_logger.go         # Custom Logging middleware for gin\n│   │   │   ├── middlewares.go        # Core Middleware setup\n│   │   │   ├── rate_limiter.go       # IP-Based rate limiter with token bucket algorithm\n│   │   │   └── request_id.go         # Request ID middleware, sets X-Request-ID header\n│   │   ├── routes\n│   │   │   ├── auth.go               # Authentication routes\n│   │   │   ├── card.go               # Card routes\n│   │   │   ├── routes.go             # Core routes setup\n│   │   │   ├── user.go               # User  routes\n│   │   │   └── wallet.go             # Wallet routes\n│   │   ├── dto\n│   │   │   ├── auth.go               # Authentication-related DTOs/REST API Request Response Structurers\n│   │   │   ├── card.go               # Card dto\n│   │   │   ├── shared.go             # Shared dto\n│   │   │   ├── user.go               # User  dto\n│   │   │   └── wallet.go             # Wallet routes\n│   │   └── server.go                 # HTTP server setup with gin\n│   ├── infra\n│   │   ├── postgres\n│   │   │   ├── postgres_connection.go    # Postgres connection setup with pgx, returns *sql.DB\n│   │   │   └── postgres_migrations.go    # Database migration handling with golang-migrate/v4\n│   │   ├── kafka\n│   │   │   └── sample.md                 # Placeholder for Kafka integration\n│   ├── common\n│   │   ├── app_errs.go               # Custom error types\n│   │   ├── config.go                 # Configuration management\n│   │   ├── constants.go              # Global constants\n│   │   ├── context_keys.go           # Context key definitions\n│   │   ├── custom_err_messages.go    # Error message definitions\n│   │   ├── slog_config.go            # Structured logging configuration\n│   │   └── timeouts.go               # Context timeout constants\n├── migrations\n│   ├── 000001_create_users_table.down.sql   # User table rollback\n│   ├── 000001_create_users_table.up.sql     # User table creation\n│   ├── 000002_create_wallets_table.down.sql # Wallet table rollback\n│   └── 000002_create_wallets_table.up.sql   # Wallet table creation\n│   ├── 000003_create_cards_table.down.sql   # Cards table rollback\n│   └── 000003_create_cards_table.up.sql     # Cards table creation\n├── scripts/\n│   ├── pre-push                      # Git pre-push hook (runs tests and lint before every push)\n│   ├── setup-dev-env.sh              # Script to set up development environment\n│   └── setup-prod-env.sh             # Script to set up production environment\n├── env-configs/\n│   ├── dev.Makefile                  # Makefile for development environment\n│   ├── prod.Makefile                 # Makefile for production environment\n│   ├── compose.dev.yaml              # Docker Compose file for development\n│   ├── compose.prod.yaml             # Docker Compose file for production\n│   └── config.example.yaml           # Example configuration file\n├── config.yaml                       # Application configuration\n├── main.go                           # Application entry point\n├── Makefile                          # Development commands and shortcuts\n├── Dockerfile                        # Docker file with multi stage builds\n├── .dockerignore                     # Directories to ignore in the Docker builds\n├── README.md                         # Project documentation\n├── compose.yaml                      # Docker Compose configuration\n├── go.mod                            # Go module definition\n├── go.sum                            # Go module checksums\n└── .air.toml                         # Live reload configuration with air\n```\n\n\u003ca href=\"#top\"\u003eBack to Top\u003c/a\u003e\n\n## API Documentation\n\n### Authentication Endpoints\n\n#### Register User\n- **URL**: `/api/v1/register`\n- **Method**: `POST`\n- **Description**: Registers a new user with hashed password, generates JWT tokens, sets an HTTP-only cookie and X-Request-Id header.\n- **Access**: Public\n- **Request Body**:\n  ```json\n  {\n    \"fullName\": \"John Doe\",\n    \"email\": \"someone@example.com\",\n    \"password\": \"samplepass\"\n  }\n  ```\n- **Success Response**: `201 Created`\n- **Error Responses**: `400 Bad Request`, `409 Conflict`, `500 Internal Server Error`\n\n#### Login\n- **URL**: `/api/v1/login`\n- **Method**: `POST`\n- **Description**: Authenticate a user, verifies password, generates JWT token, sets an HTTP-only cookie and X-Request-Id header.\n- **Access**: Public\n- **Request Body**:\n  ```json\n  {\n    \"email\": \"someone@example.com\",\n    \"password\": \"samplepass\"\n  }\n  ```\n- **Success Response**: `200 OK`\n- **Error Responses**: `400 Bad Request`, `401 Unauthorized`, `404 Not Found`, `500 Internal Server Error`\n\n### User Management Endpoints\n\n#### Create User with Specific Role\n- **URL**: `/api/v1/users`\n- **Method**: `POST`\n- **Description**: Creates a new user with a specific role.\n- **Access**: Admin (can create any role), Agent (can create user or merchant roles)\n- **Authentication**: Required (Bearer Token)\n- **Request Body**:\n  ```json\n  {\n    \"fullName\": \"Keanu Reeves\",\n    \"email\": \"keanu@example.com\",\n    \"password\": \"keanupass\",\n    \"role\": \"admin\"\n  }\n  ```\n- **Success Response**: `201 Created`\n- **Error Responses**: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `409 Conflict`, `500 Internal Server Error`\n\n### Wallet Endpoints\n\n#### Create a New Wallet\n- **URL**: `/api/v1/users/{user_uuid}/wallets`\n- **Method**: `POST`\n- **Access**: Admin, Merchant, User\n- **Authentication**: Required (Bearer Token)\n- **Request Body**:\n  ```json\n  {\n    \"currency\": \"USD\"\n  }\n  ```\n- **Success Response**: `201 Created`\n- **Error Responses**: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `409 Conflict`, `500 Internal Server Error`\n\n#### Get Wallet Balance\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/balance`\n- **Method**: `GET`\n- **Access**: Admin, Agent, Merchant, User (own wallet only)\n- **Authentication**: Required (Bearer Token)\n- **Success Response**: `200 OK`\n- **Error Responses**: `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `500 Internal Server Error`\n\n#### Update Wallet Status\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/status`\n- **Method**: `PATCH`\n- **Access**: Admin, Agent, Merchant, User (own wallet only)\n- **Authentication**: Required (Bearer Token)\n- **Request Body**:\n  ```json\n  {\n    \"status\": \"inactive\"\n  }\n  ```\n- **Success Response**: `200 OK`\n- **Error Responses**: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `500 Internal Server Error`\n\n### Card Endpoints\n\n#### Add a New Card to Wallet\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards`\n- **Method**: `POST`\n- **Access**: Admin, Merchant, User (own wallet only)\n- **Authentication**: Required (Bearer Token)\n- **Request Body**:\n  ```json\n  {\n    \"cardNumber\": \"4111111111111111\",\n    \"provider\": \"visa\",\n    \"type\": \"credit\",\n    \"expiryDate\": \"12/25\",\n    \"cvv\": \"123\"\n  }\n  ```\n- **Success Response**: `201 Created`\n- **Error Responses**: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `409 Conflict`, `500 Internal Server Error`\n\n#### Get Card Details\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards/{card_uuid}`\n- **Method**: `GET`\n- **Access**: Admin, Agent (read-only), Merchant, User (own cards only)\n- **Authentication**: Required (Bearer Token)\n- **Success Response**: `200 OK`\n- **Error Responses**: `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `500 Internal Server Error`\n\n#### Update Card Details\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards/{card_uuid}`\n- **Method**: `PATCH`\n- **Access**: Admin, Merchant, User (own cards only)\n- **Authentication**: Required (Bearer Token)\n- **Request Body**:\n  ```json\n  {\n    \"expiryDate\": \"12/26\",\n    \"status\": \"inactive\"\n  }\n  ```\n- **Success Response**: `200 OK`\n- **Error Responses**: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `500 Internal Server Error`\n\n#### Delete Card\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards/{card_uuid}`\n- **Method**: `DELETE`\n- **Access**: Admin, Merchant, User (own cards only)\n- **Authentication**: Required (Bearer Token)\n- **Success Response**: `200 OK`\n- **Error Responses**: `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `500 Internal Server Error`\n\n#### List Cards\n- **URL**: `/api/v1/users/{user_uuid}/wallets/{wallet_uuid}/cards`\n- **Method**: `GET`\n- **Access**: Admin, Agent (read-only), Merchant, User (own wallet only)\n- **Authentication**: Required (Bearer Token)\n- **Query Parameters**:\n  - `provider` (optional): Filter by card provider\n  - `status` (optional): Filter by card status\n- **Success Response**: `200 OK`\n- **Error Responses**: `401 Unauthorized`, `403 Forbidden`, `500 Internal Server Error`\n\n[Back to Top](#top)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashtishad%2Fxpay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashtishad%2Fxpay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashtishad%2Fxpay/lists"}