Links de pagamento
Um Payment Link é uma página de checkout hospedada e compartilhável (URL com assinatura) para vender
Um Payment Link é uma página de checkout hospedada e compartilhável (URL com assinatura) para vender um ou mais itens. Você cria, consulta, lista, atualiza e remove links como um recurso persistente.
| Operação | Método | Endpoint |
|---|---|---|
| Criar | POST | /v1/checkouts/payment-links |
| Listar | GET | /v1/checkouts/payment-links |
| Consultar | GET | /v1/checkouts/payment-links/{paymentLinkId} |
| Atualizar | PUT | /v1/checkouts/payment-links/{paymentLinkId} |
| Excluir | DELETE | /v1/checkouts/payment-links/{paymentLinkId} |
Todas as requisições usam o header SelectKey (veja Autenticação).
O ID público de um link tem o prefixo link_.
Criar
POST /v1/checkouts/payment-links
curl -X POST "https://api.selectwin.io/v1/checkouts/payment-links" \
-H "SelectKey: sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
-H "Content-Type: application/json" \
-d '{
"name": "Black Friday PIX",
"items": [ { "id": "var_01hqzvabc", "quantity": 1 } ],
"editable": false,
"expiresAt": "2026-12-31T23:59:59Z"
}'Campos da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome de exibição (1–255 caracteres) |
items[] | array | Sim | Itens do link: { id, quantity } (1–100 itens). id é a variante (var_... ou prv_...); quantity é inteiro ≥ 1 (default 1, máx. 100000) |
discounts[] | array | Não | Códigos de cupom pré-aplicados (strings, 1–50 caracteres cada, máx. 20). A validação/retenção autoritativa acontece na cobrança |
customInputs[] | array | Não | Campos de formulário customizados (objetos livres, máx. 50) |
expiresAt | datetime | Não | A partir deste instante o link não pode mais ser usado |
availableAt | datetime | Não | Instante a partir do qual o link passa a valer |
editable | boolean | Não | Permite o cliente editar quantidades na página (default false) |
templateId | string | Não | Template de checkout para visual (tmpl_... ou ckt_...) |
domainId | string | Não | Em que domínio a accessFullUrl é montada (veja abaixo) |
integrationId | string | Não | A integração (app_...) a que uma venda por este link pertence (veja abaixo) |
metadata | object | Não | Metadados livres |
Não há mais campo
type. O antigo link "static" foi removido; existe apenas um tipo de link (persistido). Umtypeenviado por clientes antigos é silenciosamente ignorado.
domainId — o domínio do link
domainId escolhe o host da accessFullUrl. Os valores aceitos são os de
GET /v1/domains/listall:
- um domínio próprio seu, desde que pronto — verificado com TLS ativo (
activeessl), comcheckoutnopurposee sem vínculo vivo de área de membros; dmn_shared— o domínio compartilhado da plataforma (pay.selectwin.io), disponível para toda empresa. É a única forma de colocar um link no host da plataforma quando você já tem domínio próprio pronto.
Omitido, o comportamento é o de sempre: o seu domínio de checkout pronto mais antigo, e na falta dele o
pay.selectwin.io.
Um domainId que não resolva (de outra empresa, não verificado, sem checkout no purpose, ou de área de
membros) devolve 422 checkoutDomainIdIsInvalid e o link não é criado. Não existe fallback silencioso
aqui de propósito: um link montado em host de outra empresa abre 404 para o comprador, porque o checkout
resolve o lojista pelo host e recusa quando host e link discordam do dono.
A resposta devolve em domainId o domínio em que o link está — dmn_shared para os que vivem no host da
plataforma, inclusive os criados antes deste campo existir.
integrationId — a que integração a venda pertence
integrationId amarra o link a uma das suas integrações (GET /v1/integrations/list-all). Quando um
comprador abre o link, a sessão de checkout nasce carimbada com:
| campo da sessão | valor |
|---|---|
integrationType | o slug do tipo da integração — woocommerce, shopify, … |
integrationId | o app_... da integração |
É assim que um pedido gerado por um link volta a ser atribuído à loja que o criou, sem que a URL do
comprador precise carregar ?integration=. Se a URL trouxer ?integration=, ela vence — o parâmetro é
um override explícito, e como ele nomeia um tipo (não uma linha sua), o integrationId da sessão fica
nulo nesse caso, em vez de atribuir a venda a uma integração que ninguém pediu.
Uma integração deleted ou quarantined não resolve ⇒ 422 checkoutIntegrationIdIsInvalid. Uma
integração apenas desabilitada resolve normalmente: pausar uma integração não pode quebrar a criação de
links.
⚠️ A assinatura do link (
signature) é calculada sobreitems=<...>&integration=<...>. Trocar ointegrationId— ou ositems— re-assina, sempre a partir do par efetivo.
Resposta 201 Created
{
"id": "link_01hqzvabc",
"name": "Black Friday PIX",
"type": "dynamic",
"enabled": true,
"accessId": "k3m9x2qp7ab4",
"signature": "f62a0cb72d7a5d55052c96301013e64627133231f90c4614b10d0f50b9887f8d",
"accessFullUrl": "https://pay.selectwin.io/l/live/k3m9x2qp7ab4",
"sessionId": null,
"editable": false,
"items": [ { "id": "var_01hqzvabc", "quantity": 1 } ],
"discounts": [],
"customInputs": [],
"expiresAt": "2026-12-31T23:59:59.000Z",
"availableAt": null,
"templateId": null,
"integrationId": null,
"domainId": null,
"metadata": {},
"createdAt": "2026-04-12T17:56:33.000Z",
"updatedAt": "2026-04-12T17:56:33.000Z"
}| Campo | Descrição |
|---|---|
id | ID público do link (link_*). |
type | Palavra de tipo ecoada do banco (compatibilidade). |
enabled | Se o link está ativo. |
accessId / signature / accessFullUrl | Identificador de acesso, assinatura HMAC e URL pronta para compartilhar. O accessId é uma chave curta e opaca de 12 caracteres (a-z0-9), única na plataforma, e é o que a accessFullUrl carrega em /l/{environment}/{accessId}. Links criados antes de setembro/2026 têm ids de 32 caracteres e continuam válidos — nada reescreve o accessId, então trate-o sempre como string opaca de tamanho variável, nunca com tamanho fixo. |
sessionId | Sempre null (a vinculação link→sessão é resolvida no fluxo público de abertura). |
templateId | tmpl_* quando há template; senão null. |
integrationId / domainId | Sempre null (binding ainda não exposto). |
accessFullUrlé a URL pronta para compartilhar (já assinada). A assinatura HMAC emsignaturegarante a integridade dos parâmetros do link. As respostas de payment link não incluemmerchantnem_links.
⚠️
signaturenão é identificador. Ela é o HMAC do carrinho (items+integrationId), então dois links com os mesmos itens e a mesma integração têm a mesmasignature— o que os distingue (nome, template, domínio, cupons, janela de disponibilidade) está fora do payload assinado. Duplicar uma oferta é normal e permitido. Para identificar o link use oid(link_*); para abri-lo, oaccessId.
Consultar
GET /v1/checkouts/payment-links/{paymentLinkId}
Retorna o objeto completo (mesma forma da criação).
curl -X GET "https://api.selectwin.io/v1/checkouts/payment-links/link_01hqzvabc" \
-H "SelectKey: sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ"Listar
GET /v1/checkouts/payment-links
Lista paginada. Cada item traz o objeto completo do link (mesma forma da consulta individual).
Filtros
| Parâmetro | Tipo | Descrição |
|---|---|---|
limit / offset / sort | — | Paginação (limit default 20, máx. 100; offset default 0). Veja Paginação |
status | enum | enabled ou disabled |
daterange* | — | Filtros por intervalo de datas (daterange, daterangegt, daterangegte, daterangelt, daterangelte) |
Resposta 200 OK
{
"offset": 0,
"limit": 20,
"total": 3,
"page": { "current": 1, "total": 1, "offset": { "first": 0, "prev": null, "next": null, "last": 0 } },
"data": [
{
"id": "link_01hqzvabc",
"name": "Black Friday PIX",
"type": "dynamic",
"enabled": true,
"accessId": "k3m9x2qp7ab4",
"signature": "f62a0cb72d7a5d55052c96301013e64627133231f90c4614b10d0f50b9887f8d",
"accessFullUrl": "https://pay.selectwin.io/l/live/k3m9x2qp7ab4",
"sessionId": null,
"editable": false,
"items": [ { "id": "var_01hqzvabc", "quantity": 1 } ],
"discounts": [],
"customInputs": [],
"expiresAt": "2026-12-31T23:59:59.000Z",
"availableAt": null,
"templateId": null,
"integrationId": null,
"domainId": null,
"metadata": {},
"createdAt": "2026-04-12T17:56:33.000Z",
"updatedAt": "2026-04-12T17:56:33.000Z"
}
],
"hasMore": false
}A lista não inclui
merchant/_links(envelope plano{ offset, limit, total, page, data, hasMore }).
Atualizar
PUT /v1/checkouts/payment-links/{paymentLinkId}
Envie apenas os campos a alterar: name, items, discounts, customInputs, expiresAt,
availableAt, editable, templateId, domainId, integrationId, metadata. O corpo é estrito —
campos não reconhecidos são rejeitados com 400. Retorna o objeto completo (200 OK), mesma forma da criação.
Trocar o
domainIdreescreve aaccessFullUrlno host novo, mantendo oaccessId. Os links já distribuídos continuam abrindo (o host antigo ainda é seu, e o checkout continua concordando sobre o dono); você passa a divulgar o novo. OmitirdomainIdnão re-escolhe o host — o link fica onde está.
curl -X PUT "https://api.selectwin.io/v1/checkouts/payment-links/link_01hqzvabc" \
-H "SelectKey: sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
-H "Content-Type: application/json" \
-d '{ "name": "Campanha atualizada", "expiresAt": "2027-01-31T23:59:59Z" }'Excluir
DELETE /v1/checkouts/payment-links/{paymentLinkId}
{ "id": "link_01hqzvabc", "resource": "checkout-paymentLink", "deleted": true }Erros
error.code | HTTP | Quando |
|---|---|---|
invalidParameters | 400 | Validação de campos (veja error.params) |
checkoutPaymentLinkNotFound | 404 | Link não encontrado |
variantIdIsInvalid | 422 | Algum items[].id referencia uma variante inexistente |
checkoutTemplateIdIsInvalid | 422 | templateId não existe |
checkoutDomainIdIsInvalid | 422 | domainId não é um domínio que esta empresa pode usar no checkout |
checkoutIntegrationIdIsInvalid | 422 | integrationId não é uma integração desta empresa (ou está deleted/quarantined) |
checkoutPaymentLinkCreateFailed | 500 | Falha ao criar o link |
Catálogo geral: Códigos de Erro.
How is this guide?