Inspiration
Every campus fest starts the same way: a spreadsheet, a group chat, and a budget that only exists in someone's head. The lineup is the fun part. The deposits are where it breaks - a headliner's advance, a venue hold, a food truck's retainer, all due at different times and all competing for the same money.
FestOS began as a taste-aware planner: three signals in, a complete run of show out, with every pick traced to the Qloo taste graph. The PayPal AI Hackathon asked the next question - what does agentic commerce look like after the plan? So we built the missing half: a settlement agent that turns a finished lineup into vendor deposit obligations and settles them through PayPal, with policy, a cap, and a human in the loop.
What it does
FestOS has two agents and one shared state.
Planning agent. It takes a campus vibe, a budget and a date, resolves taste through Qloo Insights, scores audience affinity, and solves budget, genre mix and vendor spread into a lineup: headliner, support, opener, screening and food row. Every slot carries a reason and a Qloo trace.
Settlement agent. With one click it converts the lineup into vendor deposit obligations. A deterministic policy funds them in strict priority - headliner, screening/venue, support, opener, food - until the deposit cap is reached. The first slot that does not fit stops the run; everything below it is explicitly deferred, never silently skipped. The user reviews and approves. Then each funded obligation becomes a PayPal Orders v2 order (USD, 30% default deposit, fixed labelled FX), the vendor is paid through PayPal's approval page, and the server captures the order. The result is a ledger with order ids, capture ids, statuses and a funded/deferred split that can be audited line by line.
How we built it
- Frontend: React 19, TypeScript, Vite. The settlement panel, obligation cards and ledger live beside the plan, not behind a settings page.
- API: Node.js 20, Express.
/settlement/draftruns the policy engine;/settlement/orderscreates orders;/settlement/capturecaptures them. - PayPal: Orders v2 REST. OAuth 2 client-credentials token,
POST /v2/checkout/orderswithintent: CAPTURE, USD purchase units, return/cancel URLs andPayPal-Request-Idfor idempotency;POST /v2/checkout/orders/{id}/capturefor server-side capture. The base URL is sandbox-only - there is no live-money code path. - Taste: Qloo Insights API for entity resolution and audience affinity.
- State: settlement runs persist in
localStorageso a redirect to PayPal and back does not lose the run; the return URL auto-captures the approved order. - Tests: six automated tests, including a mocked-fetch contract test that asserts the exact OAuth, create-order and capture payloads, plus policy tests for cap behaviour and simulator end-to-end runs.
Challenges we faced
- PayPal does not settle INR. Rather than hide it, we used a fixed, labelled FX rate (INR 83.50 = USD 1.00) and showed it in the UI and README. Judges should never have to guess what a number means.
- Money is a different class of tool. Letting an LLM decide what to pay, and in what order, is not acceptable. The policy engine is deterministic; the agent can explain a decision but cannot override the cap or the priority order. The human approval step is a product requirement, not a formality.
- Stateless redirects. A PayPal redirect leaves the app. Persisting the run and rehydrating it on return was the difference between a demo and a working flow.
- Testing without credentials. We did not want "trust me" as a test strategy. Mocked-fetch contract tests pin the request shape, and a simulator runs the identical lifecycle with clearly labelled
SIM-ids when keys are absent.
Accomplishments we're proud of
- A full lifecycle that works: plan to obligations to prioritized funding to PayPal orders to approval to capture to an auditable ledger.
- A policy that is strict, explainable and visibly stress-testable: move the cap and the deferral line moves with it.
- Honest failure modes: the app says "simulator" when it is simulating, and labels the FX assumption.
- A public, Apache-2.0 repo with the demo and setup instructions.
What we learned
Agentic commerce is not "the agent can call a payment API." It is everything around that call: a budget the agent cannot exceed, a priority order a human can inspect, idempotency so a retry never double-pays, and a ledger so every cent can be traced back to a decision. The payment call is the easy part.
What's next
- Real sandbox credentials on the hosted demo, then a vendor onboarding flow.
- Partial refunds and deposit terms per vendor through PayPal.
- Multi-currency settlement.
- A treasury agent that negotiates deposit terms, still bounded by the same policy engine.
Try it out
- Live demo: https://festos-abhinav-shukla1.vercel.app/
- Source: https://github.com/abhinavshukla152005-beep/festos (Apache 2.0)
- Demo video: https://youtu.be/p7VO8B5sOro
Demo note: the hosted app runs the PayPal lifecycle in a clearly labelled simulator because sandbox API keys are not set on that host. Set PAYPAL_CLIENT_ID and PAYPAL_CLIENT_SECRET and the same flow calls PayPal Orders v2 in sandbox. The demo video shows the simulator path and the labels that make it explicit.
Built With
- agentic-commerce
- ai-agents
- css3
- express.js
- html5
- javascript
- node.js
- paypal
- paypal-orders-api
- qloo
- qloo-insights-api
- react
- rest-api
- typescript
- vercel
- vite
Log in or sign up for Devpost to join the conversation.