Z
Zoppy Partners API

Fluxo de cupons

Duas coisas diferentes se chamam cupom nesta integração: o cupom que a Zoppy cria e avisa você por webhook, e o cupom que você já tem e registra na Zoppy. Esta página separa as duas.

Zoppy envia para você

webhook coupon_create

O cupom nasce na Zoppy, disparado por um fluxo de automação. A Zoppy avisa a URL que você cadastrou e você cria o cupom no seu e-commerce ou PDV.

Você envia para a Zoppy

POST /coupons

O cupom já existe no seu sistema e você o registra na Zoppy para que ela envie ao cliente e acompanhe o uso. Esta chamada não dispara webhook: você não recebe de volta um cupom que você mesmo criou.

1. O gatilho: fluxo de automação

O webhook coupon_create não é disparado pela chegada de um pedido na API. Ele é disparado quando um fluxo de automação com o step Criar cupom executa no painel da Zoppy.

  1. 1

    Você envia o pedido

    POST /orders com o status que o fluxo espera, normalmente completed.

  2. 2

    O fluxo reconhece o pedido

    O fluxo cujo gatilho é Status do pedido executa para o cliente daquele pedido.

  3. 3

    O step Criar cupom gera o cupom

    Giftback, que é um percentual sobre a compra concluída, ou cupom de valor fixo, conforme configurado no step.

  4. 4

    A Zoppy chama a sua URL

    POST na URL cadastrada em POST /webhooks com o evento coupon_create.

Sem fluxo ativo, nenhum webhook é enviado

Não existe endpoint na Partners API para criar fluxo de automação: o fluxo é montado no painel da Zoppy. Você mesmo pode criá-lo com o login da conta que está usando para integrar, seguindo o passo a passo abaixo. Se você está validando a integração e nada chega na sua URL, este é o primeiro ponto a checar.

Um cadastro de webhook por empresa

O cadastro do webhook está vinculado ao token usado na chamada, ou seja, à empresa. Se você atende várias lojas na Zoppy, precisa chamar POST /webhooks uma vez com o token de cada uma. Uma inscrição não vale para as outras.

2. Como criar o fluxo que dispara o webhook

Passo a passo no painel da Zoppy, em Fluxo de Automação. O fluxo abaixo é o mínimo necessário para gerar um cupom e disparar o webhook: um gatilho de status de pedido e um step Criar cupom.

1

Abra Fluxo de Automação e clique em Criar novo fluxo

O menu fica no grupo COMUNICAÇÃO, na barra lateral esquerda. A tela seguinte mostra os fluxos pré-criados: clique em Criar do zero, no canto superior direito.

Tela Fluxo de Automação vazia com o botão Criar novo fluxo
2

Dê um nome e escolha Uma vez por pedido

Nome e descrição são obrigatórios. Em Rodar o fluxo, escolha Uma vez por pedido: com Uma vez por cliente o fluxo roda uma única vez para cada cliente, então repetir o teste exige um cliente novo a cada tentativa.

Modal Criar novo fluxo preenchido
3

Configure o gatilho e salve

Em Escolha o que ativará o fluxo, deixe Status do pedido - padrão. Em Qual o status do pedido?, escolha Pagamento realizado, que corresponde ao status completed da API. Clique em Salvar no rodapé do painel.

Painel do gatilho com status Pagamento realizado
4

Clique no + do canvas e escolha Criar cupom

O + fica entre o card do gatilho e o Fim. Na Lista de etapas, Criar cupom é a primeira opção do grupo Ações. É esse step, e só ele, que dispara o webhook coupon_create.

Lista de etapas com a opção Criar cupom
5

Defina o cupom e salve o step

Com Giftback, Valor do cupom é o percentual sobre a compra concluída e o valor mínimo é um múltiplo do crédito gerado. Com Cupom, você escolhe Porcentagem ou Valor fixo e informa o valor direto. Os padrões sugeridos (15%, 4x, 45 dias) servem para teste.

Configuração do step Criar cupom com tipo Giftback
6

Confira o desenho do fluxo

O canvas deve ter Início, o gatilho com o status escolhido, o step Criar cupom e Fim. Clique em Salvar, no topo à direita.

Canvas com gatilho e step Criar cupom
7

Ative o fluxo antes de salvar

No painel de confirmação, deixe Rodar fluxo retroativo? em Não, senão o fluxo gera cupom para todos os clientes que já se encaixaram nas condições. Ligue Ativar fluxo de automação, marque O meu fluxo de automação foi revisado e clique em Salvar. Se você salvar sem ligar essa chave, o fluxo nasce inativo e nenhum webhook é enviado.

Painel de confirmação com a chave Ativar fluxo de automação ligada
8

Confirme que a coluna ATIVO está ligada

Volte para a lista de fluxos. A chave da coluna ATIVO precisa estar roxa. Cinza significa pausado: clique na chave para ativar.

Lista de fluxos com a chave ATIVO ligada

Status do pedido: API e painel

O gatilho usa os rótulos em português do painel, que não são iguais aos valores aceitos em status no POST /orders. O campo status aceita exatamente quatro valores, e qualquer outro (pending, paid, refunded, failed, cancelled) retorna 422 Invalid status. Esta é a correspondência:

Status na API Opção no painel Descrição
completedPagamento realizadoÉ a opção usada na maioria dos fluxos de cupom. Mande completed quando o pedido estiver pago ou confirmado.
on-holdAguardando pagamentoPedido criado mas ainda não pago.
canceledCanceladoUm L só. Enviar cancelled retorna 422 Invalid status.
processingNenhumaNão existe opção equivalente no painel, então pedido em processing não dispara fluxo nenhum. No POST /orders ele é convertido para on-hold; no PUT /orders/:id é gravado como está e o pedido fica sem gatilho. Use on-hold ou completed.
—EntregueCorresponde a um sub-status de entrega que nenhum endpoint da Partners API preenche. Um fluxo com este gatilho nunca dispara para pedidos enviados por você: se para a sua operação entregue significa pedido finalizado, use completed.

Cada pedido entra no mesmo fluxo uma única vez. Se você criou um fluxo por status, o pedido entra no fluxo de Aguardando pagamento quando chega em on-hold e no de Pagamento realizado quando chega em completed, mas reenviar o mesmo status não faz o pedido entrar de novo no fluxo em que ele já passou.

O Tipo de desconto escolhido no step é o que você vai receber no campo type ao consultar o cupom: Porcentagem vira percent e Valor fixo vira fixed_cart.

3. O que a Zoppy envia

A Zoppy faz um POST na sua URL com Content-Type application/json. Se você cadastrou bearerToken, ele é enviado no header Authorization.

Requisição

POST https://seusite.com.br/webhooks/zoppy

Headers

{
  "Content-Type": "application/json",
  "Authorization": "Bearer o_token_que_voce_cadastrou"
}

Corpo enviado

{
  "code": "GIFT15-4A9C2B",
  "id": "1f7c9a2e-5b31-4c88-9d0a-2e64f1b7c3aa",
  "orderId": "8b2d41f0-77ac-4e19-b6d3-90c5ae12f4bb",
  "companyId": "3c5e8d10-6f42-4a97-b8e1-05d7c9b34f28"
}

Campos do corpo

Obrigatório aqui significa que o campo vem sempre no payload. Opcional significa que ele pode vir nulo.

Propriedade Tipo Descrição
codestring Obrigatório Código do cupom. É a chave que você usa nas consultas e o que o cliente digita no checkout.
idstring (uuid) Obrigatório ID do cupom na Zoppy.
orderIdstring (uuid) | null Opcional ID Zoppy do pedido que originou o cupom. Nulo quando o cupom não veio de um pedido.
companyIdstring (uuid) Obrigatório ID da empresa dona do cupom na Zoppy.

O payload é uma notificação, não o cupom: valor, validade, valor mínimo de compra e cliente não vêm no corpo.

Entrega e reenvio

  • •Responda 2xx em poucos segundos e processe depois. Qualquer outro status ou falha de conexão conta como falha.
  • •Em caso de falha reenviamos: até 10 tentativas, com backoff exponencial a partir de cerca de 2 segundos.
  • •Por causa do reenvio, o mesmo cupom pode chegar mais de uma vez. Use o code como chave de idempotência: se já processou, responda 2xx e ignore.
  • •id, orderId e companyId são identificadores da Zoppy, não os externalId do seu sistema.

4. O que fazer ao receber

  1. 1

    Responda 2xx primeiro

    Confirme o recebimento e processe em background. Não deixe a nossa chamada esperando pela criação do cupom no seu lado.

  2. 2

    Busque os dados do cupom

    GET /coupons/code/{code} devolve amount, type, expiryDate, minPurchaseValue, acumulative, used, isValid e o cliente vinculado. Alternativa: GET /coupons/order/{orderId} com o orderId do payload.

  3. 3

    Crie o cupom no seu sistema

    Use amount com type, que é percent ou fixed_cart, expiryDate como validade e minPurchaseValue como valor mínimo de compra. Se acumulative for true, permita combinar o cupom com outras promoções e descontos da loja; se false, crie como não acumulável.

  4. 4

    Devolva o seu ID, recomendado

    PUT /coupons/code/{code} com externalId igual ao ID do cupom no seu sistema. Depois disso GET /coupons/external/{externalId} funciona e a reconciliação entre os dois lados fica direta.

  5. 5

    Informe o resgate

    Quando o cliente usar o cupom, envie o pedido com couponCode preenchido em POST /orders. É assim que a Zoppy vincula o resgate ao pedido. No POST qualquer código é aceito: sem cupom correspondente na Zoppy, o pedido é gravado com couponUsed null. No PUT /orders/:id o código precisa ser de um cupom individual existente na Zoppy, senão a resposta é 422 Coupon code not found. O cupom individual usado em pedido passa a used true, mesmo com o pedido on-hold, e isValid false.

Consulta do passo 2 e resposta

GET https://api-partners.zoppy.com.br/coupons/code/GIFT15-4A9C2B
{
  "id": "1f7c9a2e-5b31-4c88-9d0a-2e64f1b7c3aa",
  "externalId": null,
  "code": "GIFT15-4A9C2B",
  "type": "fixed_cart",
  "amount": 82.35,
  "used": false,
  "isValid": true,
  "minPurchaseValue": 329.4,
  "acumulative": true,
  "startDate": "2026-08-04T13:02:11.000Z",
  "expiryDate": "2026-09-18T13:02:11.000Z",
  "customer": {
    "id": "7d4b1c60-8e35-4f21-9a07-3b62ce9d18af",
    "externalId": "cliente-erp-4471",
    "firstName": "João",
    "lastName": "Silva",
    "phone": "11987654321",
    "email": "joao@email.com"
  }
}

5. Giftback: apenas um ativo por telefone

Cada cliente mantém apenas um giftback ativo por telefone. Quando um novo giftback é gerado para um telefone que já tinha um giftback ainda não utilizado, o anterior é cancelado automaticamente, removido também da loja, e passa a constar com data de exclusão.

  • •O cancelamento atinge apenas o giftback que ainda não foi utilizado. Giftback já utilizado permanece como está.
  • •O cupom cancelado também é removido da loja, então ele deixa de ser aceito no checkout a partir daquele momento.
  • •Cupons que você registra pela API, com POST /coupons ou POST /coupons/shared, não são afetados por essa regra nem a acionam.

Não existe webhook de cupom excluído

A Zoppy não avisa você quando cancela um giftback anterior. Você tem dois caminhos para não honrar um cupom que já não vale. O primeiro é aplicar a mesma regra do seu lado: ao receber um coupon_create de giftback, invalide o giftback anterior daquele telefone que ainda não tinha sido usado. O segundo é reconsultar o cupom em GET /coupons/code/{code} antes de aceitá-lo no checkout: o cupom cancelado deixa de ser encontrado e a consulta responde 404, então o próprio 404 já é a confirmação de que o cupom não vale mais.

6. Registrar na Zoppy um cupom que você criou

Use POST /coupons quando o cupom nasce do seu lado. Informe code, amount, o phone do cliente e o externalId com o ID do cupom no seu sistema. expiryDate é opcional (sem ela, o cupom vale até 2100-01-01), mas envie a validade real.

Requisição

POST https://api-partners.zoppy.com.br/coupons
{
  "externalId": "cupom-erp-99213",
  "code": "PROMO50-JULHO",
  "type": "fixed_cart",
  "amount": 50,
  "minPurchaseValue": 200,
  "expiryDate": "2026-09-30T23:59:59.000Z",
  "phone": "11987654321",
  "awaitingOrder": false
}
  • •externalId ou createOnProvider: um dos dois é obrigatório. Envie externalId quando o cupom já existe no seu sistema. Use createOnProvider apenas se quiser que a Zoppy crie o cupom na plataforma de e-commerce.
  • •O externalId é tratado de forma diferente em cada endpoint, e nenhum dos dois avisa quando o valor se perde. Em POST /coupons ele é texto livre, UUID serve, e acima de 255 caracteres o valor é cortado. Em POST /coupons/shared ele é guardado como número inteiro de 1 a 2147483647: texto vira o número do começo ou 0, decimal é arredondado e valor acima do limite vira 2147483647, a chamada responde 200 e depois a busca por esse identificador não encontra o cupom, ou encontra outro. Lá o externalId também não é único: consulte pelo code.
  • •awaitingOrder vem true por padrão: o próximo pedido do telefone que chegar sem couponCode recebe o cupom. Se você controla o resgate do seu lado, registre com awaitingOrder false. Para baixar o cupom à mão, use PUT com { "used": true, "awaitingOrder": false }: used true sozinho não desliga awaitingOrder.
  • •Para cupom sem cliente específico e com limite de uso global, use POST /coupons/shared.

7. Como testar

  1. 1

    Monte e ative o fluxo

    Siga o passo a passo da seção 2 na conta que você está usando para integrar e confirme que a coluna ATIVO ficou ligada.

  2. 2

    Cadastre a sua URL

    POST /webhooks com event coupon_create e a sua URL. Cadastre também o bearerToken se você valida autenticação no seu endpoint.

  3. 3

    Se for giftback, confira o fluxo, não a configuração

    Quem decide se o cupom sai, e com qual percentual, validade e valor mínimo, é o step Criar cupom do fluxo de automação. GET /coupons-config devolve os parâmetros padrão de giftback da conta como referência de leitura, mas não é essa configuração que libera ou bloqueia a geração do cupom.

  4. 4

    Mande um pedido concluído

    Crie o cliente e o produto, então chame POST /orders com status completed e o lineItems do produto. O cliente precisa ter telefone e endereço.

  5. 5

    Se nada chegar, isole o lado

    O disparo é assíncrono e passa por fila, então dê alguns segundos. Passado isso, chame GET /coupons/order/{orderId} com o id do pedido que você criou: cupom gerado e webhook não recebido é problema de entrega na sua URL, cupom não gerado é o fluxo de automação.

Referência completa dos endpoints citados nesta página: