Supplier Payment Assistant
A client-only buyer workflow for the Supplier Payment Decision Agent. It registers an ephemeral RSA public key, signs a caller-supplied invoice/PO/GRN request and obtains an advisory supplier-payment decision.
It never purchases goods or pays supplier invoices. Optional x402 fees buy verification only. There is no backend, database, customer invoice or credential in this repository.
Completely offline, clearly labelled synthetic demonstration.
Inspection first: quotes without a wallet or uploading invoice data.
Explicit payment authorization with a combined 0.055 USDC maximum.
Installable CLI, JSON reports, public request models and Python interface.
No LLM key or subscription required.
Install and try offline
Requires Python 3.12 or later:
python -m pip install "git+https://github.com/LKennedyShare/supplier-payment-assistant.git"
supplier-payment-assistant --demo
python -m supplier_payment_assistant accepts the same arguments.
The offline mode is SYNTHETIC_OFFLINE_ILLUSTRATION. It generates an ephemeral RSA signature over fictional input and shows an explicitly unverified FLAG_FOR_HUMAN_REVIEW example. It performs no live checks, key registration, wallet access or network requests. No synthetic supplier identity should be treated as real.
Inspect the real workflow without paying
Prepare your own unsigned JSON request in a local invoice.json file. Required top-level fields:
transaction_id: stable for the same business request.
supplier: CRO number, VAT number and IBAN.
invoice: invoice/PO/GRN references, amount, currency, payee name and lines.
purchase_order: PO reference, supplier, amount, currency and lines.
goods_receipt: GRN/PO references, supplier and received lines.
Do not include signature: the client creates it. The PaymentRequest model in supplier_payment_assistant.contracts defines exact fields, constraints and canonical signing bytes. The live service also publishes /schemas/decision.schema.json. The model checks structure, not registry status or account ownership.
supplier-payment-assistant https://supplier-payment-verifier-production.up.railway.app --request .\invoice.json
The default is inspection only. It sends empty quote probes for both operations, not your invoice, public key or signature. No wallet is needed and no on-chain payment is signed.
Use from another agent
import json
from pathlib import Path
from supplier_payment_assistant import run_live
unsigned = json.loads(Path("invoice.json").read_text(encoding="utf-8"))
report = run_live(
"https://supplier-payment-verifier-production.up.railway.app",
unsigned,
) # Inspection only: no payment or invoice upload.
Payment additionally requires the boolean pay=True and an exact cap such as max_usdc="0.055" (or a Decimal). Truthy strings such as "false" are rejected. BuyerError.report preserves partial workflow status; the CLI writes errors to stderr and exits nonzero.
The reusable sign_request function normalizes decimal fields with PaymentRequest before signing compact, sorted-key JSON without the signature field. Signatures use RSA-PSS, SHA-256, MGF1(SHA-256) and digest-length salt. Hand-signing the original JSON without normalization can produce different bytes.
Requests identify as supplier-payment-assistant. The label is not a verified customer identity; the payer wallet establishes the service tenant.
Assurance boundaries
EXECUTE_PAYMENT, REJECT_PAYMENT and FLAG_FOR_HUMAN_REVIEW are advisory result codes, not bank instructions this client executes.
IBAN checksum/name checks are not bank Confirmation of Payee or ownership.
The three-way match compares supplied documents, not authenticated ERP data.
RSA signatures establish who signed supplied data, not whether it is true.
Confidence 1.0 is a rule result, not a guarantee of payment safety.
Keep customer-controlled approval, account-ownership and bank-payment checks.
Development
git clone https://github.com/LKennedyShare/supplier-payment-assistant.git
cd supplier-payment-assistant
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[test]"
python -m pytest -q
Tests use mocked HTTP/facilitator responses and predictable unfunded test wallet material only. The CI workflow runs tests and the offline demonstration; it never authorizes a real payment.
Release and unpaid discovery automation
PyPI publication is pending owner authorization, not configured or published. Keep using the GitHub installation above until the first PyPI publication. The owner must sign in at https://pypi.org/manage/account/publishing/ and create this one-time pending trusted publisher:
PyPI project: supplier-payment-assistant
GitHub owner: LKennedyShare
Repository: supplier-payment-assistant
Workflow filename: publish.yml
Environment: pypi (exact, fixed GitHub environment name)
The owner must also create that GitHub environment. No API token or password is used. No manual approval per release is required by default; environment protection rules can impose approval if the owner chooses. After setup, publishing a GitHub release tagged v0.1.0 builds the current version’s wheel and sdist, runs mocked tests, the installed offline CLI and strict Twine checks, then publishes via OIDC. Only release.published triggers publication, not a PR or manual workflow run. Tags must exactly match v<pyproject.version> and package identity is checked before build. PyPI versions are immutable: future releases need a new version and matching tag. Duplicate uploads fail rather than silently skipping existing files. Current version remains 0.1.0 for the first publication.
discovery.yml runs nightly at 03:41 UTC and supports manual dispatch. It uses Python’s standard library only, no SDK, wallet, secrets or funds. It reads public health/OpenAPI/MCP/agent cards/homepage/buyers metadata and sends one empty-body IBAN REST quote probe, one empty-arguments MCP IBAN quote probe and one A2A message/send with operation=check_iban and request={}. It never registers keys, signs, pays, executes verification or uploads invoices or supplier identities. No output URLs are followed. All requests identify as scout-distribution-monitor: diagnostics, not customers, purchases, demand or independent adoption.
Run locally with python scripts/check_discovery.py --service supplier --output discovery.json. The JSON, Actions artifact and step summary contain only fixed check names and statuses, never response bodies, headers or private data. Requests refuse redirects, cap bodies at 2 MB and use 15-second socket timeouts; failures exit nonzero. A missing PyPI project is explicitly pending, without masking service failures. After publication add --require-pypi to the workflow’s monitor command to enforce PyPI availability and repository/MIT/name metadata. The homepage and /buyers.txt must link this public client repository.
GitHub schedules can be delayed or dropped and public-repository schedules may be disabled after 60 days without repository activity. This is not guaranteed continuous uptime monitoring; review Actions and re-enable schedules when needed. No artificial activity, stars or promotional posting is generated.
License
MIT licensed; see LICENSE. This covers this buyer client’s source code, not the separate verification service, registry data or API usage terms.
Metadata
Release files for supplier-payment-assistant 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| supplier_payment_assistant-0.1.0.tar.gz | 25.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| supplier_payment_assistant-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.3 kB
Release files / supplier_payment_assistant-0.1.0.tar.gz
| Download URL | supplier_payment_assistant-0.1.0.tar.gz |
|---|---|
| Size | 25.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
072626c20b6f3d0bacd857cdbe2e37384cc159e9347c84503b2cc59f1ef1de53
|
|
BLAKE2b-256 checksum How to use checksums |
efda3d86c5994288ca405eff3b0e729adcf45d0e8ac9d78f4afa596f7f3b7a9f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / supplier_payment_assistant-0.1.0-py3-none-any.whl
| Download URL | supplier_payment_assistant-0.1.0-py3-none-any.whl |
|---|---|
| Size | 14.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bae5aab7163097c2c6b31640f2bb639ccea76c6f61bf2a43a255688f13afbb83
|
|
BLAKE2b-256 checksum How to use checksums |
5c1560ed78612f4f358d6ce54230785741b8f671acfa01dd247894af60b48bd2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency log