How it works
Language models propose. Deterministic code decides. PayPal moves the money.
PACT sits between two negotiating agents and the payment. This is the two-minute version of the architecture: what happens in a deal, who is allowed to do what, and which PayPal calls carry it.
The lifecycle
One deal, from a sentence to a settled payment.
The funds are held before any work starts and move only after the delivery is checked against the contract. If the check fails, nothing is captured.
Settlement rail
Capture is a consequence of verification, never of a claim.
- IntentA human sets the task and the budget
- NegotiationBuyer and seller agents agree terms
- ContractTerms compiled and hashed
- PayPal authorizationFunds held, not captured
- DeliveryThe seller agent submits the work
- AI verificationChecked against the contract
- CaptureOnly when the contract is satisfied
Contract
Machine-readable- Price
- $47.00
- Deliverables
- 3 illustrations
- Formats
- 16:9 + 1:1
- Revisions
- 1
- Terms hash
- a3f1…9c2e
Verification
$47.00 still held| Condition | Result | Evidence |
|---|---|---|
| 3 illustrations | PASS | 3 supplied |
| 1:1 format | FAIL | missing on #2 |
Not captured. One required condition failed, so the seller agent is asked to revise.
Who does what
Three kinds of actor, and a hard line between them.
A model can be persuaded, and a seller’s delivery is untrusted input. So nothing a model says changes a deal’s status, a limit or a payment until an engine has checked it.
01/Models propose
Agents do the talking and the work
Useful, and never trusted on their own word.
Buyer agent. Turns your request into a mandate and negotiates inside your budget.
Seller agent. Quotes from its own rate card, negotiates, and produces the deliverable.
AI verifier. Judges the subjective conditions, with evidence and a confidence score.
Auditor agent. Re-reads PayPal’s record of the order through one read-only tool.
Every output is parsed against a strict schema. No model holds a tool that can authorize, capture or void.
02/Deterministic code decides
Engines turn proposals into decisions
Pure functions. Same input, same answer.
Negotiation rules. Turn order and move limit. The buyer can never agree above its budget.
Contract engine. Compiles the agreed terms and hashes them: SHA-256 over canonical JSON.
Policy engine. Five spending checks decide: allow, ask a human, or block.
Verification decision. Deterministic checks plus the AI’s findings become a computed decision.
Capture guard. The last check before money moves: status, contract hash, report, amount, expiry.
Each decision is appended to a hash-chained audit log, so it can be replayed and cannot be quietly edited.
03/PayPal moves the money
Funds are held first, captured on proof
Authorization and capture, in the PayPal Sandbox.
Authorize. The contract price is held on the payer’s account before any work starts.
Capture. Only after the capture guard passes, for the amount in the contract.
Void. If the contract is not met, the hold is released and nothing is captured.
Webhooks. Signed events confirm what happened. They never trigger a capture.
PACT never takes custody of funds. Only its payment orchestrator calls the endpoints that move money.
And a person decides when code will not
When a rule cannot settle something, the engine stops and waits. It never asks a model to break the tie.
Approve the spend
The price is above the autonomous limit, or the seller is new.
Approve in PayPal
No delegated wallet is connected, so the payer consents to the hold.
Review the delivery
Verification is ambiguous, or the delivery looks like an attempt to manipulate it.
The payment rail
The PayPal calls PACT makes.
Orders v2 with intent AUTHORIZE, Payments v2 to capture or void, Vault v3 for the delegated wallet, and signed webhooks. The contract hash travels with the money as the order’s custom_id.
| Step | API | Call | What PACT sends or checks |
|---|---|---|---|
| Open the order | Orders v2 | POST | intent AUTHORIZE, amount = contract price, custom_id = pact:v1:<terms hash>, invoice_id = contract id. |
| Hold the funds | Orders v2 | POST | After re-reading the order: its amount and custom_id must still match the contract. |
| Pay on proof | Payments v2 | POST | final_capture, and only after the capture guard and a fresh read of the authorization. |
| Release otherwise | Payments v2 | POST | When the delivery is rejected, by verification or by a human reviewer. Nothing is captured. |
| Delegated wallet: consent | Vault v3 | POST | Starts the one-time consent. The payer approves it in PayPal. |
| Delegated wallet: token | Vault v3 | POST | Exchanges the consent for a payment token. Later in-policy orders authorize without a login. |
| Trust an event | Webhooks | POST | An incoming event is acted on only after PayPal confirms its signature. Events are deduplicated by id. |
Open the order
Orders v2POST/v2 /checkout /orders intent AUTHORIZE, amount = contract price, custom_id = pact:v1:<terms hash>, invoice_id = contract id.
Hold the funds
Orders v2POST/v2 /checkout /orders /{id} /authorize After re-reading the order: its amount and custom_id must still match the contract.
Pay on proof
Payments v2POST/v2 /payments /authorizations /{id} /capture final_capture, and only after the capture guard and a fresh read of the authorization.
Release otherwise
Payments v2POST/v2 /payments /authorizations /{id} /void When the delivery is rejected, by verification or by a human reviewer. Nothing is captured.
Delegated wallet: consent
Vault v3POST/v3 /vault /setup-tokens Starts the one-time consent. The payer approves it in PayPal.
Delegated wallet: token
Vault v3POST/v3 /vault /payment-tokens Exchanges the consent for a payment token. Later in-policy orders authorize without a login.
Trust an event
WebhooksPOST/v1 /notifications /verify-webhook-signature An incoming event is acted on only after PayPal confirms its signature. Events are deduplicated by id.
Idempotent by construction: PayPal-Request-Id
Each call that holds or moves money carries a deterministic PayPal-Request-Id and is written to a ledger first. If the process dies after PayPal accepted a capture, the retry replays the same key and adopts that capture instead of making a second one.
Covers Open the order · Hold the funds · Pay on proof · Release otherwise
The two gates
A deal passes two decisions. Both are computed.
One before funds are held, one before they are captured. Each is a pure function with unit tests, and each result is written to the audit trail.
Before the hold: spending controls
Five checks run on every contract, before any PayPal call. All five are always evaluated and reported, not just the first one that objects.
Category allowed
Blocks the dealThe work must be in a category you allow. Restricted work is refused whatever the policy says.
Per-transaction maximum
Blocks the dealOne deal may not exceed the per-transaction maximum ($1,000.00 by default).
Daily limit
Blocks the dealEverything authorized in a UTC day may not exceed the daily limit ($2,500.00 by default).
Autonomous limit
Asks a humanAbove the autonomous limit ($100.00 by default) the agent may not commit funds alone.
Seller trust
Asks a humanA seller with no settled history waits for a person, unless you switch that rule off.
Before the capture: the verification decision
Every contract condition gets a result, its evidence and a confidence. The decision is computed from those checks. It is never generated.
| When, decision and the money | Decision | The money |
|---|---|---|
| Every required condition passes at or above the auto-capture confidence.Capture eligibleCaptured | Capture eligible | Captured |
| A required condition clearly fails and a revision remains.Revision requiredHeld, not captured | Revision required | Held, not captured |
| A required condition clearly fails and no revision remains.RejectedHold voided | Rejected | Hold voided |
| Anything ambiguous: low confidence, the AI verifier unavailable, or suspected manipulation.Human reviewHeld until a human decides | Human review | Held until a human decides |
Go deeper
The long form, and the API.
Everything on this page is in the repository, with the reasoning behind it.
- ArchitectureComponents, the deal state machine, how a step executes, degraded modes.github.com · docs (opens in a new tab)
- Security modelTrust boundaries, what a model can and cannot reach, how deliveries are sanitised.github.com · docs (opens in a new tab)
- OpenAPI descriptionEvery HTTP endpoint of this deployment, machine-readable./openapi.json (opens in a new tab)
See it run.
Start a deal and watch each step above happen: negotiation, contract, authorization hold, delivery, verification, and a capture that waits for proof.