Programmable Promises

Pay when the work is real. A payer describes what “done” means; PayPal holds funds; a worker submits photo proof; AI checks it against a machine-readable checklist; pass triggers capture and payout, fail explains why with human review when the outcome is unclear.

Demo application using PayPal authorize → capture → Payouts. Not escrow or legal advice.


Inspiration

Freelance and gig work often breaks down at the same moment: “Did they actually do what I paid for?” Escrow products exist, but they rarely encode your definition of done in a way software can enforce. Vision models can read photos well enough to check simple, explicit criteria and PayPal already knows how to authorize, capture, and pay out.

We wanted a story you could feel in three minutes: write a promise, fund it with PayPal Buttons, watch a worker upload proof, and see money move only when the rules say so not when the model “feels” confident. Programmable Promises treats payment logic as data (checklist + thresholds + state machine), not as ad-hoc chat.

We extended that with AG Studio for operational visibility and MCP so agents can create and track promises while funding still goes through PayPal’s UI so a person approves the hold.


What we built

Actor Experience
Payer Create promise → AI drafts checklist → edit & confirm → authorize hold via PayPal → monitor status, review edge cases, AG Studio dashboard
Worker One-time link → challenge code → upload JPG/PNG → live verification progress
Agent (optional) Cursor + custom pp_* MCP tools + PayPal MCP; human completes PayPal Buttons for funding

End-to-end flow

  1. Create promise (amount, deadline, natural-language condition).
  2. Confirm checklist (required items, weights, pass threshold).
  3. Fund → Money held (PayPal authorization).
  4. Worker submits proof with challenge code visible in the image.
  5. Pass → capture + payout to worker email. Clear fail → hold kept, reasons shown. Third fail / low confidence / verifier error → Review (approve pays, deny releases hold).
  6. Past deadline → authorization voided.

Also in the repo: paginated promise list, SSE + polling on worker/payer views, optional Kafka workers for async verify and webhooks, LLM proxy for AG Studio’s agent panel, Docker Compose for local full stack.


How we built it

Architecture

TypeScript monorepo:

  • packages/shared state machine, shared decision rules, unit tests.
  • apps/api Express, PostgreSQL, Redis, PayPal client, verifier abstraction, analytics for AG Studio, studio LLM proxy.
  • apps/web Angular: create, fund, worker upload, detail/review, lazy-loaded AG Studio dashboard.
  • apps/mcp stdio MCP server over the REST API (pp_login, pp_create_promise, pp_submit_proof, …).
  • worker Kafka consumers for verification, webhooks, and payment commands (optional; sync path for simpler deploys).

Hosted demo: Angular on Vercel, API on Render, managed Postgres + Redis. The production UI calls the API directly (CORS); worker links use the live site origin.

Browser (Vercel) ──► Express API (Render) ──► Postgres / Redis
                           ├──► PayPal (authorize, capture, payouts)
                           ├──► OpenAI / Gemini (vision + checklist)
                           └──► Kafka + worker (optional)
Agents ──► MCP ──► API

PayPal

OAuth token caching, Orders with authorize intent, capture after proof, Payouts to worker email. PayPal Buttons in the UI with server-side confirm on approve. Idempotent writes, payout batch reuse on retry, background polling so long-running payout status does not depend on a single HTTP request (important on serverless/time-limited hosts).

AI + rules (the model never touches money)

  1. Checklist generation from the payer’s description (editable before confirm).
  2. Proof verification multimodal model returns per-item scores; a deterministic rules engine decides pass / fail / review.

Logged model output is for debugging; it is not the payment decision.

  • Every required item must pass with confidence (\geq \tau_{\mathrm{item}}) (default (0.7)).
  • Weighted score (\displaystyle\frac{\sum_i w_i \cdot s_i}{\sum_i w_i} \geq \tau_{\mathrm{global}}) (default (0.8)).
  • Challenge code in the image must match.

Ambiguous results → human review, not auto-pay.

AG Studio & MCP

/dashboard KPIs, status charts, promise pipeline and verification evidence from GET /api/analytics/studio-data; Studio agent via POST /api/studio/llm-turn (keys on server). PayPal MCP plus our @pp/mcp server for agent-driven create/track/submit.


What we learned

  1. Separate AI opinion from payment action a thin rules layer on vision output made behavior trustworthy and debuggable.
  2. PayPal is asynchronous payouts can stay pending; UX, retries, and background reconciliation matter as much as the happy path.
  3. Split hosting is normal static UI + long-lived API; explicit API base URL and CORS beat fragile reverse-proxy-only setups on preview URLs.
  4. Agents need guardrails MCP accelerates workflows; PayPal checkout stays human-in-the-loop for authorization.
  5. Partner SDKs are real work AG Studio + Angular versioning, lazy routes, and LLM proxy shapes were a major slice of the build.
  6. Live feedback sells the demo SSE and polling on the worker page made verification feel real, not batch-only.

Challenges we faced

Challenge What happened What we did
Duplicate proof / double pay Retries and races Idempotent payout batches, proof dedup, clear states
Payout stuck “in progress” Long PayPal processing; HTTP timeouts on PaaS Shorter in-request polls + 30s background job; Retry payment; treat unclaimed payouts appropriately in demo
Deploy: UI vs API Vercel rewrites flaky on previews Production apiBaseUrl to Render; CORS on API
Worker links showed localhost APP_BASE_URL vs browser origin Build worker URLs from window.location when payer creates from UI
AG Studio LLM 502 Request shape / model mismatch for Gemini Proxy parsing, provider-aware models, clearer errors
Angular × AG Studio Peer dependency conflicts Pin Angular 19, lazy dashboard, bundle budgets
Grid layout UX Action buttons stretched into circles align-self, flex rows, split-column alignment
Scope Time and complexity Images-only MVP, 48h deadline cap, one crisp video narrative

Tech stack

Angular 19 · Node.js / Express · TypeScript · PostgreSQL · Redis · PayPal REST · OpenAI / Gemini · AG Studio · MCP · Docker · Vercel · Render · optional Kafka (Redpanda)


Try it


Closing

Can PayPal hold the money while AI checks the proof and only then pay? Programmable Promises implements that loop: programmable checklists, rules-based verification, PayPal capture and payout, human review when automation is not enough, AG Studio for visibility, and MCP for agents without letting the model sign the check.

Built With

Share this project:

Updates

Submission history