https://usetendr.tech/pay/<your-store>/<link>. The payer opens it,
sees what they are paying for, and presses Pay. Tendr then opens the normal checkout, so everything
else works as it does for a session your own site creates: quotes, gasless payments, refunds, webhooks
and payouts to your account. Tendr never holds the money.
Make links with the API (POST /v1/payment_links, see the reference),
the TypeScript SDK or the dashboard.
Kinds of link
An open link can set
min_amount to raise its floor. It cannot lower it.
Currencies and the $1 minimum
A link is priced inUSD or in an ISO 4217 currency Tendr has a rate for (for example EUR, NGN,
JPY). The order is converted to USD when the payer presses Pay, and the currency’s own decimals apply
(JPY has none).
Every link takes at least $1.00 USD equivalent, checked on the link amount before fees:
- A fixed amount is checked when you create or edit the link, and again when the payer presses Pay, because rates move. A link priced near the floor can start refusing payments later.
- An open amount is checked when the payer presses Pay. The page shows the effective minimum: the larger
of your
min_amountand the $1.00 floor in the link’s currency. - Below the minimum the API answers
400 AMOUNT_TOO_LOWwithdetails.min_amount. - When a non-USD rate is not available the API answers
503 FX_RATE_UNAVAILABLE. Try again shortly.
Who pays the fees
fee_payer and gas_payer are optional on a link. Leave them unset (null) and the link follows your
store defaults. Set them and they apply to every payment through that link. gas_max_usd caps the
network fee Tendr will sponsor for the link. A session’s own setting still wins when your code creates
the session. See gasless payments and the gas policy.
The payer’s note
Withnote: "optional" (the default) the payer can leave a short message with the payment. Set
note: "off" to hide the box.
- At most 280 characters of plain text. Control characters are removed and whitespace is collapsed.
- It is stored on the session and returned as
payer_noteon every session event (see webhooks). It is always shown as text and links in it are never clickable. - The email you get for a payment names the link and quotes the note.
Test mode
Test and live links are separate. A link made with a test key has aurl that ends in ?mode=test.
Without ?mode=test only live links resolve, so a test link never answers on the live address. Test
links use test checkout: no real money moves.
QR codes and preview cards
Each link has a QR code at itsqr_url: /pay/<store>/<link>/qr (PNG, 1024 px). Add format=svg for
SVG. It encodes the link’s address, including ?mode=test for a test link.
Pasting the link into a chat or a social post shows a 1200 x 630 preview card with your store name, the
title, the price and your logo. The logo appears only when Tendr hosts it; otherwise the card shows your
store’s initial.
Switching off, archiving, limits
A link is never deleted: its payments and totals stay. The
slug is part of the shared address and
cannot be changed after creation. To retire an address, archive the link and make a new one.
PATCH accepts null to clear expires_at, max_uses, description, min_amount, fee_payer,
gas_payer and gas_max_usd. Omit a key to leave it as it is. Unknown keys are rejected.
How max_uses works
max_uses is safe for single-use invoices. Every open session reserves one use, so two payers
cannot both start paying a link that has one use left. A session waiting for its deposit holds the use
until it expires. Once the deposit has arrived, the session holds the use until the payment settles or
fails, even if that runs past the session’s expiry.
- While a payer is mid-payment on the last use, a second payer gets
409 LINK_RESERVED: “Someone is paying this link right now, try again shortly.” If that session expires without a deposit, the use is free again. - When every use has settled, new payers get
409 LINK_UNAVAILABLEwithavailability: "used_up". - A session started from the page lives 5 minutes until the payer gets a quote, then the normal session lifetime. A payer who walks away frees the use after those 5 minutes.
- Late deposits (money that arrives after the session is marked expired) are refunded and never count as a use.
- Refunds do not free a use. A refunded payment stays used.
use_countcan exceedmax_usesin one narrow case: a session that is past its expiry but not yet swept receives a deposit that settles. A deposit that lands in the same millisecond the session expires can do the same, because its use was already released to the next payer.
429 LINK_BUSY. Sessions that have no quote yet do not count: they expire within minutes.
Totals
Every link read returns:
Only settled payments count towards
total_paid. A refund counts towards total_refunded once it has
executed on chain. To list the payments of one link, use GET /v1/payments?payment_link_id=<id>.
Who cannot use links
A store that settles into its own contract (an integrator with payout modewallet) takes payments
through hooks instead. Creating a link for it returns 409 LINK_NOT_SUPPORTED.
What the payer sees
- Your store name and logo, the title, the description, and the price (or an amount box).
- If the link is not available, a short reason (switched off, expired, used up) and no Pay button.
- A note box when
noteisoptional. - Pay creates the session and sends the payer to the hosted checkout to choose a token and send.
- After payment, the success screen links back to the payment link page.

