Produtos e links de pagamento
Um link de pagamento é uma página pública de cobrança que a Lezty Pay hospeda por você. Você cadastra um produto (nome, preço), cria um link que aponta para ele e divulga a URL. Cada comprador que abre o link informa os próprios dados e recebe uma cobrança PIX nova, a página confirma o pagamento sozinha, e o seu sistema fica sabendo pelo mesmo webhook de sempre.
Não há nada para integrar do lado do comprador. A API serve para quem quer criar produtos e links por código; o painel oferece as mesmas operações na tela Checkout.
O que existe hoje: produto e link em BRL (PIX e cripto) e em euro, dólar e libra (cartão), limite de uso, validade, taxa por conta do comprador e endereço de retorno. Ainda não estão disponíveis: imagem do produto e entrega automática de arquivo, listados no fim desta página, em "Em breve".
Criar um produto
O produto é o que se vende: nome, descrição opcional e preço em centavos. A moeda é BRL, EUR, USD ou GBP; os links em euro, dólar e libra
estão na seção "Links em euro, dólar e libra", mais abaixo.
#!/usr/bin/env bash
# Cria um produto. Precisa de LM_API_URL e LM_API_KEY no ambiente.
# export LM_API_URL=https://api.leztypay.com
# export LM_API_KEY=sk_test_...
# Criar produto não é operação financeira: sem Idempotency-Key.
set -euo pipefail
curl --fail-with-body -sS "$LM_API_URL/v1/products" \
-H "Authorization: Bearer $LM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Curso X",
"description": "Acesso ao curso completo",
"price": 10000
}'
A resposta é o objeto product, com id no formato prd_.... Produto não é apagado: para tirar
de venda, edite com Edita um produto (chave de API) e mande "for_sale": false. Os links dele passam a
responder que o produto não está à venda. A moeda não muda depois de criado.
Em produção, o preço precisa ficar acima da taxa que a sua conta paga, senão a criação responde
400 amount_too_small. As taxas da sua conta estão na tela de taxas do painel.
Criar um link
O link aponta para um produto da mesma conta e do mesmo ambiente. Só product_id é obrigatório.
#!/usr/bin/env bash
# Cria um link de pagamento para um produto seu (o id vem da resposta de links-create-product.sh).
# Precisa de LM_API_URL e LM_API_KEY no ambiente. Sem Idempotency-Key: não é operação financeira.
set -euo pipefail
curl --fail-with-body -sS "$LM_API_URL/v1/payment-links" \
-H "Authorization: Bearer $LM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_id": "prd_01j0000000000000000000000",
"return_url": "https://loja.exemplo.com/obrigado",
"buyer_pays_fee": false,
"max_uses": 100,
"expires_at": "2027-01-31T23:59:59-03:00"
}'
Criar produto e link não é operação financeira, então não leva Idempotency-Key. Criar duas
vezes cria dois objetos.
A resposta é o objeto payment_link. Os campos que importam:
url: o endereço pronto para divulgar. Oslug(10 caracteres) é gerado por nós e não pode ser escolhido nem alterado.active:falsetira o link do ar sem apagar nada. Não existeDELETE.titleedescription: o que a página mostra. Se você não mandar, valem o nome e a descrição do produto.product: um resumo do produto (id,name,currency,price,for_sale).stats: os números do link (abaixo).
Edita um link de pagamento (chave de API) muda qualquer campo menos product_id. Para vender outro produto,
crie outro link: assim o total de um link sempre quer dizer a mesma coisa. Enviar null em
return_url, max_uses ou expires_at limpa o campo.
stats
Aparece sempre em GET /v1/payment-links/{id} e, na listagem, com with_stats=1.
| Campo | O que é |
|---|---|
paid_count |
Cobranças pagas do link |
paid_amount_total |
Soma do que os compradores pagaram, em centavos |
paid_net_total |
Soma do líquido que ficou para você, em centavos |
pending_count |
Cobranças aguardando pagamento |
remaining_uses |
Vagas livres. null se o link é ilimitado; pode ficar negativo se você baixar max_uses depois |
over_limit_count |
Vendas que passaram do limite (ver abaixo) |
A listagem aceita os filtros active, product_id e q (título ou slug), além da paginação por
cursor de Paginação.
O que o comprador vê
O comprador abre a URL, vê o nome, a descrição e o valor, preenche nome, e-mail e documento e
confirma. A página cria uma cobrança PIX nova só para ele, mostra o QR Code e fica consultando o
status até o pagamento entrar. Se o link aceita cripto, o comprador escolhe entre PIX e cripto (a moeda,
USDT ou USDC, e a rede) antes de pagar; ver Link com cripto. Pagou, a página mostra a confirmação e, se o link tem return_url,
oferece o botão de voltar para a sua loja.
Quem define o valor é o link, nunca o comprador. O que ele informa é só quem ele é.
Se o link não puder vender, a página diz o motivo: desativado, expirado, esgotado ou produto fora
de venda. Quem tenta criar a cobrança nesses casos recebe 409 com o code
payment_link_inactive, payment_link_expired, payment_link_sold_out ou product_not_for_sale.
Link com cripto
Por padrão o link aceita só PIX. Para aceitar também USDT e USDC, marque accepted_methods: ["pix", "crypto"]
ao criar ou editar o link. pix precisa continuar na lista, e cripto vale só para produto em BRL
e link sem buyer_pays_fee; fora disso é 400 validation_failed com param: accepted_methods. A
opção só aparece para o comprador quando você tem carteira utilizável (bsc ou polygon, que também vale em arbitrum e optimism, fora da
carência de 48 h) e o preço do produto é de pelo menos US$ 5; abaixo disso o link mostra só PIX. No
link, o documento do comprador é opcional em cripto. A cobrança criada pelo link segue as regras de
Cobrança em cripto: taxa de 4% + US$ 0,50, repasse direto, sem estorno.
A moeda não é configurada no link: o comprador escolhe entre as que estiverem prontas. Quem monta
a própria página lê o bloco crypto de GET /pay/v1/links/{slug}:
"crypto": {
"coins": ["usdt", "usdc"],
"offers": [
{ "coin": "usdt", "networks": ["bsc", "polygon", "arbitrum"], "min_usdt": 500, "amount_usdt_estimate": 1852, "price_brl_per_usdt": "5.400000" },
{ "coin": "usdc", "networks": ["polygon", "arbitrum", "optimism"], "min_usdt": 100, "amount_usdt_estimate": 1853, "price_brl_per_usdt": "5.400000" }
],
"networks": ["bsc", "polygon", "arbitrum"],
"min_usdt": 500,
"amount_usdt_estimate": 1852,
"price_brl_per_usdt": "5.400000"
}
coinslista só as moedas oferecidas agora; uma moeda cuja cotação ou cujo mínimo da rede não atendem some da lista.offerstraz, por moeda, as redes prontas, o piso e a estimativa. Useoffers: os campos planos (networks,min_usdt,amount_usdt_estimate,price_brl_per_usdt) descrevem só a primeira moeda pronta (o USDT, quando ele está pronto) e ficam por compatibilidade.- Os campos
*_usdtsão centavos de dólar da moeda do item (USDC vale US$ 1, como o USDT). - Para criar a cobrança, envie
crypto.networke, se for USDC,crypto.coin: "usdc"emPOST /pay/v1/links/{slug}/charges. Semcoina cobrança é em USDT.
Links em euro, dólar e libra
Crie o produto com currency em EUR, USD ou GBP e o preço em centavos dessa moeda. O link desse
produto cobra por cartão. MB WAY, Apple Pay e Google Pay (carteiras, só em euro) ainda não estão
disponíveis. Em moeda estrangeira não há PIX no link.
accepted_methodsdo link é["card"].walletsó vale emEURe ainda não está disponível; fora disso é400 validation_failedcomparam: accepted_methods.- A página mostra só os métodos que estão ligados na sua conta naquela moeda. Sem nenhum disponível, o
link responde que não pode vender agora (
payment_method_unavailable), em vez de quebrar. - O comprador informa nome, e-mail, telefone, país e documento. O cartão é digitado na página da Lezty Pay e vai direto ao adquirente: você não integra nada. Se o banco pedir 3DS, a página leva o comprador até ele e volta sozinha.
buyer_pays_feeesplits[]não valem em moeda estrangeira.- A cobrança criada pelo link segue as regras de Cartão internacional: confirmação só pelo webhook, saldo internacional em reais e saque em USDT, sem estorno pela API.
Quem monta a própria página lê payment_methods, wallets, card_session_required e
country_required em GET /pay/v1/links/{slug}, abre a tokenização com
POST /pay/v1/links/{slug}/card-session (atrás do mesmo token anti-robô da cobrança) e cria a cobrança
com payment_method: "card" e card.token.
Limite de uso e validade
expires_até a validade do link. Depois dela, a página mostra "expirado" e a criação de cobrança é recusada. Quem já estava pagando uma cobrança criada antes não é cortado.max_useslimita pagamentos, não aberturas da página. Uma cobrança aguardando pagamento reserva uma vaga enquanto estiver aguardando. Se ela expirar sem pagar, a vaga volta.- Estorno e chargeback não devolvem a vaga: você vendeu. Se quiser vender mais, suba
max_uses. - A cobrança de um link vale, no máximo, 30 minutos, ou menos se o processador de pagamentos expirar antes.
O limite não estoura por concorrência: dois compradores disputando a última vaga resultam em um
pagamento e um 409 payment_link_sold_out.
Pagamento tardio é a exceção. O PIX de uma cobrança que já expirou pode ainda ser pago, e nesse
caso a venda vale: o dinheiro entrou. Se isso acontecer com o link já cheio, a transação fica
marcada como acima do limite (payment_link.over_limit é true, e stats.over_limit_count conta
quantas) e você decide se estorna ou honra a venda.
Taxa por conta do comprador
Com buyer_pays_fee: true, o valor cobrado do comprador sobe o suficiente para cobrir a taxa, e
você recebe líquido igual ao preço do produto, com no máximo 1 centavo de sobra, que fica com você.
Quanto é a taxa, não está nesta página: ela depende das condições da sua conta, que estão na tela
de taxas do painel. A resposta de criação da cobrança já traz fee, net e o valor final.
A cobrança carrega as duas parcelas em items, que é o que você vê no painel e no webhook:
"items": [
{ "name": "Curso X", "quantity": 1, "unit_amount": 10000 },
{ "name": "Taxa de serviço", "quantity": 1, "unit_amount": 99 }
]
(O segundo valor é só ilustrativo.) amount da cobrança é a soma das duas linhas.
buyer_pays_fee só vale em BRL. Se o preço mais a taxa passar do teto de uma cobrança, a criação ou
a edição do link responde 400 amount_too_large.
O retorno não é prova de pagamento
Se o link tem return_url, depois do pagamento a página mostra o botão "Voltar para" com o domínio
de destino. Ao clicar, o comprador chega na sua loja com transaction_id e status=paid na URL.
Trate isso como uma conveniência de navegação, nunca como confirmação. Qualquer pessoa pode digitar essa URL na barra do navegador. A prova de que o pagamento aconteceu é:
- o webhook
transaction.paid(ver Webhooks), ou Consulta uma cobrançadevolvendostatus: "paid".
Libere o pedido por um dos dois. Use o transaction_id da URL só para saber qual cobrança consultar.
A return_url precisa ser https, com um domínio público (nada de IP, localhost ou endereço
interno), sem usuário e senha e sem #. Fora disso a resposta é 400 invalid_url. A página nunca
redireciona sozinha antes do pagamento, e no ambiente de teste não redireciona sozinha em momento nenhum.
payment_link na cobrança e nos webhooks
Toda cobrança que nasceu de um link traz o campo payment_link; as demais trazem null. Ele
aparece em Consulta uma cobrança, nas listagens e no data.object dos webhooks
transaction.*.
"payment_link": {
"id": "plk_...",
"slug": "7k3m9qx2ab",
"product_id": "prd_...",
"over_limit": false
}
É um campo novo e aditivo: integrações que não o conhecem continuam funcionando. Use product_id
para saber o que foi vendido e id para saber por qual link. O metadata da cobrança não é
usado pelos links.
Para listar só as vendas de um link:
#!/usr/bin/env bash
# Lista só as cobranças que nasceram de um link de pagamento.
# LM_PAYMENT_LINK_ID=plk_01j... ./links-list-transactions.sh
set -euo pipefail
curl --fail-with-body -sS "$LM_API_URL/v1/transactions?payment_link_id=$LM_PAYMENT_LINK_ID" \
-H "Authorization: Bearer $LM_API_KEY"
Um payment_link_id malformado é 400 validation_failed.
Ambiente de teste e prévia
Com uma chave sk_test_, produto e link nascem no ambiente de teste e só geram cobrança de teste,
paga pelos gatilhos. Mas a URL pública de um link de teste não abre para
qualquer pessoa: sem um token de prévia ela responde 404, igual a um slug que não existe. Isso
impede que alguém use uma conta de teste para montar uma página de cobrança com a nossa marca.
O token de prévia sai do painel, no botão "Abrir prévia" do link (vale 1 hora, só para quem está
logado na conta). A API que o emite, POST /v1/me/payment-links/{id}/preview, só aceita sessão do
painel, não chave de API. A prévia é a forma de ver o fluxo inteiro sem dinheiro.
Limites e erros
As rotas de gestão seguem os limites de Limites: 60 requisições por minuto em escrita e
600 em leitura, por chave. O envelope de erro é o de Erros. Os code próprios dos links:
| Quando | Resposta |
|---|---|
| Corpo ou campo inválido | 400 validation_failed |
return_url fora da regra |
400 invalid_url |
| Preço fora da faixa da moeda | 400 amount_too_small ou 400 amount_too_large |
buyer_pays_fee não calculável para o preço |
400 buyer_fee_not_computable |
| Conta sem permissão de cobrar neste ambiente | 403 seller_not_allowed |
| Criação e edição suspensas temporariamente (as consultas seguem funcionando) | 403 feature_disabled |
| Produto, link ou id de outra conta ou de outro ambiente | 404 resource_not_found |
| Link desativado, expirado, esgotado ou produto fora de venda | 409, com o code correspondente |
| Muitas cobranças em aberto no mesmo link | 429 payment_link_busy, com Retry-After |
Erro de validação não cria nada: corrija e repita.
Uso avançado: a API que a página consome
A página de pagamento é um cliente comum de uma API pública, sem autenticação, em /pay/v1/*. Ela
está na referência sob a tag "Página de pagamento (público)" e existe para quem
precisa montar a própria tela. Para quase todo mundo, a URL do link resolve.
Carrega o link de pagamento: carrega o link e devolve só o que a página precisa (nome, valor, taxa do comprador, estado, nome de exibição do vendedor). Fora do estadoactive, devolve só o estado.Cria a cobrança do link: cria a cobrança do comprador. ExigeIdempotency-Keye um token de verificação anti-robô no headerX-Captcha-Response. O corpo aceita apenascustomeretracking: valor, moeda e itens vêm sempre do link, e qualquer outro campo é400.Acompanha a cobrança: acompanha a cobrança, com o headerX-Pay-Tokenrecebido na criação. Nunca devolve dados do comprador nem taxa.
Esses endpoints têm limites por IP e por link, e usam um token que só serve para acompanhar aquela cobrança. Não os use como substituto da API com chave: para saber se pagou, o caminho continua sendo o webhook.
Em breve
Estes recursos ainda não estão disponíveis. Quando forem, cada um ganha a própria página:
- Imagem do produto
- Entrega automática de arquivo depois do pagamento
Referência: Cria um produto (chave de API), Cria um link de pagamento (chave de API) e Cria uma cobrança (PIX, voucher, cripto, cartão ou carteira) para a
cobrança direta, sem link.