A unified, normalized REST API for payments and email — one interface, any provider.
Developers lose hours integrating payment and email APIs because every provider has different authentication schemes, request formats, error structures, and webhook payloads. OpenAdapter solves this with a single abstraction layer:
Your app → POST /payments/charge → OpenAdapter → Stripe / PayPal
Your app → POST /email/send → OpenAdapter → SendGrid / Postmark
Switch providers by changing one environment variable.
Prerequisites: Python 3.12, Docker
git clone https://github.com/your-org/openadapter.git
cd openadapter
# Set up Python environment
python3.12 -m venv .venv
source .venv/bin/activate
pip install -e packages/adapter_core
pip install -r apps/api/requirements-dev.txt
# Configure secrets
cp .env.example .env
# Edit .env with your API keys
# Run
cd apps/api
uvicorn app.main:app --reload --port 8000Open http://localhost:8000/docs
# Build and run
docker-compose up --build
# Or pull the published image
docker run -p 8000:8000 \
-e STRIPE_API_KEY=sk_test_... \
-e SENDGRID_API_KEY=SG.... \
youruser/open-adapter:latestCharge a card (Stripe)
curl -X POST http://localhost:8000/payments/charge \
-H "Content-Type: application/json" \
-d '{
"provider": "stripe",
"amount": 2500,
"currency": "USD",
"customer_email": "user@example.com",
"source_token": "tok_visa"
}'Send an email (SendGrid)
curl -X POST http://localhost:8000/email/send \
-H "Content-Type: application/json" \
-d '{
"provider": "sendgrid",
"to": ["user@example.com"],
"from": "team@openadapter.dev",
"subject": "Welcome",
"text": "Hello from OpenAdapter"
}'Health check
curl http://localhost:8000/health
# {"status":"healthy","version":"1.0.0","environment":"production"}# All tests with coverage
pytest apps/api/tests/
# Unit tests only
pytest apps/api/tests/unit/ -v
# Integration tests only
pytest apps/api/tests/integration/ -vopenadapter/
├── apps/api/ FastAPI application (routes, services, schemas)
├── packages/
│ └── adapter_core/ Provider abstraction layer (models, interfaces, adapters)
├── infra/terraform/ AWS infrastructure as code
├── .github/workflows/ CI (ci.yml) and CD (cd.yml) pipelines
└── docs/ Architecture, API contract, deployment guide
See docs/architecture.md for a detailed breakdown.
CI runs on every pull request:
- Lint (
ruff), format check, type-check (mypy) - Unit + integration tests
- Docker image build
CD runs on merge to main:
- Builds and pushes Docker image to Docker Hub (tagged with commit SHA +
latest) - Runs
terraform applyto provision/update EC2 - Polls
/healthuntil the deployment is live
No manual AWS console login is required during deployment. See docs/deployment.md.
After one-time secret configuration in GitHub Actions, every merge to main automatically:
- Publishes a Docker image
- Provisions or updates an EC2 instance via Terraform
- Deploys the new container
- Verifies the health check
The live API URL is printed as a Terraform output (api_url).
All provider errors are normalized:
{
"detail": {
"code": "rate_limit",
"message": "Provider rate limit exceeded",
"provider": "stripe",
"retryable": true,
"raw": {}
}
}See CONTRIBUTING.md for setup, branch naming, testing, and adding new providers.