Open source · MIT · Built for the PayPal AI Hackathon 2026

Give any existing business a PayPal brain.

paypal-retrofit lets an AI agent wire PayPal into the system a business already runs on: its own database, its own invoice numbers, its own customers. Then it keeps both sides reconciled, and every action that moves money follows a rule the owner set.

No schema changes SQLite, Postgres or CSV Runs offline with a bundled PayPal mock PayPal sandbox ready
Retrofit console · Fernhill Studio demo
Retrofit console: totals for money owed, overdue and collected through PayPal above a ledger of invoices showing each one's status in the legacy system and in PayPal.
1 commandto map an existing schema to PayPal objects
0 changesto the business's tables; write-back only to columns it allows
15 eventsof PayPal webhooks verified and applied
3 rulesauto, confirm or never, for every action an agent proposes
The problem

Most businesses already have a system. It just doesn't talk to PayPal.

A booking tool, an old invoicing app, a spreadsheet, a homegrown ERP. PayPal's Agent Toolkit lets an AI agent call PayPal, but nothing helps an agent connect PayPal to a system that was never built for it. So invoices get re-typed, payments get marked by hand, and the two sets of books drift apart.

Fernhill Studio's legacy invoicing app: a plain table of invoices with many marked overdue, and a note that payments are recorded by hand.
BeforeFernhill Studio's invoicing app40 invoices, 17 overdue, every payment marked paid by hand. The PayPal column is the only thing retrofit adds, and it writes it itself.
The same invoice in the Retrofit console, comparing the legacy record with its PayPal invoice side by side, with buttons to send a reminder, record a payment or cancel.
AfterThe same invoice, connectedEach record shows what the old system believes next to what PayPal believes, with the actions that make sense for it.
Integration takes a week

Someone has to learn the PayPal API and write glue code against a schema they didn't design.

Payments never flow back

Without webhooks wired to the old system, staff reconcile by eye and mark invoices paid manually.

Agents are risky with money

An AI that can call payment APIs directly is one bad prompt away from a refund nobody approved.

How it works

Map, sync, reconcile. The old system stays in charge of its data.

1

Point it at the database you already have

The Mapper agent reads the schema and a few masked sample rows, then proposes how customers, services, invoices, line items and recurring agreements become PayPal objects. Every choice comes with a reason. Nothing touches PayPal until you accept.

  • SQLite, Postgres, or a folder of CSV exports
  • Validated against the real schema; falls back to a deterministic mapper
  • Editable later in the console
$ npx paypal-retrofit init --source sqlite:./fernhill.db
◇  Found 5 tables
  table          rows  foreign keys
  customers        12
  invoice_items    66  service_id→services, invoice_id→invoices
  invoices         40  customer_id→customers
  retainers         4  customer_id→customers
  services          8
◇  Claude is mapping your schema to PayPal objects
  object           from           detail
  Customer         customers      name=full_name, email=email
  Catalog product  services       name=name, price=unit_price
  Invoice          invoices       number=invoice_no, total=total
  Invoice items    invoice_items  via invoice_id
  Status meaning   status         open=[overdue,sent,draft] paid=[paid]
  Send to PayPal   status         when status in [overdue,sent]
  Write back       invoices       paypalId→paypal_invoice_id, …
  Subscription     retainers      monthly_fee/month, when [pending]
?  Use this mapping? Yes
└  Wrote retrofit.config.yaml and retrofit.map.json
2

Send open invoices through PayPal, with your own numbers

sync plans every change, then creates PayPal invoices that keep the business's invoice numbers, emails each customer a pay link, and writes the PayPal id and link back into the columns the mapping allows. Voided invoices are cancelled; invoices paid outside PayPal are recorded so customers aren't asked twice.

  • Idempotent: re-running never duplicates an invoice
  • Pending retainers become PayPal subscriptions
  • Drafts stay where they are
Approvals page listing actions waiting for the owner, such as reminders and a new subscription, each with Approve and Reject buttons.
3

Payments flow back on their own

When a customer pays, PayPal's webhook is checked with PayPal's own signature verification, stored once, and applied to the legacy record (status, paid date and amount) before PayPal is told it arrived. If a webhook is ever lost, the reconciler finds the payment and repairs it, and flags anything that needs a person.

  • Verified with verify-webhook-signature
  • Disputes, refunds and failed renewals become discrepancies
  • Reconciles every 5 minutes, or on demand
Webhook activity log showing PayPal events received, their status and what retrofit did, for example an invoice marked paid in the legacy system.
Architecture

A deterministic engine moves money. Agents propose and explain.

Every PayPal write is an action with an idempotency key, a reason a person can read, and the policy that decided it. The agents only ever see read tools and one write tool: propose_action.

paypal-retrofit architecture The legacy database connects to the retrofit engine, which reads records and writes back allowed columns. The engine talks to PayPal's REST APIs and receives signed webhooks. Three Claude agents sit above the engine and can only propose actions, which pass through a policy gate before the engine executes them. Existing system SQLite · Postgres · CSV customers, invoices, line items, retainers schema never altered paypal-retrofit engine adapters · mapping · sync planner webhook handler · reconciler state store: links, events, actions Policy gate: auto · confirm · never PayPal Invoicing v2 Catalog, Plans, Subscriptions Webhooks, Disputes Transaction search Agent Toolkit (reads) Claude agents Mapper · Ops · Support Console · CLI · REST API read write back REST API webhooks propose_action only read tools PayPal Agent Toolkit, read-only
Idempotent everywhere

PayPal request ids derive from the record and its content hash; one link per legacy record; one application per webhook event.

Never trusts a payload alone

On every invoice event, retrofit re-reads the invoice from PayPal before writing anything back.

Recoverable by design

Webhook failures return 500 so PayPal retries; the reconciler is the backstop for anything still missed.

AI agents

Three agents, one job each.

Built with Claude through the official Anthropic SDK. The default model is claude-opus-5-5.

Integration

Mapper

Turns an unfamiliar schema into a typed PayPal mapping with structured outputs.

  • Reads tables, keys, status values and masked samples
  • Classifies every status as open, paid or cancelled
  • Finds safe columns for write-back, never repurposes data
  • Explains each choice and flags low confidence
Operations

Ops

Works the receivables in plain language, using the SDK tool runner.

  • Ledger search and read-only SQL on the legacy database
  • PayPal reads through PayPal's Agent Toolkit
  • Batches reminders, recorded payments and refunds as proposals
  • Only claims an action happened when the engine says it ran
Who owes us the most?Why is INV-1042 unpaid?Remind everything 14+ days overdue
Support

Support

Drafts a response when a buyer opens a dispute.

  • Combines the PayPal dispute with the legacy invoice and its notes
  • Recommends contest, partial refund or accept
  • Lists available and missing evidence
  • Text only: the owner reviews and submits it
Safety

The owner decides what an agent may do with money.

Every side effect, whether it comes from sync, an agent or a button, is an action decided by a policy. The defaults are conservative and can be changed per action in the console.

ActionDefault policy
Create, send, update invoicesauto
Send remindersconfirm
Record a payment made outside PayPalconfirm
Cancel an invoiceconfirm
Refundconfirm
Create or cancel a subscriptionconfirm
Accept a dispute claimnever
  • Personal data is masked before it reaches a modelEmails, phone digits and street numbers are hidden in schema samples and tool results.
  • Agent SQL is read-onlyA single SELECT on a read-only connection or read-only transaction.
  • Writes only where you allowRetrofit never alters the schema and only fills the write-back columns named in the mapping.
  • Sandbox firstProduction mode is refused unless it is explicitly enabled; secrets live only in the environment and are redacted from logs.
The console

One place to see both sets of books.

Every table is built on AG Grid Community: filters, quick search, bulk selection, custom status cells, CSV export and editable mapping grids. Click any image to enlarge it.

PayPal platform

What it uses from PayPal

AreaUsed for
Invoicing v2Create, get, update, send, remind, cancel, record payment, record refund, search
Payments v2Refunding captured invoice payments
Catalog Products, Billing Plans, SubscriptionsTurning recurring agreements such as retainers into PayPal subscriptions
Webhooks v1Registering the endpoint, signature verification, 15 event types across invoices, captures, subscriptions, sales and disputes
Disputes v1Listing and reading disputes for the Support agent; accepting claims only if the owner allows it
Transaction SearchFees and transaction history for the Ops agent
PayPal Agent ToolkitThe Ops agent's read-only PayPal tools in sandbox and production; writes are deliberately not exposed
Quick start

Try it in two minutes. No accounts needed.

The demo runs Fernhill Studio's legacy app, a local stand-in for the PayPal endpoints and the console in one process.

# Node 20+ with corepack
$ git clone https://github.com/Thinkelution/paypal-retrofit.git
$ cd paypal-retrofit
$ corepack enable && pnpm install && pnpm build
$ pnpm retrofit demo --fresh

paypal-retrofit demo (mock PayPal, no account needed)
  Dashboard     http://localhost:8787/
  Legacy app    http://localhost:8787/fernhill

# your own system, against the PayPal sandbox
$ cp .env.example .env    # PayPal sandbox app + ANTHROPIC_API_KEY
$ pnpm retrofit init --source postgres://…   # or sqlite:… / csv:…
$ pnpm retrofit sync --dry-run
$ pnpm retrofit serve

What to try

  1. Press Send 22 invoices through PayPal.
  2. Open an invoice, press Pay as customer, and pay.
  3. Watch the legacy app's row turn paid.
  4. Approve the new retainer as a subscription.
  5. Simulate a buyer dispute and draft a response.

Turn on the agents

Add ANTHROPIC_API_KEY to .env. Without it, mapping uses the deterministic mapper and the agent panel stays off.

PayPal AI Hackathon 2026

Built for “Build What's Next with PayPal and AI”.

A new, open-source project that makes PayPal integration practical for businesses that already have a system, with AI doing the integration work and a deterministic engine doing the money work.

TypeScriptNode.jsExpressReactAG GridSQLitePostgreSQLPayPal RESTPayPal Agent ToolkitClaudeRender

About the hackathon

  • PayPal at the centre. Invoicing, subscriptions, webhooks, disputes and the Agent Toolkit.
  • AI that does real work. Schema mapping, receivables operations and dispute drafting.
  • A complete product. CLI, console, offline demo, tests and docs for judges.
  • A real audience. Small businesses whose payment data lives in a system they can't rebuild.
FAQ

Questions

Does it change my database?

No schema changes, ever. Retrofit reads your tables and writes only to the columns your mapping names, such as a PayPal invoice id or a paid date. If you have no such columns, it keeps the links in its own state store. For CSV sources it writes to sidecar files and leaves the originals untouched.

Do I need a PayPal account to try it?

No. The demo ships with a local stand-in for the PayPal endpoints retrofit uses, with signed webhooks and customer pay pages. To use the real PayPal sandbox, create a free developer app and run the demo with --sandbox.

Can the AI move money on its own?

Only if you let it. Agents can only propose actions; each kind of action has a policy (auto, confirm or never). Refunds, cancellations and reminders wait for your approval by default, and accepting disputes is refused.

Which AI model does it use?

Claude through the official Anthropic SDK, defaulting to claude-opus-5-5. You can choose another model with RETROFIT_MODEL.

Is it production ready?

Not yet. It is built and tested against PayPal's sandbox APIs and refuses production mode unless explicitly enabled. Treat it as a strong starting point, not a finished payments product.

Is this an official PayPal product?

No. paypal-retrofit is an independent open-source project built on PayPal's public APIs and Agent Toolkit. It is not affiliated with or endorsed by PayPal.