Famílias de Produtos

Agrupe produtos e planos relacionados sob uma única entidade de catálogo e defina um comportamento padrão de cobrança na mudança para transições de ofertas dentro do grupo.

Uma família de produtos agrupa produtos e planos relacionados em uma única entidade de catálogo — por exemplo, os níveis de uma mesma assinatura (Light, Pro, Premium) ou um conjunto de complementos avulsos vendidos em conjunto. As famílias dão estrutura ao seu catálogo: em vez de uma lista plana de produtos, você modela as relações entre eles.

Uma família também carrega um comportamento padrão de cobrança na mudança — a regra aplicada quando uma assinatura passa de uma oferta para outra pertencente a produtos da mesma família (um upgrade, downgrade ou troca de plano). Defina-o uma vez na família, e toda transição dentro dessa família o herda, a menos que seja sobrescrito.

A Tokeflow orquestra pagamentos; ela não processa nem liquida fundos. As famílias de produtos são pura modelagem de catálogo — elas descrevem o que você vende e como as mudanças de plano são cobradas, nunca quem movimenta o dinheiro.

As famílias de produtos fazem parte do catálogo, que tem escopo de Merchant. Com uma chave de Merchant, o merchant é inferido. Com uma chave de Organization, direcione a um merchant com o parâmetro de query merchant_id (em list/get) ou o campo de corpo (em create). Consulte Autenticação.

Onde as famílias se encaixam

Uma família fica no topo da hierarquia do catálogo. Os produtos pertencem a uma família; ofertas e preços derivam dos produtos; assinaturas se apoiam em ofertas.

Quando um assinante faz a transição de uma oferta em um produto para uma oferta em outro produto da mesma família, o change_charge_behavior da família decide como a mudança é cobrada.

O comportamento de cobrança na mudança

change_charge_behavior define o tratamento de cobrança padrão para transições de ofertas dentro da família.

ValueMeaning
next_renewAplica a mudança na próxima renovação — o novo preço passa a valer no ciclo de faturamento seguinte.
proratedRateia a diferença para o ciclo atual.
overrideSubstitui a cobrança atual pelos termos da nova oferta imediatamente.

Se você omitir change_charge_behavior na criação, a família assume o padrão next_renew.

O mecanismo de transição executa os três comportamentos — next_renew, prorated e override. O change_charge_behavior padrão armazenado na família é aplicado a cada mudança dentro dela, a menos que uma transição de oferta substitua um par específico.

O objeto de família de produtos

FieldTypeDescription
idstringIdentificador único, prefixado com pfa_.
merchant_idstringMerchant proprietário, prefixado com mrc_.
namestringNome legível para humanos, por exemplo Streaming Plans.
slugstringIdentificador em minúsculas, único por merchant.
descriptionstring | nullDescrição opcional em texto livre.
custom_plan_idstring | nullReferência opcional a um plano externo, apenas para exibição. Único por merchant quando definido.
change_charge_behaviorenumComportamento de transição padrão: next_renew, prorated ou override.
created_atstringTimestamp de criação em ISO 8601 UTC.
updated_atstringTimestamp da última atualização em ISO 8601 UTC.
deleted_atstring | nullTimestamp de exclusão lógica em ISO 8601 UTC, ou null quando ativo. Presente apenas em registros com exclusão lógica.
{
  "id": "pfa_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "name": "Streaming Plans",
  "slug": "streaming-plans",
  "description": "Family of streaming subscription plans",
  "custom_plan_id": "plan_external_42",
  "change_charge_behavior": "next_renew",
  "created_at": "2026-05-19T12:00:00.000Z",
  "updated_at": "2026-05-19T12:00:00.000Z"
}

Criar uma família de produtos

POST/api/v1/product-families

Auth: chave de Organization (com merchant_id) ou chave de Merchant. Requer o escopo products:write.

Cria uma nova família no catálogo do merchant de destino.

Parâmetros de corpo

FieldTypeRequiredDescription
namestringSimNome legível para humanos.
slugstringSimIdentificador em minúsculas, único por merchant (entre famílias ativas).
descriptionstringNãoDescrição em texto livre.
custom_plan_idstringNãoReferência a um plano externo (apenas para exibição), única por merchant quando definida.
change_charge_behaviorenumNãonext_renew (padrão), prorated ou override.
merchant_idstringCondicionalObrigatório apenas com uma chave de Organization, para direcionar a um merchant. Inferido a partir de uma chave de Merchant.
curl -X POST https://api.tokeflow.com/api/v1/product-families \
  -H "Authorization: Bearer sk_live_mer_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f3c1d20-9b4a-4e2c-9f6a-2c1d0e7b5a44" \
  -d '{
    "name": "Streaming Plans",
    "slug": "streaming-plans",
    "description": "Family of streaming subscription plans",
    "custom_plan_id": "plan_external_42",
    "change_charge_behavior": "next_renew"
  }'

Resposta 201 Created

{
  "success": true,
  "data": {
    "id": "pfa_a1b2c3d4e5",
    "merchant_id": "mrc_a1b2c3d4e5",
    "name": "Streaming Plans",
    "slug": "streaming-plans",
    "description": "Family of streaming subscription plans",
    "custom_plan_id": "plan_external_42",
    "change_charge_behavior": "next_renew",
    "created_at": "2026-05-19T12:00:00.000Z",
    "updated_at": "2026-05-19T12:00:00.000Z"
  },
  "request_id": "req_8f3c1d20",
  "timestamp": "2026-05-19T12:00:00.000Z"
}

Envie um cabeçalho Idempotency-Key na criação. Repetir a mesma chave retorna o resultado original (HTTP 200 no replay vs 201 na primeira criação) em vez de criar uma duplicata. Consulte Idempotência e limites de taxa.

slug deve ser único por merchant entre as famílias ativas. Uma duplicata retorna 409 (conflict_error). O mesmo se aplica a custom_plan_id quando definido.


Listar famílias de produtos

GET/api/v1/product-families

Auth: chave de Organization (com merchant_id) ou chave de Merchant. Requer o escopo products:read.

Retorna uma lista paginada de famílias do merchant, das mais recentes para as mais antigas.

Parâmetros de query

FieldTypeRequiredDescription
namestringNãoFiltro de correspondência parcial (sem diferenciar maiúsculas de minúsculas) no nome da família.
slugstringNãoFiltra por slug exato.
change_charge_behaviorenumNãoFiltra por next_renew, prorated ou override.
pageintegerNãoNúmero da página, padrão 1, mínimo 1.
limitintegerNãoItens por página, padrão 20, máximo 100.
merchant_idstringCondicionalObrigatório apenas com uma chave de Organization.
curl -G https://api.tokeflow.com/api/v1/product-families \
  -H "Authorization: Bearer sk_live_mer_…" \
  --data-urlencode "page=1" \
  --data-urlencode "limit=20" \
  --data-urlencode "name=Streaming" \
  --data-urlencode "change_charge_behavior=next_renew"

Resposta 200 OK

{
  "success": true,
  "data": [
    {
      "id": "pfa_a1b2c3d4e5",
      "merchant_id": "mrc_a1b2c3d4e5",
      "name": "Streaming Plans",
      "slug": "streaming-plans",
      "description": "Family of streaming subscription plans",
      "custom_plan_id": "plan_external_42",
      "change_charge_behavior": "next_renew",
      "created_at": "2026-05-19T12:00:00.000Z",
      "updated_at": "2026-05-19T12:00:00.000Z"
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "limit": 20,
      "total": 1,
      "total_pages": 1,
      "has_next": false,
      "has_prev": false
    }
  },
  "request_id": "req_8f3c1d20",
  "timestamp": "2026-05-19T12:00:00.000Z"
}

Obter uma família de produtos

GET/api/v1/product-families/:id

Auth: chave de Organization (com merchant_id) ou chave de Merchant. Requer o escopo products:read.

Recupera uma única família pelo ID.

curl https://api.tokeflow.com/api/v1/product-families/pfa_a1b2c3d4e5 \
  -H "Authorization: Bearer sk_live_mer_…"

Resposta 200 OK

{
  "success": true,
  "data": {
    "id": "pfa_a1b2c3d4e5",
    "merchant_id": "mrc_a1b2c3d4e5",
    "name": "Streaming Plans",
    "slug": "streaming-plans",
    "description": "Family of streaming subscription plans",
    "custom_plan_id": "plan_external_42",
    "change_charge_behavior": "next_renew",
    "created_at": "2026-05-19T12:00:00.000Z",
    "updated_at": "2026-05-19T12:00:00.000Z"
  },
  "request_id": "req_8f3c1d20",
  "timestamp": "2026-05-19T12:00:00.000Z"
}

Um ID desconhecido retorna 404 (not_found_error).


Atualizar uma família de produtos

PATCH/api/v1/product-families/:id

Auth: chave de Organization (com merchant_id) ou chave de Merchant. Requer o escopo products:write.

Atualiza parcialmente uma família. Envie apenas os campos que deseja alterar. Todos os campos de criação são atualizáveis: name, slug, description, custom_plan_id e change_charge_behavior.

curl -X PATCH https://api.tokeflow.com/api/v1/product-families/pfa_a1b2c3d4e5 \
  -H "Authorization: Bearer sk_live_mer_…" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "All streaming subscription tiers",
    "change_charge_behavior": "prorated"
  }'

Resposta 200 OK

{
  "success": true,
  "data": {
    "id": "pfa_a1b2c3d4e5",
    "merchant_id": "mrc_a1b2c3d4e5",
    "name": "Streaming Plans",
    "slug": "streaming-plans",
    "description": "All streaming subscription tiers",
    "custom_plan_id": "plan_external_42",
    "change_charge_behavior": "prorated",
    "created_at": "2026-05-19T12:00:00.000Z",
    "updated_at": "2026-05-20T09:15:00.000Z"
  },
  "request_id": "req_8f3c1d20",
  "timestamp": "2026-05-20T09:15:00.000Z"
}

Alterar slug ou custom_plan_id para um valor já usado por outra família ativa no mesmo merchant retorna 409 (conflict_error).


Excluir logicamente uma família de produtos

DELETE/api/v1/product-families/:id

Auth: chave de Organization (com merchant_id) ou chave de Merchant. Requer o escopo products:write.

Faz a exclusão lógica da família. O registro é mantido com um timestamp deleted_at e excluído dos resultados de list e get, preservando a auditabilidade. As posições de slug e custom_plan_id são liberadas para reutilização por novas famílias ativas.

curl -X DELETE https://api.tokeflow.com/api/v1/product-families/pfa_a1b2c3d4e5 \
  -H "Authorization: Bearer sk_live_mer_…"

Resposta 204 No Content

O corpo da resposta está vazio. Um ID desconhecido retorna 404 (not_found_error).

Esta é uma exclusão lógica — a família pode ser recuperada com o endpoint de restauração abaixo.


Restaurar uma família de produtos

POST/api/v1/product-families/:id/restore

Auth: chave de Organization (com merchant_id) ou chave de Merchant. Requer o escopo products:write.

Restaura uma família com exclusão lógica, limpando seu deleted_at. A restauração recupera o slug e o custom_plan_id originais somente se nenhuma família ativa os tiver assumido nesse meio-tempo.

curl -X POST https://api.tokeflow.com/api/v1/product-families/pfa_a1b2c3d4e5/restore \
  -H "Authorization: Bearer sk_live_mer_…"

Resposta 201 Created

{
  "success": true,
  "data": {
    "id": "pfa_a1b2c3d4e5",
    "merchant_id": "mrc_a1b2c3d4e5",
    "name": "Streaming Plans",
    "slug": "streaming-plans",
    "description": "All streaming subscription tiers",
    "custom_plan_id": "plan_external_42",
    "change_charge_behavior": "prorated",
    "created_at": "2026-05-19T12:00:00.000Z",
    "updated_at": "2026-05-21T11:00:00.000Z"
  },
  "request_id": "req_8f3c1d20",
  "timestamp": "2026-05-21T11:00:00.000Z"
}

Casos de erro

ConditionHTTPType
A família já está ativa (sem exclusão lógica)400validation_error
Uma família ativa agora detém o mesmo slug409conflict_error
Uma família ativa agora detém o mesmo custom_plan_id409conflict_error
Família não encontrada404not_found_error

Se a restauração falhar com um conflito de slug ou custom_plan_id, renomeie ou arquive a família ativa que detém a posição e, em seguida, tente a restauração novamente.

Erros

Todos os erros usam o envelope padrão. Consulte Erros para o catálogo completo.

{
  "error": {
    "type": "conflict_error",
    "code": "PRODUCT_FAMILY_SLUG_TAKEN",
    "message": "Product family with slug 'streaming-plans' already exists",
    "details": {},
    "request_id": "req_8f3c1d20",
    "timestamp": "2026-05-19T12:00:00.000Z"
  }
}

Relacionados

Nesta página