Checkouts

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çãoMétodoEndpoint
CriarPOST/v1/checkouts/payment-links
ListarGET/v1/checkouts/payment-links
ConsultarGET/v1/checkouts/payment-links/{paymentLinkId}
AtualizarPUT/v1/checkouts/payment-links/{paymentLinkId}
ExcluirDELETE/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

CampoTipoObrigatórioDescrição
namestringSimNome de exibição (1–255 caracteres)
items[]arraySimItens do link: { id, quantity } (1–100 itens). id é a variante (var_... ou prv_...); quantity é inteiro ≥ 1 (default 1, máx. 100000)
discounts[]arrayNãoCódigos de cupom pré-aplicados (strings, 1–50 caracteres cada, máx. 20). A validação/retenção autoritativa acontece na cobrança
customInputs[]arrayNãoCampos de formulário customizados (objetos livres, máx. 50)
expiresAtdatetimeNãoA partir deste instante o link não pode mais ser usado
availableAtdatetimeNãoInstante a partir do qual o link passa a valer
editablebooleanNãoPermite o cliente editar quantidades na página (default false)
templateIdstringNãoTemplate de checkout para visual (tmpl_... ou ckt_...)
domainIdstringNãoEm que domínio a accessFullUrl é montada (veja abaixo)
integrationIdstringNãoA integração (app_...) a que uma venda por este link pertence (veja abaixo)
metadataobjectNãoMetadados livres

Não há mais campo type. O antigo link "static" foi removido; existe apenas um tipo de link (persistido). Um type enviado por clientes antigos é silenciosamente ignorado.

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 (active e ssl), com checkout no purpose e 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ãovalor
integrationTypeo slug do tipo da integração — woocommerce, shopify, …
integrationIdo 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 sobre items=<...>&integration=<...>. Trocar o integrationId — ou os itemsre-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"
}
CampoDescrição
idID público do link (link_*).
typePalavra de tipo ecoada do banco (compatibilidade).
enabledSe o link está ativo.
accessId / signature / accessFullUrlIdentificador 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.
sessionIdSempre null (a vinculação link→sessão é resolvida no fluxo público de abertura).
templateIdtmpl_* quando há template; senão null.
integrationId / domainIdSempre null (binding ainda não exposto).

accessFullUrl é a URL pronta para compartilhar (já assinada). A assinatura HMAC em signature garante a integridade dos parâmetros do link. As respostas de payment link não incluem merchant nem _links.

⚠️ signature nã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 mesma signature — 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 o id (link_*); para abri-lo, o accessId.


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âmetroTipoDescrição
limit / offset / sortPaginação (limit default 20, máx. 100; offset default 0). Veja Paginação
statusenumenabled 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 domainId reescreve a accessFullUrl no host novo, mantendo o accessId. 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. Omitir domainId nã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.codeHTTPQuando
invalidParameters400Validação de campos (veja error.params)
checkoutPaymentLinkNotFound404Link não encontrado
variantIdIsInvalid422Algum items[].id referencia uma variante inexistente
checkoutTemplateIdIsInvalid422templateId não existe
checkoutDomainIdIsInvalid422domainId não é um domínio que esta empresa pode usar no checkout
checkoutIntegrationIdIsInvalid422integrationId não é uma integração desta empresa (ou está deleted/quarantined)
checkoutPaymentLinkCreateFailed500Falha ao criar o link

Catálogo geral: Códigos de Erro.

How is this guide?

On this page