Pular para o conteúdo principal
Este guia aborda a construção de um sistema de cumprimento manual de chaves de licença de ponta a ponta. Em vez de o Dodo Payments gerar automaticamente uma chave no pagamento, cada compra cria uma concessão pending e aguarda que você forneça o valor da chave do seu próprio sistema, de um fornecedor terceiro ou de um conjunto finito de códigos. Ao final, você terá:
  • Um produto com uma autorização de Chave de Licença definida para cumprimento manual.
  • Um ouvinte de webhook que detecta quando um cliente está aguardando uma chave.
  • Uma chamada de cumprimento que entrega a chave e notifica o cliente automaticamente.

License Keys overview

O ciclo completo da chave de licença e a configuração fulfillment_mode.

Fulfill License Key Grant API

Referência da API para o endpoint que você chama para entregar uma chave.

Como Funciona

O cumprimento manual altera apenas a etapa de emissão. Ativação, validação, desativação, expiração e revogação funcionam exatamente como uma chave gerada automaticamente, uma vez entregue.

Pré-requisitos

Para seguir este guia, você precisará de:
  • Uma conta de comerciante do Dodo Payments.
  • Sua chave de API (DODO_PAYMENTS_API_KEY) e a chave secreta do webhook do painel de controle. Veja o guia de geração de chave de API.
  • Um endpoint de backend que possa receber webhooks.
Use https://test.dodopayments.com e credenciais de modo de teste durante a construção. Alterne para https://live.dodopayments.com e chaves ao vivo quando for para a produção.

Etapa 1 — Criar uma Autorização de Chave de Licença no Modo Manual

Uma autorização é uma definição reutilizável do que você entrega. Crie uma autorização de Chave de Licença e defina sua fulfillment_mode para manual.
1

Open Entitlements

Vá para Autorizations no seu painel e clique em + para criar uma nova autorização.
2

Choose License Key

Selecione Chave de Licença como a integração e dê um Nome. O formulário expõe esses campos:
  • Modo de CumprimentoAutomatic por padrão. Esta é a configuração que habilita o cumprimento manual; você a altera no próximo passo.
  • Duração da Licença — quanto tempo cada chave emitida permanece válida, ou Sem expiração.
  • Limite de Ativações — máximo de ativações por chave, ou Ilimitado.
  • Mensagem de Ativação — mensagem opcional voltada ao cliente exibida quando ele ativa a chave.
Novo formulário de autorização de Chave de Licença com nome, modo de cumprimento, duração da licença, limite de ativações e mensagem de ativação
3

Set Fulfillment Mode to Manual

Abra o dropdown Modo de Cumprimento e altere de Automático para Manual. Esta é a configuração que conduz todo este guia — sem ela, as chaves são geradas e enviadas por e-email automaticamente e nenhuma concessão pendente é criada. Com Manual selecionado, cada compra cria uma concessão pending para você cumprir. Clique em Criar Autorização para salvar.
fulfillment_mode padrão é auto. Omitir, ou deixar uma autorização existente inalterada, mantém o comportamento automático. Somente autorizações explicitamente definidas para manual criam concessões pendentes.

Etapa 2 — Anexe a Autorização a um Produto

Abra o produto que deseja vender, expanda Configurações Avançadas → Autorizações e Créditos, e selecione a autorização de Chave de Licença que definiu como Manual na Etapa 1. Um único produto pode entregar essa chave de licença junto com outras autorizações na mesma compra.
Painel de autorizações do produto com Chave de Licença selecionada
O modo de cumprimento é uma propriedade da autorização, não do produto. Porque você definiu como Manual na Etapa 1, todo produto a que essa autorização está vinculada cria concessões de chaves de licença pending na compra — não há nada extra para configurar aqui.
Se você ainda não tem um produto, crie um primeiro (único ou assinatura). Veja o Guia de Integração de Pagamentos Únicos para vender o produto através do checkout.

Etapa 3 — Detectar Concessões Pendentes

Quando um cliente compra o produto, o Dodo Payments cria uma concessão em status pending sem chave anexada e dispara um webhook entitlement_grant.created. Este é o seu sinal de que um cliente está aguardando uma chave.

Ouça o webhook

Configure um endpoint de webhook (Desenvolvedor → Webhooks no painel) e aja sobre as concessões de chave de licença pendentes. A implementação segue a especificação Webhooks Padrão.
import { Webhook } from 'standardwebhooks';

const webhook = new Webhook(process.env.DODO_WEBHOOK_KEY!);

export async function POST(request: Request) {
  const rawBody = await request.text();
  const headers = {
    'webhook-id': request.headers.get('webhook-id') || '',
    'webhook-signature': request.headers.get('webhook-signature') || '',
    'webhook-timestamp': request.headers.get('webhook-timestamp') || '',
  };

  await webhook.verify(rawBody, headers);
  const event = JSON.parse(rawBody);

  // A customer bought a manual-mode license key and is waiting for it.
  if (
    event.type === 'entitlement_grant.created' &&
    event.data.integration_type === 'license_key' &&
    event.data.status === 'pending'
  ) {
    await queueLicenseKeyFulfillment({
      grantId: event.data.id,
      customerId: event.data.customer_id,
    });
  }

  return new Response('ok');
}
A carga útil da concessão carrega integration_type: "license_key", para que você possa reconhecer uma concessão de chave de licença sem uma busca extra. Veja a referência de webhook de Concessão de Autorização para a carga útil completa.

Ou faça polling da API de Listagem de Concessões

Se preferir não depender de webhooks, liste as concessões para a autorização e filtre por integration_type e status:
const pending = await client.entitlements.grants.list('ent_license_key_id', {
  integration_type: 'license_key',
  status: 'pending',
});

for (const grant of pending.items) {
  console.log(`Grant ${grant.id} for customer ${grant.customer_id} needs a key`);
}

Etapa 4 — Entregar a Chave

Obtenha o valor da chave do seu próprio sistema, depois envie-o com o endpoint Cumprir Concessão de Chave de Licença. Isso requer sua chave de API secreta (permissão de Editor); não é um dos endpoints de licença pública.
async function fulfill(grantId: string, key: string) {
  const res = await fetch(
    `https://test.dodopayments.com/grants/${grantId}/license-key`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`,
      },
      body: JSON.stringify({
        key,
        // Optional — fall back to the entitlement config when omitted
        activations_limit: 5,
        expires_at: '2027-05-01T00:00:00Z',
      }),
    },
  );

  if (!res.ok) {
    // See the status code table below for handling
    throw new Error(`Fulfillment failed: ${res.status}`);
  }

  return res.json(); // updated grant, now status: "delivered"
}

Campos de solicitação

key
string
obrigatório
A string da chave de licença a ser entregue ao cliente. Espaços em branco são removidos; um valor vazio ou apenas de espaço em branco é rejeitado.
activations_limit
integer
Limite de ativações por chave. Retoma a configuração da autorização quando omitido.
expires_at
string
Expiração por chave (ISO 8601). Retoma a duração da configuração da autorização quando omitido. Para concessões emitidas por assinatura, a validade permanece vinculada à assinatura independentemente.
Com sucesso, a concessão avança para delivered, o cliente recebe automaticamente a chave (o mesmo e-mail que receberia sob cumprimento automático), e entitlement_grant.delivered dispara. O cliente recebe um e-mail com a chave de licença, o produto, limite de ativação, expiração e suas instruções de ativação:
E-mail de chave de licença do cliente mostrando a chave, produto, limite de ativação, expiração e instruções de ativação
Você não precisa enviar a chave por e-mail você mesmo — a entrega acontece automaticamente quando a concessão é cumprida.

Etapa 5 — Lidando com Erros e Novas Tentativas

O endpoint valida a concessão antes de entregar algo. Trate essas respostas:
StatusSignificadoO que fazer
200Chave entregue, concessão agora é delivered.Concluído.
400Não é uma concessão de chave de licença, ou a chave está vazia/em branco.Corrija a solicitação; não tente novamente como está.
404Nenhuma concessão com esse ID para o seu negócio.Verifique o grant_id.
409Concessão não aguardando cumprimento (já entregue ou já possui uma chave), ou o valor da chave já existe.Se já foi entregue, trate como sucesso. Se uma chave duplicada, forneça uma chave diferente.
422Corpo da solicitação falhou na validação (e.g. activations_limit < 1).Corrija o campo e tente novamente.
O cumprimento pode ser tentado novamente em erros transitórios (timeouts, 5xx). Cada concessão só pode ser cumprida uma vez, então uma nova tentativa após uma chamada bem-sucedida, mas não reconhecida, retorna 409 em vez de emitir uma segunda chave ou enviar um e-mail duplicado. Use o id da concessão como sua chave de idempotência.

Verifique o Fluxo

  1. Compre o produto em modo de teste (veja os guias de checkout).
  2. Confirme se seu webhook recebeu entitlement_grant.created com status: "pending" e integration_type: "license_key", ou se a concessão aparece na resposta da Listagem de Concessões com esses filtros.
  3. Chame o endpoint de cumprimento com uma chave de teste.
  4. Confirme se a resposta mostra status: "delivered" com um license_key preenchido, o cliente recebe o e-mail da chave e entitlement_grant.delivered dispara.
Uma vez entregue, o cliente pode ativar e validar a chave nos endpoints de licença pública exatamente como uma chave gerada automaticamente.

Referência de API Relacionada

Create Entitlement

Crie a autorização de Chave de Licença com fulfillment_mode: manual.

List Grants

Filtre por integration_type e status para encontrar concessões pendentes.

Fulfill License Key Grant

Entregue o valor da chave e faça a transição da concessão para entregue.

Entitlement Grant Webhooks

Os eventos entitlement_grant.* que sinalizam concessões pendentes e entregues.

Create Entitlement

Create the License Key entitlement with fulfillment_mode: manual.

List Grants

Filter by integration_type and status to find pending grants.

Fulfill License Key Grant

Deliver the key value and transition the grant to delivered.

Entitlement Grant Webhooks

The entitlement_grant.* events that signal pending and delivered grants.
Last modified on June 9, 2026