Integrations for local Ethiopian payment gateways (Chapa, SantiPay, AddisPay, ...)
# Ethiopian Payment Integration
Enterprise-grade Express 5 boilerplate for Ethiopian PSPs (**Chapa**, **SantiPay**, **AddisPay**) with:
- Modular MVC folders you can lift into any project (each payment provider ships with its own models, controllers, services, validators, repositories, HTTP client).
- Shared JWT authentication/user module (Sequelize + Argon2) with HTTP-only cookies and bearer support.
- Dual persistence layers per payment module: **MySQL (Sequelize)** for structured records and **MongoDB (Mongoose)** for raw payload archives.
- Modern security middleware (Helmet, CORS, compression) and structured logging via Pino.
- Unit tests proving auth and provider service logic.
> **Drop-in modules**: copy `src/modules/payments/ ` into another project and wire it with your own MySQL + Mongo connections and auth guard. No refactoring needed.
## Tech Stack
- Node.js 18+, Express 5 (router-level async/await, fetch-ready).
- Sequelize (MySQL) + Mongoose (MongoDB) running side by side.
- Argon2 password hashing, JWT tokens, Joi validation.
- pnpm for reproducible installs, Jest for unit tests.
## Quick Start
```bash
pnpm install
pnpm approve-builds # one-time approval for native argon2 build
cp .env.example .env # update DB URLs + API keys
pnpm dev
```
By default the server listens on `PORT` (4000) and auto-syncs Sequelize models to the configured MySQL database while connecting to Mongo for payload archiving.
## Environment
Key settings defined in `.env`:
| Variable | Description |
| --- | --- |
| `MYSQL_*` | Standard host/port/database/user/password for Sequelize |
| `MONGO_URI` | MongoDB connection string (raw payload store) |
| `JWT_SECRET`, `JWT_EXPIRES_IN`, `TOKEN_COOKIE_NAME` | Auth token settings |
| `CHAPA_*`, `SANTIPAY_*`, `ADDISPAY_*` | Provider base URLs + API keys |
| `CORS_ORIGIN` | Comma-separated allowlist for CORS |
## Project Layout
```
src/
app.js # Express factory (injects DB connections + modules)
server.js …