Skip to content

Contract‑first Python payments kit with FastAPI routers, gRPC services, SQLAlchemy, and JWT auth, supports transactions, refunds, and settlements.

Notifications You must be signed in to change notification settings

mrzupworkuser/payments-service-kit-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Payments Service Kit — Clean Architecture Reference

A compact, production‑minded payment layer built around explicit contracts (Protobuf/gRPC), thin HTTP adapters (FastAPI routers), isolated provider integrations, and a disciplined SQLAlchemy persistence tier.

Core principles

  • Contract‑driven design: Protobuf specs define the surface; routers and clients conform to it.
  • Separation of concerns: transport, authN/Z, provider logic, and data access live in distinct modules.
  • Strong, explicit types: Pydantic, Marshmallow SQLAlchemy, and Enums reduce invalid states.
  • Fail‑safe posture: defensive parsing and sanitized error propagation by default.

Architecture overview

Clients → FastAPI Routers (routers/*) → gRPC Stubs (proto.*_pb2_grpc) → Backing Services
                                     ↙                                  ↘
                            SQLAlchemy Persistence (sql/*)      Provider Adapters (actions/*)

Authorization (voter/*) and Utilities (helper/*) cross-cut at the edges

Strength signals in this codebase

  • Typed boundaries and validation
    • Pydantic request models and Marshmallow SQLAlchemy schemas for ORM serialization.
    • t.Literal and Enum usage constrain inputs (e.g., payment method, order direction).
  • Provider isolation
    • actions/authnet.py wraps Authorize.Net SDK with small, testable methods and env‑scoped config (TEST/LIVE).
  • AuthN/Z done right
    • JWTBearer guards HTTP routes; voter (voter/transaction.py) enforces ownership checks.
  • Error hygiene and response shaping
    • gRPC RpcError → FastAPI HTTPException with scrubbed messages; MessageToDict + case conversion utilities ensure consistent payloads.
  • Data layer discipline
    • Engine config with pool_pre_ping, small pool, READ COMMITTED isolation, and scoped_session for thread safety.
    • CRUD with safe dynamic ordering, pagination, cross‑table filtering, and date windowing.
  • 12‑factor configuration
    • python‑decouple pulls DB and provider settings from environment variables.

Key modules (evidence → capability)

  • routers/transactions.py, routers/user.py → Thin HTTP adapters; typed params; JWT integration; gRPC orchestration.
  • actions/authnet.py → Encapsulated Authorize.Net flows (CreateCustomerProfile, ChargeCreditCard, etc.).
  • voter/transaction.py → Isolated authorization policy (add/edit/view) using logged‑in user context.
  • sql/database.py → Engine/session setup with pooling, pre‑ping, isolation level, scoped sessions.
  • sql/crud/transactions.py → Query composition: filters, sorting, pagination, joins (user, invoice).
  • sql/models/users.py, sql/schemas/user/user.py → ORM entity and corresponding schema set.
  • enumerations/user_payment_methods.py → Enum source of truth for payment types and status lifecycle.
  • proto/transactions/transactions.proto → Contract for transactions, settlements, refunds, and listing API.

Notable implementation details

  • Defensive parsing: guarded ast.literal_eval for stringified detail values in transaction payloads.
  • Consistent case conversion: camelCase ↔ snake_case bridging at the API boundary.
  • Pagination metadata and stable ordering exposed from the CRUD layer into list responses.

API quick tour

  • Users: create, read by id, update profile, update password, update timezone.
  • Transactions: checkout, profile payment, read by id, list with filters, read settlement, refund (full/partial), cancel refund, read refund by transaction id.

Configuration (env‑first)

  • Database: DB_ENGINE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_URL, MYSQL_PORT, MYSQL_DB
  • Authorize.Net: AUTH_ENVIRONMENT, AUTH_TEST_*, AUTH_LIVE_*
  • Auth and channels: provided via helper utilities consumed by routers

Extending with a new payment provider

  1. Add enum entry in enumerations/user_payment_methods.py.
  2. Implement an adapter in actions/ mirroring the provider’s SDK with small methods and deterministic returns.
  3. Extend the gRPC backend (per proto/) and consume via the router using the existing stub pattern.

Why this stands out

  • The code makes illegal states hard to represent through strong typing and enums.
  • Boundaries are explicit and enforced by contracts, not convention.
  • Operationally safe defaults in the DB layer and error handling reduce production risk.
  • Clear extension seams enable adding providers or endpoints without cross‑layer churn.

Releases

No releases published

Packages

No packages published

Languages