1.2.0-rc.1 / Payment profiles
Verifier transport
Read authenticated assertions from the explicitly appointed HTTPS verifier.
profiles/network_payments.py joins current-origin HTTPS discovery, retained authority history, the delegated-authority resolver, a provider’s signed payment assertion and the durable local payment ledger. It is a read-only verification adapter. An authenticated accepted quote and separate payer mandate must already be in the ledger; no method creates them, requests a charge or issues an access token.
The verifier performs the following sequence for one explicit check ID:
- Read the retained accepted quote and mandate, then construct the exact payment-check body.
- Fetch
/odexa-service.jsonand/odexa.jsonfrom the quoted origin using verified HTTPS. Persist their exact bytes and reject revision rollback or identity redefinition. - Resolve the quoted provider, endpoint, payment capability, named delegation and accepted resource/purpose against that current origin authority.
- Resolve and connect to the provider using the bounded transport. Immediately before sending HTTP content or a scoped credential, check retained history again, read the live clock and resolve authority again. DNS, TLS or local-history delays must not preserve expired authorization to disclose payment context.
- POST only the canonical payment check to the exact quoted verification endpoint. Require a successful
application/joseresponse. The response header’s key ID is merely a hint to a key that the origin must authorize; it supplies no trust of its own. - Fetch and retain fresh origin authority after the provider reply. Withdrawal, key revocation, outage or rollback at this point prevents payment-state commitment.
- Verify the provider signature and exact settlement bindings. After acquiring the payment write lock, check the locally highest observed snapshot and reevaluate signature, delegation, key validity and timing using the live clock. Commit exact proof, state and audit together only if all checks pass.
The payment transaction uses a trusted callable clock, not a timestamp captured before waiting for a database lock. It retries a local authority evaluation once if the whole-second clock changes during that evaluation; continued time movement aborts for a new current observation. A payment confirmation after the accepted access window can record a financial fact with access still expired. Acceptance, a verified payment gate and policy access permission remain separate concepts.
transport = AuthorityTransport() # Verified public HTTPS addresses by default.
history = AuthorityHistory('/private/application-data/authority.sqlite3')
verifier = NetworkPaymentVerifier(transport, history)
state = verifier.check(ledger, agreement_id, check_id=check_id,
delegation_id=origin + '/delegations/payment', credential=scoped_provider_credential)
The optional credential names one exact provider origin and canonical tenant directory. It is never forwarded to the origin’s metadata URLs, another host, a redirect or a different tenant path. No cookie jar, environment proxy or ambient login is used. Loopback tests explicitly supply their private test CA and permit the exact loopback address; the production-default address policy rejects it.
Network or authority failure leaves the existing payment state unchanged. A retry verifies the same payment; it does not request another debit. An exact check-ID/response-byte retry returns the committed state. A provider that changes response bytes under the same check ID is rejected; a new observation of a changed provider state needs a new check ID and a higher sequence.
Consistency and remaining boundaries
The origin and provider are different systems. No local transaction can make remote revocation globally atomic. The adapter checks current published authority at the stated observation and transmission boundaries, and again after the response. An origin change that has not been observed cannot be claimed as already enforced. The separate history database and payment database also do not form one distributed transaction; the history guard establishes the locally highest revision at its read point. Signed historical records remain historical evidence, not current authority.
The TLS tests run two distinct origins (separate loopback ports) with actual sockets, certificates, signatures and SQLite state. They exercise successful confirmation and exact retry, scoped credential isolation, origin withdrawal/outage after the provider reply, wrong tenant/signature/amount, revoked keys, key rotation preserving earlier signed proof, revision rollback, missing payer authority and a delayed pre-transmission authorization check. The provider is a synthetic status server: this demonstrates the protocol adapter, not a commercial processor or bank settlement.
This adapter itself supplies read-only verification. The subsequent paid agreement service now connects it to signed offer acceptance, separate payer provisioning, tokens and protected delivery. Its transaction-bound ledger supplies register_commit_guard so verifier key/history and a new response’s 60-second freshness bound remain valid at the enclosing agreement commit. Exact historical checks remain read-only. Refund commands, closed paid-evidence migration and production deployment are separate boundaries; no provider-specific privilege or dependency is introduced into Odexa’s free path.