QWED-UCP includes 10 verification guards that validate different aspects of UCP checkout data.
1. Money guard
Verifies the total formula is mathematically correct.
Usage
Tolerance
Uses Decimal precision with 1 cent ($0.01) tolerance for floating-point errors.
2. State guard
Verifies valid checkout state machine transitions.
Valid states
Usage
Rules
incomplete: Can be empty
ready_for_complete: Must have line items
completed: Must have order object
- Cannot transition backwards
3. Schema guard
Validates UCP JSON schema compliance.
Usage
Validates
- Required fields present
- Correct types (string, number, array)
- Valid enum values (status, total types)
4. Line items guard
Verifies price × quantity = line total for each item.
Usage
Checks
- Each item:
price × quantity = line_total
- Sum of line items = subtotal
- Quantities must be positive integers
- Prices must be non-negative
5. Discount guard
Verifies percentage and fixed discount calculations.
Usage - percentage discount
Usage - fixed discount
Rules
- Percentage: Must be 0-100%
- Fixed: Cannot exceed subtotal
- Discount must be non-negative
6. Currency guard
Validates ISO 4217 currency codes and format.
Usage
Validates
- 3-letter ISO 4217 codes (USD, EUR, GBP, JPY, etc.)
- Zero-decimal currencies (JPY, KRW) have no decimals
- Currency conversion accuracy
Zero-decimal currencies
7. Refund guard
Verifies refund amounts match original transactions.
Usage - full refund
Usage - partial refund
Usage - tax reversal
Usage - checkout refund
Rules
- Full refund must exactly match original total
- Partial refund percentage must be 0-100%
- Refund cannot exceed original total
- Tax reversal must be proportional to the refund percentage
8. Tip guard
Verifies tip calculations (pre-tax and post-tax).
Usage - pre-tax tip
Usage - post-tax tip
Usage - bounds check
Rules
- Tip percentage must be 0-100%
- Tip cannot be negative
- Tip cannot exceed 100% of the base amount
- Supports both pre-tax (subtotal) and post-tax (total) calculations
9. Fee guard
Verifies fee calculations (service, delivery, platform).
Usage - service fee
Usage - delivery fee
Rules
- Fee percentage cannot be negative
- Distance and rate cannot be negative
- Platform fee cannot be negative
- Platform fee cannot exceed the configured maximum percentage (default 30%)
10. Attestation guard
Generates cryptographic proofs (JWTs) for verification results.
Usage - sign a checkout
Every attestation is bound to a single verification event. You must pass a unique transaction_attempt_id and a one-time request_nonce when signing — the same values must be supplied at verify time. This prevents an attestation from one checkout being replayed against another.
verification_result accepts either a UCPVerificationResult returned by UCPVerifier.verify_checkout(...) or a legacy {"verified": bool, "errors": [...]} dict. Both are normalized internally.
Usage - verify an attestation
Verification is fail-closed on binding mismatch. You must pass the same transaction_attempt_id and request_nonce used when signing; any mismatch — or a missing jti, or a token that has already been consumed — returns verified=False.
Attestations are single-use by default. When consume=True (the default), the guard records the JWT’s jti and rejects any later call that presents the same token. Set consume=False only for read-only inspection.
Usage - create a receipt
create_receipt produces a non-cryptographic audit summary that pairs with an attestation. The attestation_id should be the same UUID returned in sign_checkout(...).details["attestation_id"], and transaction_attempt_id must match the value bound into the JWT.
JWT payload fields
In production, set QWED_ATTESTATION_SECRET as an environment variable or pass secret_key directly. Without a secret, initialization raises a ValueError unless allow_insecure=True or the QWED_DEV_MODE=1 env var is set.
Verification result fields
All guard results and UCPVerificationResult include:
Trust status
Every guard result and UCPVerificationResult carries a typed status: TrustStatus field that distinguishes between materially different failure modes. The TrustStatus enum is available from qwed-ucp v0.3.0 onward. Downstream policy code should branch on status rather than the derived verified: bool, so that “proof disproved” is not treated the same as “verifier engine crashed.”
States
Reading status
Verifier-level aggregation
UCPVerifier.verify_checkout() propagates the most-severe guard status to the top-level result (fail-closed ordering):
verified: bool remains a backward-compatible derived field: result.verified is True only when result.status == TrustStatus.VERIFIED. Existing code that reads result.verified continues to work unchanged, and existing constructors that pass verified=True or verified=False still produce the corresponding VERIFIED or FAILED status.
Running all guards
Use UCPVerifier to run all guards at once: