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_createO 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 /couponsO 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
Você envia o pedido
POST /orders com o status que o fluxo espera, normalmente completed.
- 2
O fluxo reconhece o pedido
O fluxo cujo gatilho é Status do pedido executa para o cliente daquele pedido.
- 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
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.
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.

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.

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.

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.

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.

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.

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.

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.

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 |
|---|---|---|
completed | Pagamento realizado | É a opção usada na maioria dos fluxos de cupom. Mande completed quando o pedido estiver pago ou confirmado. |
on-hold | Aguardando pagamento | Pedido criado mas ainda não pago. |
canceled | Cancelado | Um L só. Enviar cancelled retorna 422 Invalid status. |
processing | Nenhuma | Nã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. |
— | Entregue | Corresponde 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/zoppyHeaders
{
"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 | |
|---|---|---|---|
code | string | Obrigatório | Código do cupom. É a chave que você usa nas consultas e o que o cliente digita no checkout. |
id | string (uuid) | Obrigatório | ID do cupom na Zoppy. |
orderId | string (uuid) | null | Opcional | ID Zoppy do pedido que originou o cupom. Nulo quando o cupom não veio de um pedido. |
companyId | string (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
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
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
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
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
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
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
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
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
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
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: