Começar
Link de pagamento
Uma chamada, uma URL: cobre sem construir checkout, sem tocar em cartão.
O caminho mais curto entre "tenho um produto publicado" e "alguém me pagou". Você cria um link, manda pra pessoa, e acabou — não tem checkout pra construir: sem página de pagamento, sem input de cartão, sem SDK de provedor no seu app, sem escopo PCI.
Antes: duas coisas que o link exige
const link = await infi.links.create(productId, { slug: "seu-tenant" });
link.url;
// https://app-sandbox.beinfi.com/pay/seu-tenant/links/plink_… ← manda isso
// (com sk_live_ o host é app.beinfi.com)Essa linha só funciona se as duas peças abaixo existirem — as duas vêm de catálogo:
| Peça | De onde vem |
|---|---|
productId | products.create() (ou products.list()). O productId do provisionamento é do produto seed, que não serve |
| Versão publicada do produto | products.versions.publish(...) — sem isso, links.create responde 422 product has no published version |
O slug é o do seu tenant e entra na URL pública, então ele é argumento: o SDK não
deduz isso de uma secret key.
O que acontece quando alguém abre
O link não tem pagador. Quem abre preenche os próprios dados e paga; o cliente e a fatura são materializados no submit. Isso é o que permite mandar o mesmo link pra várias pessoas — ou pra um grupo — sem cadastrar ninguém antes.
Quem recebe o dinheiro é a sua conta no provedor. Qual provedor processa é decidido pelo Infi Routing no momento do pagamento, não na criação do link.
Pix e boleto exigem CPF/CNPJ do pagador
O provedor recusa criar o pagador sem documento: a cobrança para em
422 customer_tax_id_required ("A CPF/CNPJ is required to process this payment").
Vale pra Pix e boleto. Se você montar o checkout no seu app em vez de usar o
link, passe taxId junto do cliente:
infi.checkout({ slug, productId, customer: { externalId, email, taxId } }).
Pra onde o pagador vai depois
Por padrão ele fica no nosso recibo. Se você quer o pagador de volta no seu site, passe as URLs na criação do link:
const link = await infi.links.create(productId, {
slug: "seu-tenant",
successUrl: "https://seu-app.com/obrigado?order=42",
cancelUrl: "https://seu-app.com/carrinho",
});Depois de pagar, o checkout leva o pagador pra
successUrl com ?status=success&invoice=<id> anexado — os seus parâmetros
ficam. cancelUrl aparece como "Voltar para {sua loja}" enquanto o checkout
está aberto. As duas precisam ser URL absoluta http(s); caminho relativo ou
qualquer outro esquema responde 422.
O mesmo par existe em infi.checkout({ successUrl, cancelUrl }) pra faturas
criadas no seu servidor, e no embed (@beinfi/checkout) o equivalente é a prop
returnUrl.
Redirect não é confirmação
status=success na URL é um evento do navegador do pagador. Libere o produto no
webhook payment.confirmed, nunca pelo parâmetro.
Listar e revogar
await infi.links.list(productId, { slug: "seu-tenant" });
await infi.links.revoke(productId, link.id);Revogar é definitivo
O token para de resolver na hora. Faturas que já saíram daquele link continuam pagáveis — quem estava no meio do checkout não perde a cobrança que tem em mão.
E como eu sei que pagaram?
Não é pelo retorno de links.create: pagamento é assíncrono. Em produção, webhook
assinado (payment.confirmed); em sandbox, polling da fatura — os dois em
webhooks.
Quando usar o link e quando não
Use o link
Venda pontual, cobrança por WhatsApp, primeira venda antes de ter app.
Use metering
Cobrança por uso contínuo (tokens, requests), onde o valor só existe depois que o cliente consumiu — veja SDK.
Se você quiser controlar a tela mesmo usando link
O fluxo do comprador por HTTP — abrir sessão, cobrar, e onde a fatura aparece — está em a página de obrigado.