Inspiration

A plausible payment request should not become permission to spend.

Business agents can help prepare contractor and software payments, but giving a model payment credentials turns a mistaken interpretation or malicious instruction into a financial risk. PayGuard explores a narrower, practical alternative: let AI propose the terms, let deterministic policy authorize them, and let a separate executor verify authorization before paying.

The intended users are developers adding payment capabilities to business agents, and the operators who need to understand and control those requests.

What it does

PayGuard is a local, single-operator authorization prototype built around PayPal Sandbox Payouts. It turns a natural-language request into six structured fields: amount, currency, recipient, category, invoice reference and purpose.

The gateway validates the intent and returns ALLOW, REVIEW or DENY under fixed rules: USD only, a USD 500 ceiling, human review above USD 50, an approved-recipient list, contractor/software categories and recipient-plus-invoice duplication checks. Human review cannot override a denial.

The responsive workspace shows the request, individual policy checks, review queue, execution receipt and chronological audit trail. Approval and execution are separate actions. Even a policy-allowed request requires an authenticated operator to initiate execution.

How I built it

Three Node.js processes separate proposal, authorization and execution:

  1. Agent: extracts intent using local Ollama or an explicitly labeled deterministic demo parser. Its process environment receives no PayPal credentials, signing key or executor token.
  2. Gateway: validates untrusted output, evaluates policy, stores immutable terms and issues an expiring Ed25519-signed grant. Required human approval is bound to those stored terms.
  3. Executor: independently verifies the grant, intent, expiry, policy and required review, then durably reserves the request and recipient/invoice before calling PayPal.

The PayPal adapter implements client-credentials OAuth, Payouts creation, status retrieval and independent reconciliation. It is hardcoded to the PayPal Sandbox origin and refuses redirects. Stable request and sender identifiers accompany execution. Uncertain outcomes remain reserved and are never automatically retried.

Hash-chained, fsynced local journals reconstruct state across restarts. The interface distinguishes API submission from settlement and shows both batch and individual-item status.

The stack is JavaScript, Node.js 20.9+, native HTTP/crypto/filesystem APIs, HTML and CSS, PayPal REST APIs, Ollama and Qwen2.5 1.5B. There are no npm dependencies. Source code, documentation and original UI assets are licensed under Apache-2.0; separately installed runtimes and model weights retain their own licenses.

How AI is used

Actual inference uses Ollama 0.35.1 with qwen2.5:1.5b, running locally with cloud disabled. The model produces JSON intent, not an approval decision, and has no payment tools.

Explicit alternatives and malformed money terms are checked before inference. Model output undergoes strict six-field validation and checks against explicitly supplied payment terms. If inference fails or returns invalid intent, the request fails without silently switching to the demo parser. These checks cover tested input patterns, not every possible semantic ambiguity.

What is verified, and what is simulated

On 4 October 2026, two distinct USD 0.01 PayPal Sandbox payouts completed the agent → gateway → signed grant → executor → PayPal flow. Both were independently reconciled against the PayPal API, with matching terms and both batch and item SUCCESS. The second payout used actual local Ollama extraction; the first used the deterministic parser. These were sandbox mock funds, not production money.

The USD 0.01 requests did not require threshold review, but an authenticated operator initiated execution. The larger payment examples and the screenshots demonstrate simulated payments. A demo receipt is not evidence of PayPal settlement, and the demo parser is not model inference. AI mode and payment mode can be selected independently.

The repository records 9/9 live AI/input/policy cases passing, including review, denial, malformed input, ambiguity and injection cases. Four review/denied execution attempts returned HTTP 403 before reaching the executor. The automated suite contains 22 passing tests, including actual three-process HTTP and restart behavior; provider fixtures do not create external payments.

Challenges and what I learned

An ambiguous request initially led the model to choose one of two amounts. That proposal never executed. I added explicit-ambiguity rejection and term-binding checks, then verified the nine-case run. The lesson was to make the authorization boundary independent of model obedience.

Payment acceptance also differs from payment settlement. PayGuard therefore preserves uncertain attempts, exposes separate batch/item states and reconciles recorded terms before declaring success.

Try it yourself

Clone the public repository, enter its directory and run npm start with Node.js 20.9+ and npm. Open http://127.0.0.1:3000. The offline demo needs no API credentials or model download; its simulation-only operator passphrase is payguard-demo.

Try the USD 120 human-review request, authenticate and approve its stored terms, then simulate execution. Try the USD 900 denial and the USD 24 policy-allowed request. Use fresh invoice references. Run npm test and npm run check for automated verification.

The README provides complete optional setup for real local Ollama inference and for judges' own PayPal Business sender and Personal recipient sandbox accounts. Real AI can be tested with offline payments. Sandbox verification and read-only payout reconciliation commands are documented separately.

Limits and what's next

This is a working sandbox prototype on a trusted local host. Process/environment separation is not OS isolation against hostile code under the same user. It has no production payment mode, multi-user identity, cumulative spending budget or trusted accounting source. Renamed invoices can evade exact duplication checks; hash chains do not prevent a host owner from rewriting an entire journal.

Next steps would be separate OS identities, stronger operator authentication, cumulative budgets, invoice/accounting verification and independent audit checkpoints. The current contribution is a concrete, inspectable authorization boundary that keeps model-generated proposals separate from payment authority.

Built With

Share this project:

Updates

Submission history