Pular para o conteúdo principal
Um plano é o template de cobrança recorrente do Z2Pay. Ele é composto por componentes (plan_items) — cada um representa uma cobrança do bundle — e cada componente tem uma ou mais versões de preço (prices), sempre em centavos. O fluxo típico é: cria o plano em draft, adiciona pelo menos um componente recorrente com preço (ou usa o endpoint atômico de cobrança), e publica o plano para que ele aceite assinaturas.
Todos os endpoints desta página exigem o header x-api-key. Veja Autenticação. Os exemplos usam a base URL de sandbox https://billing-api.sandbox.z2pay.com.

Conceitos

Plano

Template de cobrança identificado por um code único. Nasce em draft e precisa ser publicado. IDs com prefixo plan_.

Componente (plan_item)

Cada cobrança dentro do plano. Pode ser recurring (cobrado todo ciclo) ou activation (cobrado uma vez, na adesão). IDs com prefixo pli_.

Preço (price)

Versão de preço de um componente, em centavos. Criar um preço novo marca o anterior da mesma combinação (moeda, recorrência) como não-corrente. IDs com prefixo price_.

Recorrência

Define a cadência (unit + interval), a âncora do ciclo e quando cobrar (prepaid/postpaid).

Endpoints

MétodoRotaDescrição
POST/plansCria um plano em draft
GET/plansLista planos (paginado, com filtros)
GET/plans/{id}Busca um plano por ID
PATCH/plans/{id}Atualiza campos editáveis do plano
POST/plans/{id}/publishPublica o plano (draftactive)
POST/plans/{id}/archiveArquiva o plano
GET/plans/{id}/templatePlano + componentes com o preço corrente de cada um
GET/plans/{id}/itemsLista os componentes do plano
POST/plans/{id}/itemsAdiciona um componente ao plano
PATCH/plans/{id}/items/{itemId}Atualiza um componente
DELETE/plans/{id}/items/{itemId}Arquiva um componente
GET/plans/{id}/pricesLista as versões de preço do plano
POST/plans/{id}/pricesCria uma nova versão de preço
POST/plans/{id}/prices/{priceId}/archiveArquiva uma versão de preço
POST/plans/{id}/chargesCria componente + preço atomicamente
Os POSTs aceitam o header opcional Idempotency-Key para repetir a requisição com segurança. Veja Convenções.

Criar plano

POST /plans — retorna 201 Created. O plano nasce em draft.

Parâmetros (body)

code
string
obrigatório
Identificador único do plano. 1 a 100 caracteres. Apenas letras minúsculas, números, hífen e underscore (regex ^[a-z0-9-_]+$).
name
string
obrigatório
Nome do plano. 1 a 255 caracteres.
description
string
Descrição livre. Até 1000 caracteres. Opcional.
metadata
object
Objeto livre de chave/valor para dados próprios. Opcional.
curl -X POST https://billing-api.sandbox.z2pay.com/plans \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7f1c0a2e-create-plan-pro" \
  -d '{
    "code": "plano-pro",
    "name": "Plano Pro",
    "description": "Acesso completo, cobrado mensalmente",
    "metadata": { "tier": "pro" }
  }'
{
  "id": "plan_8aZqkR3v2NfLpW0d",
  "companyId": "comp_4yT2bX",
  "code": "plano-pro",
  "name": "Plano Pro",
  "description": "Acesso completo, cobrado mensalmente",
  "status": "draft",
  "metadata": { "tier": "pro" },
  "createdAt": "2026-06-24T13:40:11.000Z",
  "updatedAt": "2026-06-24T13:40:11.000Z",
  "deletedAt": null
}
Se já existir um plano com o mesmo code, a API responde 409 Conflict. Veja Erros.

Listar planos

GET /plans — retorna 200 OK com uma lista paginada.

Parâmetros (query)

status
string
Filtra por status. Aceita CSV (?status=active,draft). Valores válidos: draft, active, inactive, archived. Até 100 caracteres.
Busca rápida — match parcial em code OU name. Até 100 caracteres.
code
string
Match parcial no campo code. Até 100 caracteres.
name
string
Match parcial no campo name. Até 255 caracteres.
item
string
Match parcial no nome de algum componente do plano. Até 255 caracteres.
priceMin
integer
Inclui só planos com algum componente cujo preço corrente seja maior ou igual a este valor (em centavos). Mínimo 0.
priceMax
integer
Inclui só planos com algum componente cujo preço corrente seja menor ou igual a este valor (em centavos). Mínimo 0.
createdFrom
string
Data ISO 8601 (com offset) ou data simples (YYYY-MM-DD). Inclui só planos criados a partir desta data (inclusivo).
createdTo
string
Data ISO 8601 (com offset) ou data simples (YYYY-MM-DD). Inclui só planos criados até esta data (inclusivo).
sortBy
string
Campo de ordenação. Valores válidos: createdAt, name.
sortDir
string
Direção da ordenação. Valores válidos: asc, desc.
page
integer
Página da paginação.
limit
integer
Quantidade de itens por página.
curl "https://billing-api.sandbox.z2pay.com/plans?status=active,draft&page=1&limit=20" \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Buscar plano por ID

GET /plans/{id} — retorna 200 OK ou 404 Not Found se o plano não existir.
curl https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Template do plano

GET /plans/{id}/template — retorna 200 OK com o plano mais cada componente acompanhado do seu preço corrente. 404 Not Found se o plano não existir.

Parâmetros (query)

currency
string
Restringe os preços a uma única moeda (ex.: BRL). Opcional — sem ela, retorna o preço corrente de cada componente em todas as moedas.
curl "https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/template?currency=BRL" \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Atualizar plano

PATCH /plans/{id} — atualização parcial. Retorna 200 OK ou 404 Not Found.
Passe apenas os campos que quer alterar. Transições de status não são feitas aqui — use publish / archive.

Parâmetros (body)

name
string
Novo nome. 1 a 255 caracteres. Opcional.
description
string
Nova descrição. Até 1000 caracteres. Aceita null para limpar. Opcional.
metadata
object
Novo objeto de metadados. Opcional.
curl -X PATCH https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Plano Pro (anual)" }'

Publicar e arquivar plano

POST /plans/{id}/publish leva o plano de draft para active. POST /plans/{id}/archive arquiva o plano. Ambos retornam 200 OK ou 404 Not Found.
Um plano só pode ser publicado se tiver pelo menos um componente recorrente com preço — caso contrário, assinaturas criadas em cima dele gerariam faturas sem itens. Crie a cobrança antes de publicar.
curl -X POST https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/publish \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Componentes (plan_items)

Cada componente é uma cobrança dentro do plano.
  • recurring — cobrado todo ciclo. Vira um item de assinatura quando uma assinatura é criada a partir do plano.
  • activation — cobrado/entregue uma vez, na adesão. Materializa na fatura de adesão.
O default é recurring.

Adicionar componente

POST /plans/{id}/items — retorna 201 Created. 404 se o plano não existir, 409 se o key já existir no plano.
key
string
obrigatório
Slug estável, único por plano. 1 a 100 caracteres. Apenas letras minúsculas, números, hífen e underscore (regex ^[a-z0-9-_]+$).
name
string
obrigatório
Nome do componente. 1 a 255 caracteres.
kind
string
padrão:"recurring"
recurring (cobrado todo ciclo) ou activation (cobrado uma vez, na adesão).
quantityDefault
integer
padrão:1
Quantidade padrão. Inteiro positivo.
quantityIncluded
integer
padrão:0
Quantidade já incluída (não cobrada além). Inteiro maior ou igual a 0.
optional
boolean
padrão:false
Se o componente é opcional no bundle.
displayOrder
integer
padrão:0
Ordem de exibição. Inteiro maior ou igual a 0.
description
string
Descrição. Até 1000 caracteres. Opcional.
metadata
object
Objeto livre. Opcional.
curl -X POST https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/items \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "assinatura-base",
    "name": "Assinatura base",
    "kind": "recurring",
    "quantityDefault": 1,
    "quantityIncluded": 0,
    "optional": false,
    "displayOrder": 0
  }'
{
  "id": "pli_2bN7xQ9wKtLm4Rd0",
  "companyId": "comp_4yT2bX",
  "planId": "plan_8aZqkR3v2NfLpW0d",
  "key": "assinatura-base",
  "name": "Assinatura base",
  "kind": "recurring",
  "quantityDefault": 1,
  "quantityIncluded": 0,
  "optional": false,
  "displayOrder": 0,
  "description": null,
  "metadata": {},
  "createdAt": "2026-06-24T13:42:30.000Z",
  "updatedAt": "2026-06-24T13:42:30.000Z",
  "deletedAt": null
}

Listar, atualizar e arquivar componentes

GET /plans/{id}/items lista os componentes (não paginado). PATCH /plans/{id}/items/{itemId} atualiza um componente (200 / 404). DELETE /plans/{id}/items/{itemId} arquiva um componente (200 / 404).
No PATCH, os campos editáveis são: name, quantityDefault, quantityIncluded, optional, displayOrder, description (aceita null) e metadata. Todos opcionais. key e kind não são editáveis.
O componente default (presente em planos legados) não pode ser arquivado — o DELETE responde 409 Conflict nesse caso.
curl -X DELETE https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/items/pli_2bN7xQ9wKtLm4Rd0 \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Preços (prices)

Cada preço é uma versão de cobrança de um componente, sempre em centavos.

Criar versão de preço

POST /plans/{id}/prices — retorna 201 Created e marca este preço como corrente. 404 se o plano não existir.
Criar um preço novo marca automaticamente o preço anterior da mesma combinação (moeda, recorrência) como não-corrente.
planItemId
string
ID do componente (plan_items.id) que este preço versiona. 1 a 36 caracteres. Opcional — preferido quando você acabou de criar o componente.
planItemKey
string
Slug do componente (plan_items.key). 1 a 100 caracteres, regex ^[a-z0-9-_]+$. Opcional. Se nem planItemId nem planItemKey forem informados, usa o componente default (legado).
billingScheme
string
padrão:"fixed"
Esquema de cobrança. Valores válidos: fixed, tiered, per_unit, package, metered.
money
object
obrigatório
Valor do preço.
recurrence
object
obrigatório
Regra de recorrência.
tiers
array
Faixas de preço (para billingScheme=tiered). Cada faixa tem upTo (inteiro positivo ou null na última faixa, indicando infinito) e unitAmount (centavos, inteiro maior ou igual a 0). Opcional.
packageSize
integer
Tamanho do pacote (para billingScheme=package). Inteiro positivo. Opcional.
meterId
string
Identificador do medidor (para billingScheme=metered). Até 100 caracteres. Opcional.
trialSpec
object
Configuração de trial. Opcional.
Combinações inválidas de anchor / unit / anchorDay são rejeitadas: anchorDay é obrigatório quando anchor=day_of_month, e anchor=day_of_month/end_of_month só vale com unit=month ou unit=year.
curl -X POST https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/prices \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3d8e1b40-price-pro-mensal" \
  -d '{
    "planItemId": "pli_2bN7xQ9wKtLm4Rd0",
    "billingScheme": "fixed",
    "money": { "amount": 4990, "currency": "BRL" },
    "recurrence": {
      "interval": 1,
      "unit": "month",
      "anchor": "subscription_start",
      "collectionTiming": "prepaid"
    },
    "trialSpec": { "durationDays": 7, "requiresPaymentMethod": true }
  }'
{
  "id": "price_5cM3pV8nDhQr2Yt9",
  "planItemId": "pli_2bN7xQ9wKtLm4Rd0",
  "planId": "plan_8aZqkR3v2NfLpW0d",
  "billingScheme": "fixed",
  "amount": 4990,
  "currency": "BRL",
  "recurrence": {
    "interval": 1,
    "unit": "month",
    "anchor": "subscription_start",
    "collectionTiming": "prepaid"
  },
  "tiers": null,
  "packageSize": null,
  "meterId": null,
  "trialSpec": { "durationDays": 7, "requiresPaymentMethod": true },
  "isCurrent": true,
  "publishedAt": "2026-06-24T13:45:02.000Z",
  "archivedAt": null,
  "createdAt": "2026-06-24T13:45:02.000Z",
  "updatedAt": "2026-06-24T13:45:02.000Z"
}

Listar e arquivar preços

GET /plans/{id}/prices lista as versões de preço do plano (não paginado). POST /plans/{id}/prices/{priceId}/archive arquiva uma versão específica (200 / 404).
curl -X POST https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/prices/price_5cM3pV8nDhQr2Yt9/archive \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Criar cobrança (componente + preço) atomicamente

POST /plans/{id}/charges — retorna 201 Created com { item, price }. 400 se a validação falhar (item ou preço), 404 se o plano não existir.
Cria o componente e seu preço inicial numa única transação. O Zod valida ambos os bodies antes de qualquer escrita — se a validação falhar, nada é persistido (evita componentes órfãos do fluxo POST /items + POST /prices em sequência).
item
object
obrigatório
Mesmos campos de Adicionar componente (key, name, kind, etc.).
price
object
obrigatório
Mesmos campos de Criar versão de preço, exceto planItemId e planItemKey — o service liga o preço ao componente recém-criado automaticamente.
curl -X POST https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/charges \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a1c4-charge-base" \
  -d '{
    "item": {
      "key": "assinatura-base",
      "name": "Assinatura base",
      "kind": "recurring"
    },
    "price": {
      "billingScheme": "fixed",
      "money": { "amount": 4990, "currency": "BRL" },
      "recurrence": {
        "interval": 1,
        "unit": "month",
        "anchor": "subscription_start"
      }
    }
  }'
{
  "item": {
    "id": "pli_2bN7xQ9wKtLm4Rd0",
    "planId": "plan_8aZqkR3v2NfLpW0d",
    "key": "assinatura-base",
    "name": "Assinatura base",
    "kind": "recurring"
  },
  "price": {
    "id": "price_5cM3pV8nDhQr2Yt9",
    "planItemId": "pli_2bN7xQ9wKtLm4Rd0",
    "planId": "plan_8aZqkR3v2NfLpW0d",
    "billingScheme": "fixed",
    "amount": 4990,
    "currency": "BRL",
    "isCurrent": true
  }
}

Fluxo recomendado

1

Crie o plano

POST /plans com code e name. Ele nasce em draft.
2

Adicione a cobrança

Use POST /plans/{id}/charges para criar o componente recorrente e seu preço de uma vez, ou faça POST /plans/{id}/items seguido de POST /plans/{id}/prices.
3

Publique o plano

POST /plans/{id}/publish leva o plano para active, permitindo criar assinaturas.
Com o plano active e ao menos um componente recorrente com preço, você já pode criar assinaturas.

Veja também

Assinaturas

Crie e gerencie assinaturas a partir de um plano publicado.

Faturas

Como as faturas são geradas e cobradas a cada ciclo.

Ciclos

Entenda a cadência, âncoras e o timing de cobrança.

Visão geral de assinaturas

Panorama do módulo de cobrança recorrente.