9.3 KiB
9.3 KiB
Auburn Oil Customer Gateway - API
A modern, high-performance REST API powering the Auburn Oil customer self-service portal. Built with FastAPI and designed for reliability, security, and ease of deployment.
___ __ ____ _ __
/ | __ __/ /_ __ ___________ / __ \(_) /
/ /| |/ / / / __ \/ / / / ___/ __ \ / / / / / /
/ ___ / /_/ / /_/ / /_/ / / / / / / / /_/ / / /
/_/ |_\__,_/_.___/\__,_/_/ /_/ /_/ \____/_/_/
Customer Gateway API
What This Does
This API serves as the backbone for Auburn Oil's customer portal, enabling:
| Feature | Description |
|---|---|
| Customer Onboarding | Multi-step registration for new customers with tank photo uploads |
| Order Management | Place heating oil delivery orders with real-time pricing |
| Payment Processing | Secure credit card handling via Authorize.net (PCI-compliant) |
| Account Management | Password reset, profile updates, delivery history |
| Tank Inspections | Upload and manage annual tank inspection photos |
Tech Stack
- Framework: FastAPI 0.104 (async Python)
- Database: PostgreSQL with SQLAlchemy 2.0 (async)
- Authentication: JWT tokens with bcrypt password hashing
- Payments: Authorize.net CIM (tokenized card storage)
- Server: Uvicorn ASGI
Quick Start
Prerequisites
- Docker & Docker Compose
- PostgreSQL database (can be remote)
- Authorize.net merchant account (sandbox for development)
1. Configure Environment
Copy the example environment file and customize:
cp .env.example .env.dev
Edit .env.dev with your settings:
# Database
POSTGRES_SERVER=your-db-host
POSTGRES_PORT=5432
POSTGRES_DBNAME=auburnoil
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=your-secure-password
# Security (generate a strong key!)
JWT_SECRET_KEY=your-256-bit-secret-key
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=1440
# Payments (use sandbox credentials for dev)
AUTH_NET_API_LOGIN_ID=your-login-id
AUTH_NET_TRANSACTION_KEY=your-transaction-key
# Email (for password resets)
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM_EMAIL=noreply@yourdomain.com
# Frontend URL (for password reset links)
FRONTEND_URL=http://localhost:3000
2. Deploy with Docker
Development (with hot-reload):
cd deploy
docker compose -f docker-compose.dev.yml up --build
Local Network Testing:
cd deploy
docker compose -f docker-compose.local.yml up --build
Production:
cd deploy
docker compose -f docker-compose.prod.yml up -d --build
3. Access the API
| Environment | API URL | Docs |
|---|---|---|
| Development | http://localhost:8000 | http://localhost:8000/docs |
| Production | https://api.portal.auburnoil.com | https://api.portal.auburnoil.com/docs |
API Endpoints
Authentication (/auth)
| Method | Endpoint | Description |
|---|---|---|
POST |
/auth/login |
Login with email/password, returns JWT |
POST |
/auth/register |
Register existing customer (requires account #) |
POST |
/auth/new |
New customer single-step registration |
POST |
/auth/step1 |
New customer wizard - Step 1 (info) |
POST |
/auth/step2 |
New customer wizard - Step 2 (credentials) |
POST |
/auth/step3 |
New customer wizard - Step 3 (tank photos) |
GET |
/auth/me |
Get current user profile |
POST |
/auth/forgot-password |
Request password reset email |
POST |
/auth/reset-password |
Complete password reset |
POST |
/auth/change-password |
Change password (authenticated) |
POST |
/auth/upload-tank-images |
Upload tank inspection photos |
GET |
/auth/tank-images/{account} |
Get tank image history |
Orders (/order)
| Method | Endpoint | Description |
|---|---|---|
POST |
/order/ |
Place new delivery order (min 100 gallons) |
Customer Info (/info)
| Method | Endpoint | Description |
|---|---|---|
GET |
/info/deliveries |
Get delivery history (last 20) |
GET |
/info/pricing/current |
Get current oil price per gallon |
Payments (/payment)
| Method | Endpoint | Description |
|---|---|---|
POST |
/payment/process |
Process payment (saved or new card) |
GET |
/payment/cards |
List saved payment methods |
POST |
/payment/cards |
Save new card (tokenize) |
PUT |
/payment/cards/{id} |
Update card details |
DELETE |
/payment/cards/{id} |
Remove saved card |
POST |
/payment/cards/{id}/set-default |
Set default payment method |
POST |
/payment/sync-billing-info |
Sync billing to Authorize.net |
Database Setup
Run Migrations
Apply database migrations in order:
# Connect to your PostgreSQL database
psql -h your-host -U postgres -d auburnoil
# Run migrations
\i migrations/20240108_create_portal_user_table.sql
\i migrations/20240108_add_tank_image_upload_dates.sql
Key Tables
| Table | Purpose |
|---|---|
customer_customer |
Customer profiles and addresses |
portal_user |
Portal login credentials |
delivery_delivery |
Delivery orders and history |
card_card |
Saved payment methods (tokenized) |
transactions |
Payment transaction records |
customer_tank |
Tank inspection metadata |
pricing_oil_oil |
Daily oil pricing |
Project Structure
api/
├── main.py # FastAPI app entry point
├── config.py # Environment configuration
├── database.py # Database connection (async)
├── models.py # SQLAlchemy ORM models
├── schemas.py # Pydantic request/response schemas
├── routers/
│ ├── auth.py # Authentication endpoints
│ ├── info.py # Customer info endpoints
│ ├── order.py # Order management
│ └── payment.py # Payment processing
├── services/
│ └── authorizenet.py # Authorize.net integration
├── .env.example # Environment template
├── .env.dev # Development config
├── .env.local # Local network config
├── .env.prod # Production config
├── Dockerfile.dev # Development container
├── Dockerfile.local # Local network container
├── Dockerfile.prod # Production container
└── requirements.txt # Python dependencies
Security Features
- JWT Authentication: Stateless token-based auth with configurable expiration
- Password Hashing: bcrypt with automatic truncation for compatibility
- PCI Compliance: Card data never stored locally (Authorize.net tokenization)
- Image Sanitization: Uploaded images resized, metadata stripped
- CORS Protection: Environment-specific allowed origins
- Input Validation: Pydantic schemas validate all inputs
Environment Variables Reference
| Variable | Required | Description |
|---|---|---|
MODE |
Yes | DEVELOPMENT, LOCAL, or PRODUCTION |
POSTGRES_SERVER |
Yes | Database host |
POSTGRES_PORT |
Yes | Database port (usually 5432) |
POSTGRES_DBNAME |
Yes | Database name |
POSTGRES_USERNAME |
Yes | Database user |
POSTGRES_PASSWORD |
Yes | Database password |
JWT_SECRET_KEY |
Yes | Secret for signing tokens (use 256+ bits) |
JWT_ALGORITHM |
Yes | Algorithm (HS256 recommended) |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES |
Yes | Token lifetime in minutes |
AUTH_NET_API_LOGIN_ID |
Yes | Authorize.net API Login ID |
AUTH_NET_TRANSACTION_KEY |
Yes | Authorize.net Transaction Key |
SMTP_SERVER |
Yes | SMTP server for emails |
SMTP_PORT |
Yes | SMTP port (587 for TLS) |
SMTP_USERNAME |
Yes | SMTP username |
SMTP_PASSWORD |
Yes | SMTP password/app password |
SMTP_FROM_EMAIL |
Yes | From address for emails |
FRONTEND_URL |
Yes | Frontend URL for reset links |
Troubleshooting
Common Issues
Database connection failed
Check POSTGRES_* environment variables
Ensure database is accessible from Docker network
Verify firewall allows connections on port 5432
JWT token invalid
Ensure JWT_SECRET_KEY is the same across restarts
Check token hasn't expired
Verify JWT_ALGORITHM matches what was used to sign
Authorize.net errors
Sandbox vs Production: Use correct credentials for each
Test cards: Use Authorize.net test card numbers in sandbox
Check API Login ID and Transaction Key are correct
Image upload fails
Max file size: 20MB per image
Supported formats: JPEG, PNG
Check /images volume is mounted correctly
Development
Running Locally (without Docker)
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set environment variables
export MODE=DEVELOPMENT
# ... set other variables
# Run with hot-reload
uvicorn main:app --reload --host 0.0.0.0 --port 8000
API Documentation
FastAPI auto-generates interactive documentation:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
Auburn Oil Customer Gateway - Built with reliability in mind for New Hampshire and Massachusetts heating oil customers.