Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
PayPal 판매자를 위한 AI 백오피스 에이전트, 고객 메시지로 환불·청구서·구독 변경 초안 작성, 정책·판매자 승인 전까지 금전 이동 없음
An AI back-office agent for PayPal sellers. It drafts refunds, invoices and subscription changes from customer messages; nothing moves money until policy and the seller countersign.
금융TypeScript · CSSGitHub @leesin1716-byte온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기AI back office for PayPal sellers: Claude drafts refunds, invoices and subscription changes; a deterministic policy and the seller countersign before money moves.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗An AI back office for PayPal sellers that can't move money on its own.
Countersign reads a small shop's customer messages and turns each one into a single proposed PayPal change: a partial or full refund, an invoice, a subscription pause, or just a reply. Before anything executes, a deterministic policy engine re-reads the order or subscription in PayPal and checks the proposal against the seller's own rules. Small changes inside the seller's mandate run on their own. Everything else waits in a review grid until the seller countersigns it, and then it executes against the PayPal API with an idempotency key. Every step lands in an audit log.
Hosted demo: https://countersign-delta.vercel.app · Demo video: https://youtu.be/PkDmTqcNEUA No login is needed. Each visitor gets a private demo store whose orders and subscription are created in the PayPal sandbox.
A one-person online shop answers the same handful of emails every day: it arrived late, it arrived broken, can you invoice my café, please pause my box, where is my parcel. Each one ends in a few clicks in PayPal, and each one is a chance to refund the wrong order, refund twice, or give away too much. Handing those clicks to an AI agent saves time, but an agent that can call refund APIs directly is one convincing email away from paying out money it shouldn't.
Countersign keeps the speed and removes that risk. The model drafts. Code that the seller can read decides. The seller signs.
prompt_injection, the carrier shows a signature, and policy sends it to review. Nothing moves.PayPal is the system of record. Every money movement and every fact the policy relies on comes from the PayPal REST API (lib/paypal/sandbox.ts).
| What | PayPal API | Where |
|---|---|---|
Seed each demo store with real captured orders, paid with a sandbox test card, tagged with custom_id = workspace:customer | Orders v2 POST /v2/checkout/orders (card payment_source, intent: CAPTURE) | createCapturedOrder |
| Attach carrier tracking to each shipped order | Orders v2 POST /v2/checkout/orders/{id}/track | addTracking |
| Agent and policy lookups: status, captured amount, already refunded, trackers, owner | Orders v2 GET /v2/checkout/orders/{id}, Payments v2 GET /v2/payments/captures/{id} | getOrderFacts |
Partial and full refunds, with PayPal-Request-Id set to the plan id so a retried signature can never refund twice | Payments v2 POST /v2/payments/captures/{id}/refund | refundCapture |
| Wholesale invoices | Invoicing v2 create draft → POST /send → GET | createAndSendInvoice |
| A monthly "Glaze of the Month" box | Catalog Products v1, Billing Plans v1, Subscriptions v1 (card payment_source) | ensurePlan, createActiveSubscription |
| Pausing a subscription | Subscriptions v1 POST /suspend, then GET to confirm | suspendSubscription |
After every execution the app reads the object back from PayPal and shows PayPal's own numbers ("PayPal now shows $129.00 refunded of $129.00"), not its own bookkeeping.
claude-haiku-4-5-20251001) through the Anthropic TypeScript SDK, in a hand-written tool-use loop (lib/agent/agent.ts).list_customer_records, get_order, get_subscription, get_price_list. The model cannot see other customers' orders and has no tool that moves money. It ends by calling submit_proposal, whose input is validated with Zod (a refund must name an order and an amount, a pause must name a subscription, and so on). Invalid proposals are sent back to the model as tool errors.attachment evidence.<customer_message> and the system prompt tells the model to flag instructions inside it as prompt_injection.lib/policy.ts, plain TypeScript with unit tests.For each proposal, policy re-reads PayPal and runs explicit checks. The UI shows every check with its result.
custom_id says it belongs to the sender.flowchart LR
M[Customer message\n+ photo] --> A[Claude Haiku 4.5\nread-only PayPal tools]
A -->|proposal| P{Policy engine\nre-reads PayPal}
P -->|inside mandate| X[Execute in PayPal\nidempotent]
P -->|needs signature| G[AG Grid review]
P -->|review / blocked| G
G -->|seller countersigns\npolicy re-checked| X
X --> R[Read back from PayPal] --> L[Audit log]
Requirements: Node.js 20 or newer.
npm install
cp .env.example .env.local # add your keys, see below
npm run dev # http://localhost:3000
Without any keys the app still runs end to end: PayPal is replaced by an in-memory simulator (PAYPAL_MODE=mock, shown as "PayPal simulated" in the header), the six scripted messages replay recorded Claude runs, and new messages use a rules fallback.
PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING.).env.local as PAYPAL_CLIENT_ID and PAYPAL_CLIENT_SECRET.npm run probe:sandbox. It places one test order, refunds it, adds tracking, creates and cancels an invoice and creates a plan and subscription, printing OK/FAIL per call.The seed pays with PayPal's public sandbox test Visa 4032 0393 1798 4658 (override with PAYPAL_TEST_CARD). No real card or real money is involved.
Put an Anthropic API key in ANTHROPIC_API_KEY to run messages written in the demo through Claude live. The six scripted messages use recorded runs (lib/agent/seed-cache.json), so visitors who only click through the scenario cost nothing. To re-record them: npx vitest run --config vitest.record.config.mts (about $0.05).
Live calls are capped per visitor per day, for everyone per day, and in total (LIVE_AI_* in .env.example). When a cap is hit, the rules fallback answers and the UI says so.
npm test # 40 unit and integration tests (policy, agent loop with a scripted model, full scenario on the PayPal simulator, Blob store)
npx playwright install chromium
npm run test:e2e # browser tests: triage, countersign, blocked over-refund, injection, compose, reset
npm run test:e2e:sandbox # the six scenario flows against the real PayPal sandbox (keys in .env.local; no Claude spend)
npm run typecheck
npm run test:e2e:sandbox creates real sandbox orders, then checks each flow end to end: refunds and the subscription pause under the mandate, the countersigned refund and invoice, the held injection attempt, PayPal IDs in the grid and audit log, and a reset that seeds new orders. With SCREENSHOT=docs/screenshot.png it also saves the image above.
The integration tests cover the six scenario outcomes, countersigned refunds and invoices, a refund made elsewhere between drafting and signing, seller edits, idempotent retries and mandate changes.
The hosted demo runs on Vercel. Serverless instances do not share memory or disk, so on Vercel the app keeps each visitor's demo store and the rate-limit counters in a private Vercel Blob store (reads bypass the CDN cache, writes are compare-and-swap on the ETag). Locally, with no Blob credentials, it uses JSON files in ./data.
BLOB_READ_WRITE_TOKEN.PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET and, for live Claude calls, ANTHROPIC_API_KEY. The optional LIVE_AI_* and RESETS_PER_VISITOR_DAILY caps are listed in .env.example.E2E_BASE_URL=https://<your-app>.vercel.app npm run test:e2e:sandbox.Any long-running Node host also works with the file store (npm run build && npm start; set DATA_DIR to a writable folder).
app/ Next.js App Router pages and API routes (workspace, triage, messages, plans, mandate)
components/ Inbox, AG Grid plan review, plan detail, audit log, mandate bar
lib/agent/ Claude tool-use loop, prompt and tools, recorded seed runs, rules fallback
lib/paypal/ PayPal REST client (sandbox) and an in-memory simulator with the same interface
lib/policy.ts Deterministic policy engine
lib/executor.ts Executes approved plans in PayPal and reads results back
lib/service.ts Orchestration, mandate, audit log
lib/store.ts Per-visitor workspaces and rate-limit counters (private Vercel Blob when hosted, JSON files locally)
tests/, e2e/ Vitest and Playwright suites
scripts/ Sandbox probe, seed-run recorder, illustration generator
Next.js 16, React 19, TypeScript, AG Grid Community, the Anthropic TypeScript SDK (Claude Haiku 4.5), the PayPal REST APIs (Orders v2, Payments v2, Invoicing v2, Catalog Products, Billing Plans, Subscriptions v1), Zod, Vercel (hosting and Blob storage), Vitest and Playwright.