Hartii Biome docs

Games

HPAY Request v1 and v2

HPAY Request v1 and v2 are the link formats behind the HPAY tools in Games/Biome. V1 continues to describe native QUAI requests. V2 binds the reviewed WQI token explicitly. Both ship in Games/Biome 1.27.0.

Everything here is non-custodial. The payer's own wallet signs, and the money goes straight from the payer to the address in the request. Hartii holds no keys, funds or balances, takes no fee, and the tools add no contract. The payer pays the normal network fee. The network is Quai mainnet, zone Cyprus-1, chain 9.

Request v1: native QUAI

A request is one link with a query string, normally on https://hartiibiome.com/pay:

text
https://hartiibiome.com/pay?to=<your 0x00 address>&amt=1500000000000000000&ref=order-1001&chain=9&v=1
FieldMeaningRules
toWho is paid. Required.A Hartii @name, or a Cyprus-1 Quai address (starts with 0x00). A mixed-case address must pass its checksum. Qi addresses and the zero address are refused.
amtExact QUAI amount in wei. Optional.Digits only, no leading zero, above 0 and below 10^27 wei (one billion QUAI). Without it the payer chooses the amount.
usdThe dollar price the QUAI amount was quoted at. Optional.Above $0 and at most $1,000,000.00, up to two decimals. Only valid together with amt in v1. It is a label on a quoted QUAI amount, never an instruction to convert.
refYour order reference. Optional.1 to 64 characters: letters, digits and . _ : -, starting with a letter or digit.
tagThe last digits of amt. Optional.1 to 9 digits, written as text (keep leading zeros). amt must end with it. A tag needs amt. A tag of all zeros is refused when a link is built. A tagged request needs a 0x address, not a name, because a name can change owner.
expWhen the request ends. Optional.Unix seconds, no later than 2100-01-01 UTC.
memoA note for the payer. Optional.Plain text, up to 140 characters. Display only; it is never written on the chain. Hidden and direction-changing characters are refused.
chainNetwork.9 when present.
vFormat version.1 when present or omitted.

Request v2: reviewed WQI token

A v2 link names the asset and the pinned ERC-20 contract rather than relying on a symbol or an amount to imply which asset is meant. A wire link looks like this (the contract is a public deployment address):

text
https://hartiibiome.com/pay?to=WQI:<recipient>&amt=<exact-WQI-base-units>&chain=9&v=2&asset=WQI&token=0x002b2596EcF05C93a31ff916E8b456DF6C77c750
FieldMeaningRules
toThe intended recipient.A v2 URL carries the WQI: marker before the recipient. The request is bound to the parsed recipient and cannot silently fall back to native QUAI.
amtExact WQI base units.Decimal digits, exact integer units, 18 decimals, positive and below 10^27 base units. The v1 decimal-QUAI amount alias is refused.
chainNetwork.9, Quai Mainnet, Cyprus-1.
vFormat version.2 for an asset-bound token request.
assetToken identity.Exactly WQI.
tokenToken contract.The reviewed contract 0x002b2596EcF05C93a31ff916E8b456DF6C77c750; the payer's page verifies the deployment and metadata before enabling payment.

WQI is an ERC-20 on Quai's account ledger, not native Qi. A WQI transfer sends the exact token units directly to the recipient. The payer needs QUAI separately for gas. HPAY does not request a token approval, perform a swap or wrap/unwrap Qi. It has no WQI dollar quote and makes no claim about a dollar peg, backing or reserves. The recipient must accept WQI; a reference or memo does not connect HPAY to a utility or other biller.

Compatibility: old PayLink readers continue to read valid v1 QUAI links. A v1-only reader must refuse a v2 WQI link because of its explicit WQI: recipient marker; do not strip the marker or token fields and retry it as QUAI. Use an updated reader that understands v2 or ask for a native QUAI request.

How a link is read:

  • Unknown keys are ignored. A repeated known key refuses the whole link, because two readers could disagree on which copy wins.
  • Any bad known field refuses the whole link. A bad value never half-applies.
  • Old PayLink links (to, amt, memo, exp, chain, v) remain native QUAI requests. The older v1 amount key (decimal QUAI, converted to exact wei) still works; giving both amt and amount is refused. An old v1-only reader must refuse the v2 WQI: marker rather than ignore token fields and interpret the link as QUAI.
  • Every refusal has a code and a plain sentence for the person. The repository publishes 107 shared test vectors that the Gallery copy and the CLI must pass unchanged.

A request is matchable (it can be tied to one payment on the chain) only with a fixed 0x address, an exact amt, a non-zero tag and an exp. A tag makes an order's exact amount distinguishable from other requests; it does not identify the payer or prove the order reference, memo or biller.

Pricing in dollars

http
GET https://hartiibiome.com/api/hpay/quote?usd=25.00

The answer is JSON with ok: true, version: 1, and these fields:

FieldMeaning
usdThe dollar price, as text with two decimals.
amountWei, amountQuaiThe QUAI for that price, exact. Rounded up to the wei, so the payee is never short.
quaiUsd, quaiPerUsdThe mean price the quote used, and its inverse.
issuedAt, expiresAt, ttlSecondsWhen the quote was made and when its lock ends. ttlSeconds is 900.
spreadPercent, maxSpreadPercentHow far apart the answering sources were, and the limit (2).
sourcesEach source with its name, price, time and age.

Rules, from the Function's code:

  • The dollar amount is 0.01 to 1,000,000.00 with up to two decimals. Nothing but that number is read.
  • Three price sources: MEXC (QUAIUSDT), Gate.io (QUAI_USDT, last trade, dated when it is read) and CoinGecko. At least two must answer, and every source that answers must be at most 5 minutes old and agree with the others within 2 percent. CoinGecko is an aggregate that can include the exchanges, so these are separate sources, not independent ones. USDT is treated as a dollar. The quote uses the mean of the answering prices.
  • If fewer than two answer, any answering source is stale, or they disagree, the answer is HTTP 503 with a reason and no quote. Nothing guesses a price.
  • The quote is locked for 15 minutes (expiresAt). The rates are cached at the edge for 30 seconds and a refusal for 10 seconds.
  • Pages that price in dollars check the answer again in the browser: at least two sources, the 2 percent limit and the arithmetic. An answer that fails any check is never shown as a price.

requestFromQuote(quote, { to, ref, tag, memo }) in hpayRequest.mjs turns a quote into a request that ends when the quote does. generateTag makes a 6 digit tag by default, never all zeros, and tagAmount adds the tag to a price by raising it by at most 10^digits - 1 wei (under a billionth of a QUAI at nine digits).

The dollar figure in a link is the link maker's own price. The chain only records QUAI.

Price history for statements

http
GET https://hartiibiome.com/api/hpay/history?from=<unix>&to=<unix>

The hourly QUAI dollar price, for Statements and bookkeeping. It is not a quote. There is no historical WQI price endpoint.

  • One source, labelled: MEXC QUAIUSDT hourly candles, the price at the start of each hour.
  • At most 1000 hours per call, not before 2025-01-01, and not more than an hour ahead.
  • An hour with no candle has no price. It is left out, and a page shows a dash, never 0.

Matching a payment to a request, with no contract

A matchable request can be matched on the chain. A payment counts only if all of this is true, judged on the Quai node's own answers:

  1. the transaction succeeded (receipt status 1);
  2. for v1, the money went to the request address as a plain QUAI transfer or QuaiRelay send; for v2, the transaction calls the pinned WQI contract with an exact transfer and its receipt contains the one matching WQI Transfer event;
  3. the exact amount is amt in the request's asset (QUAI wei in v1, WQI base units in v2);
  4. the block time is inside the window from when the request was made to exp (a start time more than 5 minutes in the future is refused);
  5. it is the earliest such payment, and it has enough confirmations.

The result is paid, pending, unmatched or expired. A payment that looks related but fails a rule goes to an unmatched list for a person to look at and is never marked paid:

ReasonMeaning
wrong-amountA successful payment in the window within 2 percent of the amount, but not equal.
lateThe exact amount, after the expiry.
duplicateThe exact amount again, after the one that paid.
ambiguousThe exact amount, but another open request has the same payee and amount.
unverifiedThe exact amount, but the node could not confirm it, or it was a contract call, not a transfer.

A transfer that failed on the chain moved no money and is ignored.

Where the data comes from:

  • Native QUAI plain transfers are found through Quaiscan. QuaiRelay sends are found through the node's Relayed(from, to, amount) events, because Quaiscan lists no internal transfers on Quai. WQI history scans Transfer events from the pinned contract through the Quai node, then checks each candidate against the transaction, receipt, event and canonical block. It is a direct token transfer, not a Relay send.
  • Quaiscan only discovers. Each candidate is read again from the node, and where the two disagree the node wins.
  • A source that fails is reported as a gap. It is never read as "no payment". A latest block that cannot be read can never reach paid.
  • WQI scans are bounded by block windows and candidate rows. Older history or node read gaps may be missing; the page reports coverage rather than calling an incomplete read empty. A Quaiscan that is more than 60 blocks behind the node, or cannot say, makes a native-QUAI answer incomplete, so "Expired" is not final.

Confirmations. The default is 12, a placeholder until finality on Quai has been measured on mainnet. The library takes 1 to 1000. Each tool lets the person or the shop set it (see each tool for its range).

Honest limits

  • Beta.
  • Plain transfers are discovered through Quaiscan. When it is down, the page says what is missing and does not report an empty list as a fact.
  • Dollar prices for payments need at least two sources that agree. Dollar values on statements come from one source and are not a quote.
  • Wrong, late and duplicate payments are listed for a person to handle. Any refund is done by the payee. HPAY never moves money back.
  • WQI never has a historical dollar value in HPAY. A WQI amount is not a dollar peg or proof of backing. Only QUAI requests use the dollar quote and hourly QUAI price history described above.

Unknown wallet outcomes and merchant checks

The payer's browser keeps an unknown payment hold locally and restores it after reload. A new person-payment intent does not bypass the hold. If the wallet returned a unique original transaction hash, the page can check that exact transaction. If the wallet did not return a unique hash, a typed hash is only a read-only candidate: matching payer, recipient, asset and amount (or an approximate time) cannot prove it was the unknown invocation or clear its hold. Keep the hold and check the original wallet activity; do not blindly send again.

For a still-valid fixed bill, only a node-proven status-0 receipt for the exact original transaction permits a fresh review of that same request identity. A confirmed, unknown or expired request does not become a new payment. This browser recovery state is not a wallet nonce, a signature, or a server-side order ledger.

The recovery check also binds the original plain/relay/token payment model and compares the decoded payment's block hash with a freshly read raw receipt and canonical block. Terms that happen to match in a different model or block cannot resolve the original invocation. Local records and Web Locks apply only on that browser origin: moving between Biome and dedicated HPAY does not transfer a record or lock. Check the original domain first.

For a shop integration, create and retain the request and createdAt on your server, then run verifyPayment for the transaction hash. For v2, verify the canonical WQI contract and exact event as well as the request window and confirmations. Store each accepted hash with its order so the same transaction cannot pay two orders. A popup hash or browser's Confirmed message is a hint, not an order decision; the merchant's own order and accepted-hash checks remain necessary. HPAY adds no server, signing API or MCP payment tool for this.

Quai Network mainnet · chain 9 · Cyprus-1. Figures marked "read on" a date were read from the chain that day; re-read before relying on them.