README.md

July 20, 2026 · View on GitHub

QWED Logo

QWED-UCP

Deterministic Verification Middleware for Universal Commerce Protocol

Verify AI agent commerce before the money moves.

QWED-UCP sits between AI agents and payment processors — catching miscalculated totals,
invalid state transitions, and malformed checkouts before they hit production.

PyPI CI License Python 3.10+ Verified by QWED Snyk GitHub stars

Quick Start · The Guards · Integration · Trust Status · 📖 Docs


🚨 The Problem

AI agents (Gemini, ChatGPT, Claude) now generate e-commerce checkouts directly — cart totals, tax, discounts, refunds, fees. These agents hallucinate on math:

ScenarioLLM OutputCorrect
10% off $99.99"$10.00 discount"$9.999 → $10.00 ✅
8.25% tax on $100"$8.00 tax"$8.25 ❌
$50 + $30 + $20 cart"$110.00 total"$100.00 ❌
Discount applied after taxWrong orderMath error ❌

QWED-UCP blocks these errors before they reach a payment processor.


✅ What QWED-UCP Is (and Isn't)

QWED-UCP IS:

  • Verification middleware that checks AI-generated UCP checkouts
  • Deterministic — uses Decimal math (no floating-point errors) and state-machine logic
  • Open source (Apache 2.0) — integrate into any e-commerce workflow
  • A safety layer — catches calculation errors and invalid state transitions before payment

QWED-UCP is NOT:

  • A shopping cart — use Shopify, WooCommerce, or Stripe for that
  • A payment processor — use Stripe, Adyen, or Square for that
  • A fraud detection system — use Sift, Signifyd, or Riskified for that
  • A replacement for e-commerce platforms — we just verify the math

Think of QWED-UCP as the "accountant" that reviews every AI checkout before payment.

Shopify builds carts. Stripe processes payments. QWED verifies the math.


🆚 How QWED-UCP Differs from E-Commerce Platforms

AspectShopify / Stripe / AdyenQWED-UCP
PurposeBuild carts, process paymentsVerify calculations
ApproachTrust AI outputsDeterministically verify AI outputs
Accuracy~99% (edge cases fail)100% deterministic
TechStandard floating-pointDecimal + JSON Schema
IntegrationReplace your stackSits between AI and payment
PricingTransaction feesFree (Apache 2.0)

Use Together

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   AI Agent   │ ──► │  QWED-UCP    │ ──► │    Stripe    │
│ (checkout)   │     │  (verifies)  │     │  (payment)   │
└──────────────┘     └──────────────┘     └──────────────┘

🛡️ The Guards

QWED-UCP ships 10 verification guards. UCPVerifier.verify_checkout() runs the 3 core guards as a fail-closed pipeline; the remaining 7 guards are available as standalone classes for manual or middleware use.

Core Guards (run by verify_checkout())

GuardEngineWhat It Verifies
Money GuardDecimalCart totals against UCP formula: Total = Subtotal - Discount + Fulfillment + Tax + Fee
State GuardManual state logicCheckout state machine (draft → ready → complete), rejects illegal transitions
Structure GuardJSON SchemaUCP schema compliance (v1.0)

Standalone Guards

GuardEngineWhat It Verifies
Line Item GuardDecimalItem quantity × price = line total
Discount GuardDecimalPercentage and fixed discount calculations
Currency GuardDecimalCurrency precision, $0.01 rounding, supported codes
Refund GuardDecimalFull/partial refund amounts, tax reversals
Tip GuardDecimalPre/post-tax tip calculations, min/max bounds
Fee GuardDecimalService fees, delivery fees, platform fees
Attestation GuardJWT (PyJWT)Context-bound attestation tokens with in-memory replay protection

🚀 Quick Start

Installation

pip install qwed-ucp

Verify a Checkout

from qwed_ucp import UCPVerifier

verifier = UCPVerifier()

checkout = {
    "currency": "USD",
    "totals": [
        {"type": "subtotal", "amount": 100.00},
        {"type": "tax", "amount": 8.25},
        {"type": "total", "amount": 108.25}
    ],
    "status": "ready_for_complete"
}

result = verifier.verify_checkout(checkout)

if result.verified:
    print("✅ Transaction verified — safe to process!")
else:
    print(f"❌ Verification failed: {result.error}")

verify_checkout() is always a full fail-closed trust verdict: it returns verified=True only when Money Guard, State Guard, and Structure Guard all pass.

Verify Totals Only

# Math-only check — does not verify state or schema
result = verifier.verify_totals_only(checkout)

⚠️ Do not treat verify_totals_only() as a final transaction verdict. It only runs the Money Guard and does not check state or schema validity.


📊 Interpreting Results

Shared Fields (all results)

FieldTypeDescription
verifiedboolConvenience flag — True only when status == TrustStatus.VERIFIED
statusTrustStatusTyped trust verdict — see Trust Status
errorOptional[str]Error message when verification fails

Top-Level Only (UCPVerificationResult)

FieldTypeDescription
enginestr"QWED-Deterministic-v1"
guardslist[GuardResult]Individual guard outcomes
verification_modestr"deterministic"

Branching on status (preferred)

from qwed_ucp import UCPVerifier, TrustStatus

verifier = UCPVerifier()
result = verifier.verify_checkout(checkout)

if result.status == TrustStatus.VERIFIED:
    proceed_to_payment(checkout)
elif result.status == TrustStatus.ENGINE_ERROR:
    page_operator("Verifier crashed — manual review required")
else:
    reject_transaction(f"Proof failed: {result.status}")

Aggregation

verify_checkout() propagates the most-severe guard status to the top level (fail-closed ordering):

Top-level statusTriggered when
ENGINE_ERRORAny guard raised an exception
QUARANTINEDA guard returned QUARANTINED (reserved)
FAILEDA guard deterministically disproved the transaction
UNVERIFIABLEMost-severe guard status is UNVERIFIABLE
UNSUPPORTEDMost-severe guard status is UNSUPPORTED
PARTIALMost-severe guard status is PARTIAL
VERIFIEDAll guards passed

🔌 Integration

FastAPI Middleware

QWED-UCP ships a configurable FastAPI/Starlette middleware (requires Starlette, included with pip install qwed-ucp) that intercepts checkout requests and verifies them automatically:

from fastapi import FastAPI
from qwed_ucp.middleware.fastapi import QWEDUCPMiddleware

app = FastAPI()
app.add_middleware(QWEDUCPMiddleware)

The middleware:

  • Intercepts POST/PUT/PATCH to paths matching /checkout, /cart, /payment
  • Returns 422 Unprocessable Entity on verification failure (configurable)
  • Sets headers X-QWED-Verified, X-QWED-Guards-Passed, X-QWED-Error
  • Runs core guards (Money, State, Schema) plus optional advanced guards
  • Always fail-closed on empty body, malformed JSON, or non-dict payload

Configuration:

app.add_middleware(QWEDUCPMiddleware,
    block_on_failure=True,       # Block on verification failure (default)
    include_details=True,        # Include guard details in error response
    use_advanced_guards=True,    # Also run Line Items, Discount, Currency guards
    verify_paths=["/checkout"],  # Override default path list
    verify_methods=["POST"],     # Override default method list
)

A helper dependency is also available for manual injection:

from qwed_ucp.middleware.fastapi import create_verification_dependency

verify = create_verification_dependency()

@app.post("/checkout")
async def create_checkout(
    checkout: dict,
    verification = Depends(verify)
):
    if not verification["verified"]:
        raise HTTPException(422, verification["error"])
    ...

Express.js Middleware

QWED-UCP also ships an Express.js middleware:

const express = require('express');
const { createQWEDUCPMiddleware } = require('qwed-ucp');

const app = express();
app.use(express.json());
app.use(createQWEDUCPMiddleware());

app.post('/checkout', (req, res) => {
    res.json({ status: 'verified', checkout: req.body });
});

See examples/express_server.js for a complete example with rate limiting and security hardening.

Stripe

import stripe
from qwed_ucp import UCPVerifier

def create_payment_intent(ucp_checkout):
    verifier = UCPVerifier()
    result = verifier.verify_checkout(ucp_checkout)

    if not result.verified:
        raise ValueError(f"Checkout math error: {result.error}")

    total = next(
        (item["amount"] for item in ucp_checkout["totals"]
         if item["type"] == "total"),
        None
    )
    if total is None:
        raise ValueError("Missing required 'total' entry in checkout.totals")
    return stripe.PaymentIntent.create(
        amount=int(total * 100),
        currency=ucp_checkout["currency"].lower()
    )

CI/CD

# .github/workflows/verify-checkout.yml
name: Verify UCP Checkouts
on: [push]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: QWED-AI/qwed-ucp@v1
        with:
          test-script: tests/verify_checkouts.py

🔏 AttestationGuard

For environments that need cryptographic proof of verification:

from qwed_ucp import AttestationGuard, UCPVerifier
import uuid

attester = AttestationGuard(
    secret_key="your-256-bit-secret",
    allow_insecure=True     # Set False in production
)

verifier = UCPVerifier()
result = verifier.verify_checkout(checkout)

attestation = attester.sign_checkout(
    checkout=checkout,
    verification_result=result,      # Accepts UCPVerificationResult directly
    transaction_attempt_id=str(uuid.uuid4()),
    request_nonce=str(uuid.uuid4()),
    session_id="sess_abc123"
)

# attestation.token is a signed JWT

transaction_attempt_id and request_nonce are required for context binding and in-memory replay protection (not shared across replicas or restarts — use an external store for multi-instance deployment). Set QWED_ATTESTATION_SECRET env var instead of passing secret_key in code.


🏷️ Trust Status

QWED-UCP v0.3.0+ exposes a typed TrustStatus enum on every verification result, replacing the old verified: bool-only model:

StateMeaning
VERIFIEDDeterministic proof succeeded under supported conditions
FAILEDProof was attempted and disproved (e.g. totals mismatch)
UNVERIFIABLEProof could not be established (e.g. missing proof basis)
UNSUPPORTEDInput or state is outside supported semantics
PARTIALSome checks ran, but no final verdict is justified
ENGINE_ERRORA verifier dependency or the runtime crashed
QUARANTINEDReserved for policy-level rejection

verified: bool is preserved as a backward-compatible derived field: result.verified == True only when result.status == TrustStatus.VERIFIED.


🔒 Security & Privacy

Your checkout data never leaves your machine.

ConcernQWED-UCP Approach
Data TransmissionNo API calls, no cloud processing
StorageNothing stored — pure computation
DependenciesLocal-only (Decimal, JSON Schema, PyJWT, Starlette)
PCI ComplianceNo cardholder data processed

Perfect for: e-commerce with strict privacy requirements, transactions containing PII, PCI-DSS compliant environments.


🗺️ Roadmap

v0.3.0 (Current)

  • UCPVerifier with 3 core guards (Money, State, Structure)
  • All 10 guards shipped and tested
  • TrustStatus enum on every result
  • FastAPI middleware (fail-closed on unparseable bodies)
  • Express.js middleware
  • AttestationGuard with context-bound JWT + replay protection

In Progress

  • Multi-currency support (exchange rates)
  • Subscription/recurring payment validation
  • TypeScript/npm SDK

Planned

  • Shopify webhook integration
  • Stripe Checkout session verification
  • WooCommerce plugin
  • Real-time cart verification API

❓ FAQ

Is QWED-UCP free?

Yes! Apache 2.0 license. Use it in commercial products, modify it, distribute it — no restrictions.

Does it handle floating-point precision issues?

Yes! Uses Python's Decimal type with ROUND_HALF_UP to 2 decimal places. No 0.1 + 0.2 = 0.30000000000000004 issues.

What is the UCP total formula?

Total = Subtotal - Discount + Fulfillment + Tax + Fee

QWED-UCP's Money Guard verifies AI outputs against this formula exactly.

Can I use it without Google UCP?

Yes! The guards work with any JSON checkout format that has a totals array with type and amount fields.

How fast is verification?

Sub-millisecond to low milliseconds per checkout, depending on the guard set. The Decimal math engine is optimized for currency calculations.

Does QWED-UCP expose TrustStatus in the Python SDK?

Yes. qwed_ucp.TrustStatus is a 7-state enum on every result dataclass. The verified: bool field is preserved for backward compatibility.


PackagePurpose
qwed-verificationCore verification engine
qwed-financeBanking & financial verification
qwed-legalLegal contract verification
qwed-infraInfrastructure-as-code verification
qwed-taxTax compliance verification
qwed-mcpClaude Desktop MCP integration
qwed-open-responsesOpenAI Responses API guards

ResourceLink
Universal Commerce Protocolucp.dev
Google UCP Docsdevelopers.google.com/merchant/ucp
QWED Documentationdocs.qwedai.com
QWED-AI Organizationgithub.com/QWED-AI

🧑‍💻 Development

From Source

git clone https://github.com/QWED-AI/qwed-ucp.git
cd qwed-ucp
pip install -e ".[dev]"

Running Tests

pytest tests/ -v                # All tests
pytest tests/ -v --cov=src/qwed_ucp --cov-report=html  # With coverage
pytest tests/test_money_guard.py -v  # Single guard

Linting

ruff check src/ tests/

📄 License

Apache 2.0 — See LICENSE


Built with ❤️ by QWED-AI

"AI agents shouldn't guess at math. QWED makes commerce verifiable."