.gitignore | 3 +++ .trail.yaml | 4 ++++ README.md | 3 +++ app/refunds.py | 9 +++++++++ app/webhooks.py | 9 +++++++++ requirements.txt | 3 +++ 6 files changed, 31 insertions(+) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a1510d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +logs/ +runs/ +reports/ diff --git a/.trail.yaml b/.trail.yaml new file mode 100644 index 0000000..01bc89e --- /dev/null +++ b/.trail.yaml @@ -0,0 +1,4 @@ +store: supabase://trail/main +repo: payments-api +harnesses: [claude, codex] +artifacts: ["logs/", "reports/*.md"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..501ba1d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# payments-api + +Orders, charges and refunds for the Acme store. FastAPI + Postgres + Stripe. diff --git a/app/refunds.py b/app/refunds.py new file mode 100644 index 0000000..b9e9744 --- /dev/null +++ b/app/refunds.py @@ -0,0 +1,9 @@ +from app.db import db +from app.stripe import refund + + +def create_refund(order_id, amount, agent): + order = db.orders.get(order_id) + refund(order.payment_intent, amount) + db.refunds.insert(order_id=order_id, amount=amount, agent=agent) + return {"ok": True} diff --git a/app/webhooks.py b/app/webhooks.py new file mode 100644 index 0000000..09c59d0 --- /dev/null +++ b/app/webhooks.py @@ -0,0 +1,9 @@ +from app.db import db +from app.stripe import capture + + +def handle_payment_succeeded(event): + order = db.orders.get(event["data"]["order_id"]) + capture(order.payment_intent) + order.status = "paid" + db.orders.save(order) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1245164 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +fastapi==0.115.0 +stripe==9.1.0 +psycopg[binary]==3.2.1