Saltar al contenido principal
Un plan es el template de cobro recurrente de Z2Pay. Está compuesto por componentes (plan_items) — cada uno representa un cobro del bundle — y cada componente tiene una o más versiones de precio (prices), siempre en centavos. El flujo típico es: crear el plan en draft, agregar al menos un componente recurrente con precio (o usar el endpoint atómico de cobro), y publicar el plan para que acepte suscripciones.
Todos los endpoints de esta página requieren el header x-api-key. Consulta Autenticación. Los ejemplos usan la base URL de sandbox https://billing-api.sandbox.z2pay.com.

Conceptos

Plan

Template de cobro identificado por un code único. Nace en draft y debe ser publicado. IDs con prefijo plan_.

Componente (plan_item)

Cada cobro dentro del plan. Puede ser recurring (cobrado en cada ciclo) o activation (cobrado una vez, en la adhesión). IDs con prefijo pli_.

Precio (price)

Versión de precio de un componente, en centavos. Crear un precio nuevo marca el anterior de la misma combinación (moneda, recurrencia) como no vigente. IDs con prefijo price_.

Recurrencia

Define la cadencia (unit + interval), el ancla del ciclo y cuándo cobrar (prepaid/postpaid).

Endpoints

MétodoRutaDescripción
POST/plansCrea un plan en draft
GET/plansLista planes (paginado, con filtros)
GET/plans/{id}Obtiene un plan por ID
PATCH/plans/{id}Actualiza campos editables del plan
POST/plans/{id}/publishPublica el plan (draftactive)
POST/plans/{id}/archiveArchiva el plan
GET/plans/{id}/templatePlan + componentes con el precio vigente de cada uno
GET/plans/{id}/itemsLista los componentes del plan
POST/plans/{id}/itemsAgrega un componente al plan
PATCH/plans/{id}/items/{itemId}Actualiza un componente
DELETE/plans/{id}/items/{itemId}Archiva un componente
GET/plans/{id}/pricesLista las versiones de precio del plan
POST/plans/{id}/pricesCrea una nueva versión de precio
POST/plans/{id}/prices/{priceId}/archiveArchiva una versión de precio
POST/plans/{id}/chargesCrea componente + precio de forma atómica
Los POSTs aceptan el header opcional Idempotency-Key para repetir la solicitud de forma segura. Consulta Convenciones.

Crear plan

POST /plans — retorna 201 Created. El plan nace en draft.

Parámetros (body)

code
string
requerido
Identificador único del plan. De 1 a 100 caracteres. Solo letras minúsculas, números, guiones y guiones bajos (regex ^[a-z0-9-_]+$).
name
string
requerido
Nombre del plan. De 1 a 255 caracteres.
description
string
Descripción libre. Hasta 1000 caracteres. Opcional.
metadata
object
Objeto libre de clave/valor para datos propios. 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
}
Si ya existe un plan con el mismo code, la API responde 409 Conflict. Consulta Errores.

Listar planes

GET /plans — retorna 200 OK con una lista paginada.

Parámetros (query)

status
string
Filtra por estado. Acepta CSV (?status=active,draft). Valores válidos: draft, active, inactive, archived. Hasta 100 caracteres.
Búsqueda rápida — coincidencia parcial en code O name. Hasta 100 caracteres.
code
string
Coincidencia parcial en el campo code. Hasta 100 caracteres.
name
string
Coincidencia parcial en el campo name. Hasta 255 caracteres.
item
string
Coincidencia parcial en el nombre de algún componente del plan. Hasta 255 caracteres.
priceMin
integer
Incluye solo planes con algún componente cuyo precio vigente sea mayor o igual a este valor (en centavos). Mínimo 0.
priceMax
integer
Incluye solo planes con algún componente cuyo precio vigente sea menor o igual a este valor (en centavos). Mínimo 0.
createdFrom
string
Fecha ISO 8601 (con offset) o fecha simple (YYYY-MM-DD). Incluye solo planes creados a partir de esta fecha (inclusivo).
createdTo
string
Fecha ISO 8601 (con offset) o fecha simple (YYYY-MM-DD). Incluye solo planes creados hasta esta fecha (inclusivo).
sortBy
string
Campo de ordenamiento. Valores válidos: createdAt, name.
sortDir
string
Dirección del ordenamiento. Valores válidos: asc, desc.
page
integer
Página de la paginación.
limit
integer
Cantidad de ítems 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"

Obtener plan por ID

GET /plans/{id} — retorna 200 OK o 404 Not Found si el plan no existe.
curl https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Template del plan

GET /plans/{id}/template — retorna 200 OK con el plan más cada componente acompañado de su precio vigente. 404 Not Found si el plan no existe.

Parámetros (query)

currency
string
Restringe los precios a una única moneda (ej.: BRL). Opcional — sin él, retorna el precio vigente de cada componente en todas las monedas.
curl "https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/template?currency=BRL" \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Actualizar plan

PATCH /plans/{id} — actualización parcial. Retorna 200 OK o 404 Not Found.
Envía solo los campos que deseas modificar. Las transiciones de estado no se realizan aquí — usa publish / archive.

Parámetros (body)

name
string
Nuevo nombre. De 1 a 255 caracteres. Opcional.
description
string
Nueva descripción. Hasta 1000 caracteres. Acepta null para limpiar. Opcional.
metadata
object
Nuevo objeto de metadatos. 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 y archivar plan

POST /plans/{id}/publish lleva el plan de draft a active. POST /plans/{id}/archive archiva el plan. Ambos retornan 200 OK o 404 Not Found.
Un plan solo puede publicarse si tiene al menos un componente recurrente con precio — de lo contrario, las suscripciones creadas sobre él generarían facturas sin ítems. Crea el cobro 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 es un cobro dentro del plan.
  • recurring — cobrado en cada ciclo. Se convierte en un ítem de suscripción cuando se crea una suscripción a partir del plan.
  • activation — cobrado/entregado una vez, en la adhesión. Se materializa en la factura de adhesión.
El valor por defecto es recurring.

Agregar componente

POST /plans/{id}/items — retorna 201 Created. 404 si el plan no existe, 409 si el key ya existe en el plan.
key
string
requerido
Slug estable, único por plan. De 1 a 100 caracteres. Solo letras minúsculas, números, guiones y guiones bajos (regex ^[a-z0-9-_]+$).
name
string
requerido
Nombre del componente. De 1 a 255 caracteres.
kind
string
predeterminado:"recurring"
recurring (cobrado en cada ciclo) o activation (cobrado una vez, en la adhesión).
quantityDefault
integer
predeterminado:1
Cantidad por defecto. Entero positivo.
quantityIncluded
integer
predeterminado:0
Cantidad ya incluida (no cobrada adicionalmente). Entero mayor o igual a 0.
optional
boolean
predeterminado:false
Si el componente es opcional en el bundle.
displayOrder
integer
predeterminado:0
Orden de visualización. Entero mayor o igual a 0.
description
string
Descripción. Hasta 1000 caracteres. Opcional.
metadata
object
Objeto libre. 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, actualizar y archivar componentes

GET /plans/{id}/items lista los componentes (sin paginación). PATCH /plans/{id}/items/{itemId} actualiza un componente (200 / 404). DELETE /plans/{id}/items/{itemId} archiva un componente (200 / 404).
En el PATCH, los campos editables son: name, quantityDefault, quantityIncluded, optional, displayOrder, description (acepta null) y metadata. Todos opcionales. key y kind no son editables.
El componente default (presente en planes heredados) no puede archivarse — el DELETE responde 409 Conflict en ese caso.
curl -X DELETE https://billing-api.sandbox.z2pay.com/plans/plan_8aZqkR3v2NfLpW0d/items/pli_2bN7xQ9wKtLm4Rd0 \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"

Precios (prices)

Cada precio es una versión de cobro de un componente, siempre en centavos.

Crear versión de precio

POST /plans/{id}/prices — retorna 201 Created y marca este precio como vigente. 404 si el plan no existe.
Crear un precio nuevo marca automáticamente el precio anterior de la misma combinación (moneda, recurrencia) como no vigente.
planItemId
string
ID del componente (plan_items.id) que este precio versiona. De 1 a 36 caracteres. Opcional — preferido cuando acabas de crear el componente.
planItemKey
string
Slug del componente (plan_items.key). De 1 a 100 caracteres, regex ^[a-z0-9-_]+$. Opcional. Si no se informa ni planItemId ni planItemKey, usa el componente default (heredado).
billingScheme
string
predeterminado:"fixed"
Esquema de cobro. Valores válidos: fixed, tiered, per_unit, package, metered.
money
object
requerido
Valor del precio.
recurrence
object
requerido
Regla de recurrencia.
tiers
array
Tramos de precio (para billingScheme=tiered). Cada tramo tiene upTo (entero positivo o null en el último tramo, indicando infinito) y unitAmount (centavos, entero mayor o igual a 0). Opcional.
packageSize
integer
Tamaño del paquete (para billingScheme=package). Entero positivo. Opcional.
meterId
string
Identificador del medidor (para billingScheme=metered). Hasta 100 caracteres. Opcional.
trialSpec
object
Configuración del período de prueba. Opcional.
Las combinaciones inválidas de anchor / unit / anchorDay son rechazadas: anchorDay es obligatorio cuando anchor=day_of_month, y anchor=day_of_month/end_of_month solo es válido con unit=month o 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 y archivar precios

GET /plans/{id}/prices lista las versiones de precio del plan (sin paginación). POST /plans/{id}/prices/{priceId}/archive archiva una versión 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"

Crear cobro (componente + precio) de forma atómica

POST /plans/{id}/charges — retorna 201 Created con { item, price }. 400 si la validación falla (ítem o precio), 404 si el plan no existe.
Crea el componente y su precio inicial en una única transacción. Zod valida ambos bodies antes de cualquier escritura — si la validación falla, nada se persiste (evita componentes huérfanos del flujo POST /items + POST /prices en secuencia).
item
object
requerido
Mismos campos de Agregar componente (key, name, kind, etc.).
price
object
requerido
Mismos campos de Crear versión de precio, excepto planItemId y planItemKey — el servicio vincula el precio al componente recién creado de forma automática.
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
  }
}

Flujo recomendado

1

Crea el plan

POST /plans con code y name. Nace en draft.
2

Agrega el cobro

Usa POST /plans/{id}/charges para crear el componente recurrente y su precio de una sola vez, o realiza POST /plans/{id}/items seguido de POST /plans/{id}/prices.
3

Publica el plan

POST /plans/{id}/publish lleva el plan a active, permitiendo crear suscripciones.
Con el plan active y al menos un componente recurrente con precio, ya puedes crear suscripciones.

Ver también

Suscripciones

Crea y gestiona suscripciones a partir de un plan publicado.

Facturas

Cómo se generan y cobran las facturas en cada ciclo.

Ciclos

Entiende la cadencia, las anclas y el timing de cobro.

Visión general de suscripciones

Panorama del módulo de cobro recurrente.