A production-ready, payment-gated loan assessment engine built with FastAPI and OpenAI. This project implements a Two-Pass LLM Pipeline and Stripe Payment Gateway with a focus on zero-retention security and financial idempotency.
The system is designed around the Data Firewall pattern. To prevent prompt injection and ensure deterministic outputs, the engine separates data extraction from risk analysis.
-
Stripe Payment Gate
- Users initiate a request.
- The system creates a Stripe
PaymentIntentand waits for a secure webhook confirmation.
-
Pass 1 (The Extractor)
- Once payment is confirmed, the raw application text is sent to the first LLM pass.
- This pass extracts structured signals such as:
- Income
- Debt mentions
- Sentiment
- The extracted data is validated into a strict Pydantic model.
-
Pass 2 (The Analyst)
- The second LLM pass receives only the structured signals.
- It has zero access to the original raw text, physically isolating decision logic from prompt injection attacks.
Custom FastAPI middleware ensures request bodies are never logged.
Only metadata such as:
- IP address
- Request path
is captured to preserve user privacy.
Uses:
- Stripe Idempotency Keys to prevent double charging during retries
- Internal processing tracking to avoid duplicate AI assessments
Implements HMAC-SHA256 signature verification for all Stripe webhook events to prevent spoofing attacks.
An in-memory sliding-window rate limiter protects the API from abuse.
The limiter is applied at the middleware layer before request bodies are read.
Built with Pydantic v2 using:
Decimalfor financial precisionEnumfor risk categoriesfrozenmodels for immutability guarantees
| Category | Technology |
|---|---|
| Framework | FastAPI (Python 3.10+) |
| AI | OpenAI GPT-4o-mini (Structured Outputs) |
| Payments | Stripe API |
| Validation | Pydantic v2 |
| Testing | pytest, pytest-mock |
| Environment | Linux Mint / Ubuntu |
git clone git@github.com:Leli254/ai-risk-engine.git
cd ai-risk-enginepython -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtCreate a .env file:
OPENAI_API_KEY=your_openai_key
STRIPE_SECRET_KEY=your_stripe_key
STRIPE_WEBHOOK_SECRET=your_webhook_secret
PORT=8000
LOG_LEVEL=infoDo not commit your
.envfile to version control.
uvicorn main:app --reloadcurl -X POST http://localhost:8000/payment/create \
-H "Content-Type: application/json" \
-d '{
"application_id": "APP-001",
"email": "test@example.com",
"amount_usd": 5.00
}'stripe listen --forward-to localhost:8000/webhook/stripecurl -X POST http://localhost:8000/assess \
-H "Content-Type: application/json" \
-d '{
"application_id": "APP-001",
"text": "I earn 85,000 USD monthly. Need 500,000 USD loan for business expansion."
}'The project includes a comprehensive test suite using pytest and pytest-mock.
The tests are designed to be offline-first, mocking all external API calls to OpenAI and Stripe so application logic can be validated without:
- Incurring API costs
- Requiring network access
- Depending on third-party service availability
Verifies the complete two-pass extraction and scoring pipeline using structured mocks.
Validates that the @retry (tenacity) logic correctly handles transient API failures such as:
429 Quota Exceeded- Temporary connection failures
- Timeout scenarios
Simulates cryptographically signed Stripe webhook events to ensure:
- Signature verification succeeds
- Internal payment state updates correctly
- Duplicate event handling remains idempotent
Ensure your virtual environment is activated, then run:
# Run all tests with verbose output
pytest -vTo run a focused subset of tests:
# Run only pipeline tests
pytest tests/test_pipeline.py -vThe platform follows a strict security-first architecture:
- Raw applicant text is never exposed to the decision-making model
- Request bodies are not persisted in logs
- Stripe events are cryptographically verified
- Payment and assessment operations are idempotent
- Middleware-level protections mitigate abuse before processing begins
MIT License