---
schema: foundry-doc-v1
title: "Crypto Payment and License Issuance Architecture"
slug: crypto-license-sales-architecture
category: architecture
type: topic
content_type: topic
quality: complete
status: active
audience: vendor-public
bcsc_class: no-disclosure-implication
language_protocol: PROSE-TOPIC
last_edited: 2026-06-13
editor: pointsav-engineering
paired_with: crypto-license-sales-architecture.es.md
short_description: "The payment and license architecture behind software.pointsav.com — a custodian-free flow from on-chain USDC transfer to Ed25519-signed download token, with no customer accounts and no payment intermediary."
cites: []
---

A software license purchase on `software.pointsav.com` flows from a Polygon USDC
transfer on-chain to an Ed25519-signed token that authorises binary downloads. The
design is custodian-free: the customer never creates an account, the vendor never holds
customer funds beyond the moment of settlement, and no intermediary is required to route
the payment. The architecture has three moving parts — a payment watcher, a storefront,
and a release server — described here at the level of their interactions.

## Why USDC on Polygon

USDC is a USD-pegged stablecoin issued by Circle. Its value is anchored to the US dollar,
which makes it practical for fixed-price software purchases without exposing either party
to exchange-rate volatility. Polygon PoS is a proof-of-stake EVM-compatible chain with
lower transaction fees than Ethereum mainnet, making it economical for purchases in the
single-digit dollar range. The payment system operates as a read-only observer of public
blockchain state: it watches for ERC-20 Transfer log events on the USDC contract addressed
to the vendor wallet. No vendor-side smart contract is required. Any blockchain explorer
can independently verify a payment using the transaction hash.

## Payment watcher mechanics

The payment watcher polls the Polygon JSON-RPC endpoint at a configurable interval,
walking forward through confirmed blocks and inspecting ERC-20 Transfer log entries. When
it finds a Transfer to the vendor wallet address, it inspects the transferred amount to
determine which license tier the payment corresponds to — the two tiers each map to a
distinct USDC amount. On each confirmed match, it writes a structured flat-file receipt
containing the transaction hash, the sender address, the block number, the confirmation
timestamp, and the derived product identifier. It also appends an entry to a JSONL
transaction log for bookkeeping and audit purposes.

Receipts are authoritative. The storefront will not issue a license token without a
matching receipt on disk. The two-stage design — watcher writes receipt, storefront reads
receipt — means the storefront never queries the chain directly; it delegates that
responsibility entirely to the watcher. The watcher also supports a fallback RPC URL for
resilience: if the primary RPC endpoint is unreachable, it retries against the fallback
before failing.

## Per-order address derivation

By default, all payments are directed to a single static vendor wallet address, and the
transaction hash serves as the order identifier. For customers who prefer a dedicated
receiving address for order tracking or accounting purposes, the storefront can derive one
from the vendor's BIP-39 master seed using BIP-32 hierarchical deterministic key
derivation along the standard Ethereum derivation path. Each order receives a unique index,
and the mapping from order identifier to derivation index is stored locally. Payments to
derived addresses are watched and receipted by the same watcher that monitors the static
address. The derived-address flow is optional; the standard single-address flow remains
the default.

## License token issuance

Once a receipt exists for a transaction hash, the storefront issues an Ed25519-signed
license token. The signing key is held exclusively by the storefront and never leaves it.
The corresponding public verification key is held exclusively by the release server.
Neither component holds the other's key material, and no key material is transmitted
to the customer.

The token payload records the product identifier, an expiry date (one year from the time
of issuance at current configuration), and the license tier as a list of entitlements.
The token is formed by prepending the 64-byte Ed25519 signature to the raw payload bytes
and encoding the result as a base64url string. The output is a single opaque string the
customer stores and presents to the release server.

## Verification at the release server

Verification is stateless and requires no network call. When a download request arrives
with a token, the release server base64url-decodes the string, splits off the first 64
bytes as the Ed25519 signature, verifies the signature over the remaining bytes using
the stored public key, parses the payload, and checks that the product matches the
requested product and that the expiry date has not passed. A mismatched product returns
403; an invalid signature returns 401; an expired token returns 403 with a reason string
indicating the channel has expired. Because the release server holds no signing key, a
compromise of the release server does not allow an attacker to mint new tokens.

The release server exposes the public verification key at a well-known endpoint. External
tooling — such as a customer's own installer script — can download the public key once
and subsequently verify tokens offline without contacting the release server at runtime.

## Receipt idempotency and the claim flow

The storefront's license issuance endpoint is idempotent: querying the same transaction
hash multiple times always returns the same token. If a receipt is already on disk, the
token is issued immediately. If not, the storefront delegates a chain lookup to the
payment watcher's check subcommand and, on confirmation, writes the receipt before issuing
the token. The first call for a new transaction may involve a chain round-trip; every
subsequent call is served from disk with no latency beyond local I/O.

A separate claim endpoint records an off-chain association between a binary SHA-256 hash
and the buyer's wallet address. This forms the basis for a future on-chain ownership
attestation. On-chain minting capability is planned for a future version of the system;
the claim record is written now so the data is available when that capability is added.

## See also

- [[software-distribution-substrate]] — overview of the three-component distribution system of which this architecture is the payment leg
- [[private-git-paid-customer-endpoint]] — how the release server handles token verification and binary delivery at the download endpoint
