Reference
Payment requests
The format of Tenrai payment URIs and payment requests for links and QR codes. Schemes, the amount and payload parameters, and what wallets refuse.
A payment URI names an address. A payment request adds an amount, a payload or both. Wallets read either from a link, a pasted text or a QR code. The format is TCC-0006 of the conventions.
trai:trai1…
trai:trai1…?amount=1.5
trai:trai1…?amount=12.50&payload=Invoice%2042Schemes
| Network | Scheme |
|---|---|
| Mainnet | trai: |
| Testnet, Testnet100 | trai-test: |
| Development | trai-dev: |
The address must belong to the scheme's network. A wallet on another network refuses the request.
Parameters
| Parameter | Value |
|---|---|
amount | TRAI as a decimal with up to 8 places, above zero. 1.5, not atoms |
payload | Text the payer's wallet sends along as the payment's payload, percent-encoded. For an order or invoice number |
Rules a reader enforces:
- Parameters need a scheme. A bare address with
?amount=is refused. - Only
amountandpayloadexist. Any other parameter, or one given twice, makes the whole request invalid. - The whole text is at most 640 characters.
Payload characters
The payload of a request may hold letters and digits of any script, spaces, and these signs:
. , : ; - _ / # + ( ) ! ? % @ * &No space at either end, and at most 128 bytes of UTF-8. That is enough for a reference and leaves nothing a page could run or hide, so a QR code cannot carry markup or invisible characters into a payment.
This limit applies to requests only. A payment's own payload may be any bytes up to 1,024.
With the SDK
import { paymentRequest, parsePaymentRequest } from "@tenrai/sdk/wallet";
import { parseTrai } from "@tenrai/sdk";
const uri = await paymentRequest("trai1…", "mainnet", parseTrai("12.50"), "Invoice 42");
// trai:trai1…?amount=12.5&payload=Invoice%2042
const request = await parsePaymentRequest(uri, "mainnet");
// { address: "trai1…", amount: 1250000000n, payload: "Invoice 42" }parsePaymentRequest also accepts a bare address or a plain payment URI; amount and payload are then null.
Matching the payment
The payload arrives with the payment. A shop that hands out one request per order finds the order in payload_text of the incoming payment. Still compare the amount, and treat the text as input from a stranger: escape it before display.
