Merchant endpoints
Each call acts on the mode of the key or dashboard session that makes it.
Who can call
- A secret key needs the
payment_links:readscope to read andpayment_links:writeto create, change or archive. - In the dashboard, reading needs
account:readand writing needsmoney:request. No step-up is needed. - Publishable keys and shopper sessions are refused.
POSThonours theIdempotency-Keyheader, see idempotency.
The link object
Create
POST /v1/payment_links. Unknown fields are rejected.
List
GET /v1/payment_links?status=active&include_archived=false&limit=20&starting_after=plink_...
Returns { "data": [link, ...], "has_more": boolean }, newest first. limit is 1 to 100 (default 20).
Archived links are left out unless include_archived=true. Pass the last id as starting_after for
the next page.
Update
PATCH /v1/payment_links/:id with any subset of the create fields, plus archived (boolean).
nullclearsexpires_at,max_uses,description,min_amount,fee_payer,gas_payerandgas_max_usd. An omitted key is unchanged.slugcannot be changed: the request is a400.- Switching
amount_typeclears the fields that no longer apply. - Changing
currencyon a fixed link needs the newamountin the same request (else400, fieldamount). On an open link it clearsmin_amountunless you send a new one. - A change that touches the fixed amount or currency is re-checked against the $1.00 minimum.
Archive
DELETE /v1/payment_links/:id archives the link and returns it. Restore it with
PATCH { "archived": false }.
Public endpoints
The pay page at/pay/<store>/<link> uses two endpoints that need no key. They are documented so you
know what the payer’s page does; they are not an integration surface. Browsers can call them only from
Tendr’s checkout origin (CORS), so a page on your own site cannot use them. To take a link’s payment
from your own page, create a session with your secret key (POST /v1/checkout/sessions with
payment_link_id). Add ?mode=test to address a test link.
Read a link
GET /v1/payment_links/public/:merchant/:link
minor_unitsis the currency’s decimal places. Format and check amounts with it.usd_rateis1 USD = X currency, null for USD or when no rate is available.min_amount(open links) is the effective minimum, rounded up to the currency’s decimals.- An archived link reads as
inactive. No ids, use counts or limits are returned. - An unknown store and an unknown link give the same
404 NOT_FOUND.
Pay
POST /v1/payment_links/public/:merchant/:link/sessions
amount is required for open links and ignored for fixed ones. note is cleaned and capped at 280
characters, and ignored when the link has note: "off". The answer is 201:
url. expires_at is the session’s expiry at creation (5 minutes until its first
quote, then the normal session lifetime); the page uses it to offer “Continue your payment” to a payer
who comes back. The session has no external_ref. Responses are never cached.
Limits
Past a rate limit the API answers
429 RATE_LIMITED.
Errors
Creating a session for a link from your server
POST /v1/checkout/sessions accepts payment_link_id. The session takes the link’s fee and gas
settings, counts towards its max_uses, and keeps the expiry and external_ref you give it. Every
session event then carries payment_link_id, see webhooks.
