SelectwinSelectwin

Links de pagamento

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

Shell
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 o carrinho na página (default false). Com false a trava vale no servidor (desde 15/09/2026): o autosave da sessão recusa trocar item, mudar quantidade ou adicionar linha (422 checkoutCartNotEditable); order bump e upsell seguem regra própria. Antes era só de tela, e o cupom do link passava a valer para qualquer carrinho.
templateIdstringNãoTemplate de checkout (tmpl_... ou ckt_...). Não é só visual: o template define desconto por método, parcelas, endereço obrigatório e fretes. O do link vence um ?template_id= na URL, e a sessão aberta pelo link é cobrada por ele — o checkout recusa outro template no pagamento.
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

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.

Resposta 201 Created

JSON
{
  "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).

Consultar

GET /v1/checkouts/payment-links/{paymentLinkId}

Retorna o objeto completo (mesma forma da criação).

Shell
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 / sort—Paginação (limit default 20, máx. 100; offset default 0). Veja Paginação
statusenumenabled ou disabled
domainIdstringOs links que abrem neste host (dmn_…, ou dmn_shared para o host da plataforma): pelo domainId gravado no link ou, quando o host foi escolhido no automático, pela URL do link
daterange*—Filtros por intervalo de datas (daterange, daterangegt, daterangegte, daterangelt, daterangelte)

Resposta 200 OK

JSON
{
  "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
}

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.

Shell
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" }'

Testar em sandbox

POST /v1/checkouts/payment-links/{paymentLinkId}/test

Cria o link de teste de um link de produção, sem trocar de ambiente: a chamada é feita com a chave (ou a sessão) live, e o link criado é de sandbox. O ambiente fica dentro da URL (…/l/sandbox/…), então o link de teste nunca abre em produção e não cobra de verdade. Sem corpo; aceita X-Idempotency-Key.

  • Os itens são cópias. O catálogo de cada ambiente é separado, então cada variante do link ganha uma cópia no catálogo de sandbox, com o mesmo nome, preço, recorrência e imagens. O metadata da cópia guarda de onde ela veio (selectwinLiveVariantId, selectwinLiveProductId).
  • Um link de teste por link de produção. Chamar de novo refaz o mesmo link de teste, com a mesma URL, e atualiza as cópias a partir da produção (o preço novo, por exemplo). O metadata do link de teste guarda o link de produção (selectwinLiveLinkId). A primeira chamada responde 201; as seguintes, 200.
  • Abre na hora. O link de teste não herda availableAt nem expiresAt, para dar para testar antes de divulgar.
  • O que não vai junto vem em warnings. O link de teste abre no checkout padrão do sandbox (o checkout próprio do link é de produção) e não é de nenhuma integração. Item desativado na produção fica de fora, e a cópia dele é desativada. Cupom sem cupom de mesmo código no sandbox não dá desconto no teste.
  • Um teste por vez, por conta. Enquanto um link de teste da sua conta está sendo preparado, outra chamada a /test (de qualquer link) responde 409 checkoutPaymentLinkTestBusy na hora, sem gravar nada. Espere alguns segundos e chame de novo com outra X-Idempotency-Key (a chave da tentativa recusada continua devolvendo o 409).
  • Até 100 itens. O teste copia no máximo 100 itens, o mesmo limite do link. Um link antigo com mais itens que isso responde 422 checkoutPaymentLinkTestTooManyItems.
Shell
curl -X POST "https://api.selectwin.io/v1/checkouts/payment-links/link_01hqzvabc/test" \
  -H "SelectKey: sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
  -H "X-Idempotency-Key: 4f1c2a9e-teste-link"
JSON
{
  "resource": "checkout-paymentLinkTest",
  "liveLinkId": "link_01hqzvabc",
  "created": true,
  "link": {
    "id": "link_01hqzvtst",
    "name": "Campanha de lançamento",
    "accessFullUrl": "https://pay.selectwin.io/l/sandbox/k3v9q2m7x1ab",
    "items": [{ "id": "var_01hqzvcpy", "quantity": 1 }],
    "...": "o mesmo objeto da criação"
  },
  "items": [
    { "liveVariantId": "var_01hqzvabc", "variantId": "var_01hqzvcpy", "productId": "prd_01hqzvcpy", "quantity": 1, "copiedNow": true }
  ],
  "warnings": [
    { "code": "couponsNotInSandbox", "values": ["LANCAMENTO10"] },
    { "code": "templateNotCarried" }
  ]
}
warnings[].codeSignificado
variantsNotOnSaleVariantes de produção desativadas, ou de produto desativado, ficaram fora do teste (values: os ids de produção)
couponsNotInSandboxEstes códigos não existem no sandbox, e o teste abre sem o desconto deles (values: os códigos)
templateNotCarriedO link tem checkout próprio, que é de produção. O teste abre no checkout padrão do sandbox
integrationNotCarriedO link é de uma integração, e a venda de teste não é atribuída a ela

Excluir

DELETE /v1/checkouts/payment-links/{paymentLinkId}

JSON
{ "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, desativada ou de outro ambiente (um link live não aceita variante de sandbox)
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)
checkoutPaymentLinkTestFromSandbox409/test chamado com chave ou sessão de sandbox. Lá, todo link já é de teste
checkoutPaymentLinkTestNothingToSell422/test: nenhum item do link está à venda na produção
checkoutPaymentLinkTestTooManyItems422/test: o link tem mais de 100 itens (error.params[0].items diz quantos)
checkoutPaymentLinkTestBusy409/test: outro link de teste da conta está sendo preparado agora. Nada foi gravado: tente de novo em instantes, com outra X-Idempotency-Key
checkoutPaymentLinkCreateFailed500Falha ao criar o link

Catálogo geral: Códigos de Erro.

Atualizado em 21 de outubro de 2026

Preferências de cookies

Hoje o site usa só cookies essenciais: nenhuma ferramenta de medição ou de anúncios está ligada, e nada é compartilhado com terceiros. Se isso mudar, você decide aqui antes de qualquer coisa ser carregada.

  • Mantêm o site funcionando: segurança, a sua escolha sobre cookies e preferências como a versão da documentação. Não dependem de consentimento.

    Sempre ativos