Guia Completo do Ciclo de Vida do Produto
Este guia fornece um passo a passo completo do ciclo de vida do produto no OmniCRM, desde a criação de uma definição de produto até a provisão de serviços, adição de complementos e desprovisionamento. Abordaremos a estratégia de preços, integração com Ansible e forneceremos exemplos do mundo real ao longo do caminho.
Visão Geral: A Jornada do Produto ao Serviço
O ciclo de vida de um produto no OmniCRM segue estas etapas:
- Definição do Produto - O administrador cria um modelo de produto com regras de preços e provisão.
- Criação do Serviço - O cliente solicita o produto, o sistema provisiona a instância do serviço.
- Ciclo de Vida do Serviço - O cliente utiliza o serviço, adiciona complementos/recargas, modifica o serviço.
- Desprovisionamento - O serviço é encerrado, os recursos são liberados.
Compreendendo Preços: Atacado vs Varejo
Cada produto e serviço no OmniCRM possui duas dimensões de preços: atacado e varejo.
Custo de Atacado
O custo de atacado representa o custo real para entregar o serviço:
- Custos de infraestrutura e largura de banda
- Taxas de licenciamento
- Custos de equipamentos
- Despesas operacionais
Custo de Varejo
O custo de varejo é o valor cobrado ao cliente.
Custos de Configuração
Tanto o atacado quanto o varejo têm variantes de custo de configuração para cobranças de provisão únicas:
wholesale_setup_cost- Seu custo para provisionarretail_setup_cost- Valor cobrado ao cliente pela ativação
Exemplo:
{
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00
}
Etapa 1: Criando uma Definição de Produto
Produtos são modelos que definem o que é provisionado e como os clientes são cobrados.
Criando um Produto de SIM Móvel
Vamos criar um produto de SIM móvel pré-pago com 20GB de dados por mês.
Passo 1: Navegar para Gestão de Produtos
Na interface do administrador, vá para Produtos → Criar Produto.
Passo 2: Definir Informações Básicas
{
"product_name": "Prepaid Mobile 20GB",
"product_slug": "prepaid-mobile-20gb",
"category": "standalone",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-sim-card",
"comment": "Prepaid mobile SIM with 20GB data, unlimited calls & texts"
}
Explicações dos Campos:
product_name- Nome voltado para o cliente exibido no catálogo.product_slug- Identificador seguro para URL usado em chamadas de API e links.category- "standalone" significa que isso cria um novo serviço (vs complemento/pacote).service_type- Agrupa produtos relacionados, usado para filtragem de complementos.enabled- Deve ser verdadeiro para que o produto possa ser solicitado.icon- Ícone do FontAwesome exibido na interface.comment- Notas internas para referência da equipe.
Passo 3: Definir Preços
{
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00,
"contract_days": 30
}
Detalhamento de Preços:
- Receita mensal por cliente: £15.00
- Custo mensal para entrega: £5.00
- Margem de lucro mensal: £10.00 (200% de markup, 67% de margem)
- Lucro de configuração: -£1.00 (subvencionado para atrair clientes)
- Duração do contrato: 30 dias (renovação mensal)
Passo 4: Definir Elegibilidade do Cliente
{
"residential": true,
"business": false,
"customer_can_purchase": true,
"available_from": "2025-01-01T00:00:00Z",
"available_until": null
}
- Clientes residenciais podem solicitar.
- Clientes empresariais não podem (linha de produtos diferente).
- Compra autoatendida habilitada.
- Disponível a partir de 1º de janeiro de 2025.
- Sem data de término (oferta contínua).
Passo 5: Configurar Renovação Automática
{
"auto_renew": "prompt",
"allow_auto_renew": true
}
"prompt"- Perguntar ao cliente se deseja renovação automática na compra."true"- Renovar automaticamente sem perguntar."false"- Nunca renovar automaticamente (apenas recarga manual).allow_auto_renew: true- O cliente pode habilitar/desabilitar a renovação automática mais tarde.
Passo 6: Especificar Requisitos de Inventário
Os requisitos de inventário definem quais recursos físicos ou virtuais devem ser alocados ao provisionar este produto. Esta é uma etapa crítica que conecta seu catálogo de produtos ao seu Sistema de Gestão de Inventário.
{
"inventory_items_list": "['SIM Card', 'Mobile Number']"
}
O que são Itens de Inventário?
Itens de inventário são recursos rastreáveis armazenados no sistema de inventário do OmniCRM. Cada item tem:
- Tipo - Definido pelo Modelo de Inventário (por exemplo, "SIM Card", "Mobile Number", "Modem").
- Atributos únicos - Números de série, endereços MAC, números de telefone, etc.
- Estado - Em Estoque, Atribuído, Descomissionado, etc.
- Localização - Localização física ou lógica.
Como Funcionam os Requisitos de Inventário:
A inventory_items_list é uma lista Python (como uma string) contendo nomes de tipos de inventário. Cada nome deve corresponder exatamente a um nome existente de Modelo de Inventário.
Exemplo de Requisitos de Inventário:
# Produto SIM Móvel
inventory_items_list: "['SIM Card', 'Mobile Number']"
# Serviço de internet fixa
inventory_items_list: "['Modem Router', 'Static IP Address']"
# Serviço digital (sem itens físicos)
inventory_items_list: "[]"
# Wireless fixo com CPE
inventory_items_list: "['Fixed Wireless CPE', 'IPv4 Address', 'IPv6 Prefix']"
O Processo do Seletor de Inventário
Quando um usuário provisiona um produto com requisitos de inventário, o sistema impõe um processo de seleção obrigatório:
1. Botão de Provisão Clicado
Após selecionar o produto, o usuário clica em "Provisionar". Em vez de provisionar imediatamente, o sistema verifica a inventory_items_list.
2. Modal do Seletor de Inventário Aparece
Se o inventário for necessário, um diálogo modal aparece com um dropdown separado para cada tipo de inventário:
3. Filtrando Inventário Disponível
O dropdown para cada tipo de inventário mostra apenas itens que são:
- Tipo Correto - Corresponde exatamente ao nome do modelo de inventário.
- Status Disponível -
item_stateé "New" ou "In Stock" (não "Assigned" ou "Damaged"). - Não Atribuído -
service_idecustomer_idsão NULL. - Em Estoque na Localização - Opcionalmente filtrado por localização de armazém/loja.
Exemplo de Opções de Dropdown:
Para o tipo de inventário "SIM Card", o dropdown pode mostrar:
Cada opção exibe:
- ID de Inventário ou número de referência.
- Identificador primário (
itemtext1- por exemplo, ICCID para SIM, número para telefone). - Localização atual (
item_location).
4. Seleção Necessária para Prosseguir
Regra Crítica: O provisionamento NÃO pode prosseguir sem selecionar todos os itens de inventário necessários.
- O botão "Continuar" é desativado até que todos os dropdowns tenham seleções.
- O usuário deve selecionar um item para cada tipo de inventário.
- O sistema valida as seleções antes de prosseguir.
5. Inventário Selecionado Passado para Ansible
Uma vez que o usuário clica em "Continuar", os IDs de inventário selecionados são passados para o playbook do Ansible como variáveis:
# Usuário selecionou:
# - ID de inventário do SIM Card: 5001
# - ID de inventário do Mobile Number: 5002
# Variáveis passadas para Ansible:
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001, # ID de Inventário
"Mobile Number": 5002, # ID de Inventário
"access_token": "eyJ..."
}
Nota: O nome da variável corresponde exatamente ao tipo de inventário. O playbook usa hostvars[inventory_hostname]['SIM Card'] para acessar o ID do inventário.
6. Playbook Busca Detalhes Completos do Inventário
O playbook do Ansible usa o ID do inventário para buscar detalhes completos:
- name: Get SIM Card details from inventory
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_sim
- name: Extract ICCID and IMSI
set_fact:
iccid: "{{ api_response_sim.json.itemtext1 }}"
imsi: "{{ api_response_sim.json.itemtext2 }}"
Agora o playbook tem todos os detalhes do SIM (ICCID, IMSI, etc.) para provisionar o assinante no HSS.
7. Estado do Inventário Alterado para "Atribuído"
Após a criação do registro de serviço, o playbook atualiza o inventário para vinculá-lo ao serviço:
- name: Assign SIM Card to Service
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body:
{
"service_id": "{{ service_creation_response.json.service_id }}",
"customer_id": "{{ customer_id }}",
"item_state": "Assigned"
}
Importante: A atribuição de inventário acontece durante a execução do playbook como uma tarefa específica, NÃO quando o botão de provisão é clicado. Isso significa:
- Risco de Dupla Atribuição: Entre clicar em "Provisionar" e o inventário ser atribuído, outro usuário poderia teoricamente selecionar o mesmo item de inventário.
- Melhor Prática: Para operações de alto volume, implemente bloqueio de inventário ou use transações de banco de dados.
- Rollback em Caso de Falha: Se o playbook falhar antes da atribuição do inventário, o inventário permanece não atribuído e disponível para reutilização.
Por que não atribuir mais cedo?
O inventário não é atribuído quando "Provisionar" é clicado porque:
- ID do Serviço Necessário: O
service_idnão existe até que o serviço seja criado no playbook. - Simplicidade de Rollback: Se o provisionamento falhar cedo (por exemplo, a criação da conta OCS falhar), o inventário não precisa de limpeza.
- Flexibilidade: O playbook pode decidir não atribuir inventário com base em lógica condicional.
Tratando Provisionamentos Falhados:
Quando um provisionamento falha após o inventário ser atribuído, o bloco de resgate deve liberar o inventário:
rescue:
- name: Release inventory on failure
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body:
{
"service_id": null,
"customer_id": null,
"item_state": "In Stock"
}
when: service_id is defined # Apenas se o serviço foi criado
Isso garante que o inventário não fique em um estado "Atribuído" para um serviço inexistente ou falhado.
Quando a Lista de Inventário Está Vazia
Se inventory_items_list: "[]" (lista vazia), o seletor de inventário é completamente pulado e o provisionamento prossegue imediatamente. Isso é comum para:
- Produtos digitais - Licenças de software, contas de VPN.
- Complementos de serviço - Recargas de dados que não precisam de novo hardware.
- Serviços virtuais - Que não consomem recursos rastreáveis.
Exemplo: Um complemento "5GB Data Boost" tem inventory_items_list: "[]" porque apenas adiciona saldo a um serviço existente sem precisar de novo hardware.
Configuração do Modelo de Inventário
Antes de usar um tipo de inventário em inventory_items_list, você deve criar o Modelo de Inventário:
- Navegue até Administração → Inventário → Modelos.
- Crie um modelo com o nome exato (por exemplo, "SIM Card").
- Defina os campos:
itemtext1_label: "ICCID".itemtext2_label: "IMSI".itemtext3_label: "PUK Code".
- Adicione itens de inventário desse tipo ao estoque.
Para detalhes completos sobre como criar e gerenciar modelos de inventário, consulte Gestão de Inventário.
Múltiplos Itens do Mesmo Tipo
Embora a inventory_items_list seja um array, ter tipos duplicados (por exemplo, "['SIM Card', 'SIM Card']") não é recomendado pois pode causar confusão na interface e na nomeação de variáveis do playbook.
Para cenários que exigem múltiplos itens semelhantes:
Opção 1: Criar nomes de modelos de inventário distintos
# Serviço de telefone Dual-SIM
inventory_items_list: "['Primary SIM Card', 'Secondary SIM Card', 'Mobile Number']"
Crie modelos separados: "Primary SIM Card" e "Secondary SIM Card" com os mesmos campos, mas nomes diferentes.
Opção 2: Usar um único item de inventário agrupado
# Kit Dual-SIM
inventory_items_list: "['Dual SIM Kit', 'Mobile Number']"
Onde o modelo de inventário "Dual SIM Kit" tem campos para ambos os SIMs (itemtext1: ICCID Primário, itemtext2: ICCID Secundário, etc.).
Cenários Comuns de Inventário
Serviço Móvel:
inventory_items_list: "['SIM Card', 'Mobile Number']"
- SIM Card: Físico ou eSIM com ICCID/IMSI.
- Mobile Number: Número de telefone (MSISDN).
Internet Fixa:
inventory_items_list: "['Modem Router', 'Static IP Address']"
- Modem Router: Dispositivo CPE com endereço MAC.
- Static IP Address: IPv4 do pool de endereços.
Wireless Fixo:
inventory_items_list: "['Fixed Wireless CPE', 'IPv4 Address', 'IPv6 Prefix']"
- CPE: Equipamento nas instalações do cliente (antena, modem).
- IPv4: Endereço IP público.
- IPv6 Prefix: prefixo /56 ou /64.
Nota: Compromissos e agendamentos não são itens de inventário. Use sistemas de agendamento/calendário separados para compromissos de instalação.
Serviço VoIP:
inventory_items_list: "['DID Number']"
- DID Number: Número de telefone de Discagem Direta.
Nota: Nomes de usuário SIP, senhas e configurações de conta são gerados programaticamente pelo playbook de provisão, não selecionados do inventário.
GPON/Fibra:
inventory_items_list: "['ONT Device', 'GPON Port', 'IPv4 Address', 'Fiber Drop Cable']"
- ONT Device: Terminal Óptico de Rede com número de série.
- GPON Port: Porta específica no OLT com conexão de fibra.
- IPv4 Address: IP público ou privado.
- Fiber Drop Cable: Cabo de fibra física da rua até as instalações (rastreado para gestão de ativos).
Aluguel de Equipamentos:
inventory_items_list: "['Rental Modem']"
- Rastreia qual modem está com qual cliente.
- Importante para recuperar equipamentos em caso de cancelamento.
Por que os Requisitos de Inventário Importam
1. Prevenir Dupla Atribuição
Sem rastreamento de inventário, você poderia acidentalmente:
- Atribuir o mesmo cartão SIM a dois clientes.
- Alocar o mesmo endereço IP a múltiplos serviços.
- Enviar o mesmo número de série de equipamento para diferentes locais.
O seletor de inventário garante que cada item seja atribuído a exatamente um serviço.
2. Rastro de Auditoria
A atribuição de inventário cria um rastro de auditoria completo:
- Qual cartão SIM está com qual cliente.
- Quando foi atribuído.
- Qual serviço está usando qual número de telefone.
- Histórico de equipamentos (quem teve, quando, para qual serviço).
3. Planejamento de Recursos
Rastrear níveis de inventário:
- Alertar quando os cartões SIM estiverem baixos.
- Reordenar antes da falta de estoque.
- Planejar horários de técnicos com base na disponibilidade do CPE.
- Gerenciar alocação de espaço de endereço IP.
4. Rastreio de Custos
Vincular custo de atacado a item específico:
- Rastrear custo de cada cartão SIM.
- Calcular depreciação de equipamentos.
- Identificar itens perdidos ou roubados.
- COGS (Custo das Mercadorias Vendidas) preciso.
5. Desprovisionamento
Quando o serviço é cancelado, o inventário pode ser:
- Liberado de volta ao estoque (cartões SIM, modems).
- Retirado (equipamentos danificados).
- Retornado ao fornecedor (equipamentos alugados).
- Mantido por um período de carência (números de telefone antes da liberação).
Resolvendo Problemas com o Seletor de Inventário
Problema: Mensagem "Nenhum inventário disponível" aparece.
Causas:
- Nenhum item de inventário do tipo requerido existe no banco de dados.
- Todos os itens já estão "Atribuídos" a outros serviços.
- Itens estão marcados como "Danificados" ou "Fora de Serviço".
- O nome do modelo de inventário não corresponde exatamente (sensível a maiúsculas e minúsculas).
Solução:
- Verifique se o modelo de inventário existe: Administração → Inventário → Modelos.
- Verifique se o nome do modelo corresponde exatamente (incluindo espaços, maiúsculas e minúsculas).
- Adicione itens de inventário desse tipo: Administração → Inventário → Adicionar Item.
- Verifique se os itens estão no estado "Novo" ou "Em Estoque".
- Verifique se os itens não estão atribuídos (
service_iddeve ser NULL).
Problema: O seletor de inventário não aparece.
Causas:
inventory_items_listestá vazio:"[]".inventory_items_listé NULL ou não está definido.- A categoria do produto é "complemento" e herda o inventário do serviço pai.
Solução:
- Se o inventário for necessário, defina
inventory_items_list: "['Type1', 'Type2']". - Verifique se a definição do produto foi salva corretamente.
- Verifique a resposta da API para o produto incluir
inventory_items_list.
Problema: O playbook falha com "inventário não encontrado".
Causas:
- O playbook referencia o nome da variável errado.
- O ID do inventário não foi passado corretamente.
- O inventário foi excluído entre a seleção e o provisionamento.
Solução:
- Verifique se o playbook usa a variável correta:
hostvars[inventory_hostname]['SIM Card']. - Verifique se a variável é um inteiro:
{{ hostvars[inventory_hostname]['SIM Card'] | int }}. - Adicione tratamento de erro no playbook para inventário ausente.
Consulte Gestão de Inventário para detalhes completos sobre como criar modelos, adicionar itens e gerenciar níveis de estoque.
Passo 7: Definir Recursos e Termos
Recursos e termos são conteúdos de marketing e legais voltados para o cliente que ajudam os clientes a entender o que estão comprando e as obrigações envolvidas.
{
"features_list": "20GB High-Speed Data. Unlimited Calls & Texts. EU Roaming Included. No Contract. 30-Day Expiry",
"terms": "Credit expires after 30 days. Data, calls, and texts valid only within expiry period. Fair use policy applies. See website for full terms."
}
Propósito e Valor Comercial
Lista de Recursos - Marketing e Vendas:
A lista de recursos serve a várias funções comerciais críticas:
- Diferenciação de Produto - Ajuda os clientes a comparar rapidamente produtos e escolher o certo.
- "Prepaid Mobile 20GB" vs "Prepaid Mobile 50GB" - recursos mostram claramente a diferença.
- Sem recursos, os clientes só veem preço, perdendo a proposta de valor.
- Comunicação de Marketing - Pontos de venda principais exibidos de forma proeminente.
- "EU Roaming Included" atrai viajantes internacionais.
- "No Contract" atrai clientes avessos a compromissos.
- Recursos impulsionam decisões de compra.
- Expectativas do Cliente - Define expectativas claras sobre o que está incluído.
- Reduz chamadas de suporte ("Isso inclui chamadas?" → claramente listado).
- Prevê mal-entendidos e pedidos de reembolso.
- Constrói confiança por meio da transparência.
- Autoatendimento - Permite que os clientes selecionem produtos apropriados por conta própria.
- O cliente lê os recursos, entende a oferta, faz uma escolha informada.
- Reduz a necessidade de explicação da equipe de vendas.
- Acelera o processo de compra.
- SEO e Descobribilidade - Recursos podem ser indexados para pesquisa.
- O cliente pesquisa "plano móvel de chamadas ilimitadas" → o produto aparece.
- Melhora a capacidade de busca do catálogo de produtos.
Termos e Condições - Legal e Conformidade:
Os termos servem a propósitos legais e operacionais:
- Proteção Legal - Protege a empresa de disputas e responsabilidade.
- "O crédito expira após 30 dias" - o cliente não pode exigir reembolso após 31 dias.
- "A política de uso justo se aplica" - previne abusos (tethering de todo o escritório em um plano móvel).
- Cria um acordo vinculativo.
- Gerenciamento de Expectativas - Prevê insatisfação do cliente.
- "Válido apenas dentro do período de validade" - o cliente conhece o prazo de uso.
- "Não pode ser reembolsado" (para complementos) - previne compras fraudulentas.
- Reduz chargebacks e reclamações.
- Conformidade Regulatória - Atende a requisitos legais.
- Leis de proteção ao consumidor exigem termos claros.
- Regulamentações de telecomunicações exigem divulgação.
- Termos de GDPR/privacidade podem ser referenciados.
- Limites Operacionais - Define o escopo e limitações do serviço.
- "Sujeito à cobertura da rede" - não é responsável por zonas mortas.
- "A velocidade pode variar" - gerencia expectativas sobre velocidades "até".
- "O equipamento deve ser devolvido" - garante recuperação de equipamentos alugados.
- Rastro de Auditoria - Prova que o cliente foi informado.
- O cliente aceitou os termos na compra.
- O sistema registra o timestamp de aceitação.
- Defensável em disputas ou processos legais.
Exemplo do Mundo Real:
O cliente compra um plano "Chamadas e Textos Ilimitados", depois o utiliza para telemarketing (10.000 chamadas/dia). Sem termos:
- Cliente: "Você disse ilimitado!"
- Provedor: "Queríamos dizer uso pessoal..."
- Cliente: "Isso não é o que você anunciou!"
- Resultado: Disputa, potencial reclamação ao regulador, dano à marca.
Com termos: "A política de uso justo se aplica. O serviço é apenas para uso pessoal. Uso comercial proibido."
- Provedor: Aponta para os termos que o cliente aceitou.
- O cliente não pode alegar ignorância.
- Base legal para suspender o serviço.
- Disputa resolvida a favor do provedor.
Formato da Lista de Recursos:
Entender o formato correto é crítico porque formatação inadequada quebra a exibição da interface. Os recursos podem aparecer como uma longa string em vez de pontos de lista, ou não serem exibidos de forma alguma.
O campo features_list pode ser formatado de duas maneiras:
Opção 1: String Separada por Ponto (Recomendado)
Os recursos são separados por um ponto e espaço (". "). A interface divide neste delimitador e renderiza cada recurso como um ponto de lista.
Por que esse formato?
- Simples de editar - basta digitar os recursos com pontos entre eles.
- Sem caracteres especiais para escapar.
- Funciona de forma confiável em todos os componentes da interface.
- Fácil de atualizar sem quebrar a sintaxe JSON.
Correto vs Incorreto:
Opção 2: String de Array JSON
"['20GB High-Speed Data', 'Unlimited Calls & Texts', 'EU Roaming Included']"
A interface também pode analisar arrays JSON. Observe que isso é uma string contendo JSON, não um array JSON real no banco de dados.
Por que esse formato existe?
- Permite recursos com pontos neles (por exemplo, "Até 100Mbps. Sujeito à disponibilidade.").
- Geração programática a partir de scripts/API é mais fácil.
- Importado de catálogos de produtos externos que usam arrays.
Importante: Isso deve ser uma sintaxe de lista Python válida como string. Aspas simples em torno de cada item, aspas duplas em torno da string inteira.
Qual Formato Usar?
- Separado por ponto - Para criação manual de produtos na interface (mais simples, menos propenso a erros).
- Array JSON - Para criação de produtos baseada em API/script (mais robusto para recursos complexos).
Ambos os formatos produzem saída idêntica na interface - eles apenas afetam como você insere os dados.
Onde os Recursos Aparecem na Interface:
1. Catálogo de Produtos (Visão do Cliente)
Quando os clientes navegam pelos produtos disponíveis, os recursos são exibidos como pontos de lista em cada cartão de produto:
2. Página de Detalhes do Produto
Clicando em "Ver Detalhes" mostra todas as informações do produto, incluindo:
- Nome do produto e ícone.
- Preços (custo mensal, custo de configuração).
- Lista completa de recursos (pontos de lista).
- Termos e condições (veja abaixo).
- Disponibilidade e elegibilidade.
3. Confirmação de Provisão
Durante a provisão, os recursos são mostrados para o usuário revisar antes de confirmar:
Recursos: • 20GB High-Speed Data • Unlimited Calls & Texts • EU Roaming Included • No Contract • 30-Day Expiry
Custo: £15.00/mês Configuração: £0.00
[Cancelar] [Confirmar & Provisionar]
4. Detalhes do Serviço (Após Provisão)
Após o serviço estar ativo, os recursos são exibidos na página de detalhes do serviço para referência do cliente.
Formato dos Termos e Condições:
O campo terms é texto simples que pode incluir quebras de linha:
Onde os Termos Aparecem na Interface:
1. Página de Detalhes do Produto
Os termos são exibidos em uma seção colapsada que se expande quando clicada:
2. Confirmação do Pedido
Durante a provisão, uma caixa de seleção exige que o usuário aceite os termos:
O botão [Provisionar] desativado até ser marcado.
3. Faturas
Os termos do serviço podem ser incluídos nas faturas como notas de rodapé para clareza.
Melhores Práticas:
- Recursos: Mantenha concisos (menos de 50 caracteres cada), concentre-se nos principais benefícios.
- Termos: Inclua requisitos legais críticos, políticas de expiração, políticas de uso justo.
- Ambos: Atualize quando o produto mudar para manter os clientes informados.
Passo 8: Vincular Playbook de Provisão do Ansible
{
"provisioning_play": "play_local_mobile_sim",
"provisioning_json_vars": "{
\"days\": 30,
\"data_gb\": 20,
\"voice_minutes\": \"unlimited\",
\"sms_count\": \"unlimited\"
}"
}
provisioning_play- Nome do playbook do Ansible (sem extensão .yaml).provisioning_json_vars- Variáveis padrão passadas para o playbook.- O playbook deve existir em:
OmniCRM-API/Provisioners/plays/play_local_mobile_sim.yaml.
Definição Completa do Produto
{
"product_name": "Prepaid Mobile 20GB",
"product_slug": "prepaid-mobile-20gb",
"category": "standalone",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-sim-card",
"comment": "Prepaid mobile SIM with 20GB data, unlimited calls & texts",
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00,
"contract_days": 30,
"residential": true,
"business": false,
"customer_can_purchase": true,
"available_from": "2025-01-01T00:00:00Z",
"available_until": null,
"auto_renew": "prompt",
"allow_auto_renew": true,
"inventory_items_list": "['SIM Card', 'Mobile Number']",
"features_list": "[
'20GB High-Speed Data',
'Unlimited Calls & Texts',
'EU Roaming Included',
'No Contract',
'30-Day Expiry'
]",
"terms": "Credit expires after 30 days. Data, calls, and texts valid only within expiry period. Fair use policy applies.",
"provisioning_play": "play_local_mobile_sim",
"provisioning_json_vars": "{
\"days\": 30,
\"data_gb\": 20,
\"voice_minutes\": \"unlimited\",
\"sms_count\": \"unlimited\"
}"
}
Criando um Produto Adicional
Complementos melhoram ou modificam serviços existentes. Eles vêm em dois tipos: complementos virtuais (sem recursos físicos) e complementos de hardware (exigem inventário).
Exemplo 1: Complemento Virtual (5GB Data Boost)
Um complemento digital que adiciona dados a um serviço móvel existente:
{
"product_name": "5GB Data Boost",
"product_slug": "5gb-data-boost",
"category": "addon",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-plus",
"comment": "Add 5GB extra data to existing mobile service",
"retail_cost": 5.00,
"wholesale_cost": 1.50,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 0.00,
"contract_days": 0,
"residential": true,
"business": true,
"customer_can_purchase": true,
"auto_renew": "false",
"allow_auto_renew": false,
"inventory_items_list": "[]",
"relies_on_list": "",
"features_list": "5GB High-Speed Data. Valid for 7 Days",
"terms": "Data expires after 7 days or when exhausted. Cannot be refunded.",
"provisioning_play": "play_topup_charge_then_action",
"provisioning_json_vars": "{
\"data_gb\": 5,
\"days\": 7
}"
}
Exemplo 2: Complemento de Hardware (Aluguel de Modem)
Um complemento que fornece equipamento físico para um serviço de fibra existente:
{
"product_name": "WiFi 6 Modem Rental",
"product_slug": "wifi6-modem-rental",
"category": "addon",
"service_type": "internet",
"enabled": true,
"icon": "fa-solid fa-router",
"comment": "Add WiFi 6 modem to fiber service - rental",
"retail_cost": 10.00,
"wholesale_cost": 3.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 45.00,
"contract_days": 30,
"residential": true,
"business": true,
"customer_can_purchase": true,
"auto_renew": "true",
"allow_auto_renew": true,
"inventory_items_list": "['Rental Modem']",
"relies_on_list": "",
"features_list": "WiFi 6 (802.11ax). Dual-band 2.4GHz + 5GHz. Up to 40 devices. Parental controls",
"terms": "Equipment rental. Must be returned on service cancellation or £150 replacement fee applies. Equipment remains property of provider.",
"provisioning_play": "play_addon_assign_modem",
"provisioning_json_vars": "{
\"device_type\": \"modem_router\",
\"requires_configuration\": true
}"
}
Principais Diferenças para Complementos:
category: "addon"- Aplicado a serviço existente, não autônomo.contract_days: 0(virtual) ou30(aluguel recorrente) - Frequência de cobrança.inventory_items_list: "[]"(virtual) ou"['Rental Modem']"(hardware) - Recursos físicos.auto_renew: "false"(uma vez) ou"true"(aluguel) - Comportamento recorrente.relies_on_list: ""- Vazio significa que se aplica a qualquer serviço do tiposervice_typecorrespondente.
Por que os Complementos de Hardware Precisam de Inventário:
Complementos de hardware exigem inventory_items_list porque:
- Rastrear Equipamento - Saber qual modem está com qual cliente.
- Prevenir Faltas de Estoque - Não é possível provisionar complemento se não houver modems em estoque.
- Recuperação - Quando o cliente cancela, saber qual equipamento recuperar.
- Rastreio de Custos - Vincular custo de atacado a número de série específico.
- Depreciação - Rastrear valor do equipamento ao longo do período de aluguel.
- Garantia - Identificar unidades defeituosas pelo número de série.
Fluxo de Provisão de Complementos com Inventário:
Quando um cliente adiciona "Aluguel de Modem WiFi 6" ao seu serviço de fibra:
- Complemento Selecionado - O cliente clica em "Adicionar ao Serviço".
- Seletor de Inventário Aparece - Assim como serviços autônomos:
- Pagamento Processado - £10.00 de aluguel mensal cobrado.
- Modem Atribuído - Inventário atualizado:
service_id: Vinculado ao serviço de fibra.customer_id: Vinculado ao cliente.item_state: "Assigned".
- Envio Acionado - Sistema de atendimento notificado para enviar o modem.
- Instalação - O cliente recebe o modem, conecta ao ONT.
- Cobrança Recorrente - £10/mês cobrado até o complemento ser cancelado.
Desprovisionamento de Complementos de Hardware:
Quando o cliente cancela o aluguel do modem:
- Cancelamento Iniciado - O cliente clica em "Remover Complemento".
- Processo de Retorno Iniciado:
- Email enviado com instruções de retorno.
- Etiqueta de envio pré-paga gerada.
- Período de carência de 14 dias antes da penalidade.
- Equipamento Retornado:
- Inventário atualizado:
item_state= "In Stock" (após reforma). - Ou
item_state= "Damaged" (se defeituoso). - Vinculado ao próximo cliente uma vez reformado.
- Inventário atualizado:
- Sem Retorno:
- Após 14 dias, taxa de substituição de £150 cobrada.
- Inventário marcado:
item_state= "Lost". - Custo de atacado (£45) + valor de substituição recuperado.
Preços para Complementos:
Os complementos podem ser precificados de forma diferente dos serviços autônomos:
- Complementos virtuais normalmente não têm custos de configuração.
- Complementos de hardware podem ter custos de configuração de atacado para equipamentos.
- Complementos de aluguel recorrente usam
contract_dayspara frequência de cobrança.
Etapa 2: O Processo de Provisão
Quando um cliente solicita o produto "Prepaid Mobile 20GB", o OmniCRM orquestra a provisão através do Ansible.
Diagrama de Fluxo de Provisão
Cliente Faz Pedido → Seleção de Inventário → Job de Provisão Criado ↓ ↓ Pagamento Autorizado ← Variáveis Montadas ← Playbook do Ansible Executado ↓ ↓ Registro de Serviço Criado → Configuração de Conta OCS → Inventário Atribuído → Serviço Ativo
Fluxo de Provisão Passo a Passo
1. Cliente Inicia Pedido
Na página do cliente:
- A equipe clica em "Adicionar Serviço".
- Seleciona "Prepaid Mobile 20GB" no carrossel de produtos.
- Detalhes do produto e preços exibidos.
2. Seleção de Inventário
O sistema solicita o inventário necessário:
- SIM Card - Dropdown mostra os SIMs disponíveis em estoque.
- Exemplo: "SIM-00123 - ICCID: 8944...".
- Mobile Number - Dropdown mostra os números de telefone disponíveis.
- Exemplo: "+44 7700 900123".
A equipe ou o cliente seleciona itens do inventário disponível.
3. Confirmação de Preços
O sistema exibe o preço final:
- Custo de configuração: £0.00 (ativação gratuita).
- Custo mensal: £15.00.
- Devido hoje: £15.00 (primeiro mês).
- Data de renovação: 30 dias a partir de hoje.
Se a solicitação de renovação automática estiver habilitada, o cliente escolhe:
- Renovar automaticamente este serviço a cada 30 dias.
4. Botão de Provisão Clicado
Quando "Provisionar" é clicado, a API:
- Cria um registro de
Provisioncom status "Running" (status=1). - Mescla variáveis do produto + solicitação + seleções de inventário.
- Cria um thread em segundo plano para executar o playbook do Ansible.
- Retorna
provision_idpara a interface para rastreamento de status.
5. Variáveis Montadas
O sistema mescla variáveis de múltiplas fontes:
Do Produto:
{
"days": 30,
"data_gb": 20,
"voice_minutes": "unlimited",
"sms_count": "unlimited"
}
Da Solicitação:
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001,
"Mobile Number": 5002
}
Adicionado pelo Sistema:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"initiating_user": 7
}
Variáveis Finais Passadas para Ansible:
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001,
"Mobile Number": 5002,
"days": 30,
"data_gb": 20,
"voice_minutes": "unlimited",
"sms_count": "unlimited",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"initiating_user": 7
}
6. Execução do Playbook do Ansible
O playbook play_local_mobile_sim.yaml é executado com essas variáveis.
Compreendendo o Playbook de Provisão do Ansible
Vamos examinar um playbook de provisão real para entender o que acontece nos bastidores.
Exemplo de Playbook de Provisão de SIM Móvel
Localização:
OmniCRM-API/Provisioners/plays/play_local_mobile_sim.yaml
Estrutura de Alto Nível:
- name: Mobile SIM Provisioning
hosts: localhost
gather_facts: no
become: False
tasks:
- name: Main block
block:
# 1. Load configuration
# 2. Fetch product details from API
# 3. Fetch customer details from API
# 4. Fetch inventory details from API
# 5. Create account in OCS (CGRateS)
# 6. Add balances and allowances to OCS
# 7. Create service record in CRM
# 8. Assign inventory to service
# 9. Record transactions
# 10. Send welcome notifications
rescue:
# Rollback on failure
# - Remove OCS account
# - Release inventory
# - Log error
Detalhamento do Playbook:
Tarefa 1: Carregar Configuração
- name: Include vars of crm_config
ansible.builtin.include_vars:
file: "../../crm_config.yaml"
name: crm_config
Carrega a configuração do sistema, incluindo:
- URL e credenciais do OCS/CGRateS.
- URL base do CRM.
- Configuração do inquilino.
Tarefa 2: Buscar Detalhes do Produto
- name: Get Product information from CRM API
uri:
url: "{{ crm_config.crm.base_url }}/crm/product/product_id/{{ product_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
return_content: yes
register: api_response_product
O que isso faz:
- Chama
GET /crm/product/product_id/42. - Recupera a definição completa do produto.
- Armazena na variável
api_response_product.
Por que: Mesmo tendo provisioning_json_vars do produto, buscamos o produto completo para obter:
- Preços mais recentes (podem ter mudado desde o início do pedido).
- Nome do produto para nomeação do serviço.
- Lista de recursos para documentação.
- Custos de atacado para rastreamento de margem.
Tarefa 3: Definir Fatos do Pacote
- name: Set package facts
set_fact:
package_name: "{{ api_response_product.json.product_name }}"
monthly_cost: "{{ api_response_product.json.retail_cost }}"
setup_cost: "{{ api_response_product.json.retail_setup_cost }}"
Extrai valores comumente usados em variáveis simples para legibilidade.
Tarefa 4: Buscar Detalhes do Inventário
- name: Get SIM information from CRM API
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_sim
- name: Set IMSI from Inventory response
set_fact:
imsi: "{{ api_response_sim.json.itemtext2 }}"
iccid: "{{ api_response_sim.json.itemtext1 }}"
O que isso faz:
- Busca o ID do inventário do cartão SIM 5001.
- Recupera detalhes do SIM:
itemtext1= ICCID (número do cartão SIM).itemtext2= IMSI (identidade do assinante).
- Faz o mesmo para o número de telefone móvel (recupera o número de telefone).
Por que isso é importante:
- O IMSI é necessário para provisionar o assinante no HSS (Servidor de Assinantes).
- O ICCID é registrado nas notas de serviço para solução de problemas.
- O número de telefone (MSISDN) é exibido para o cliente e usado para roteamento.
Tarefa 5: Gerar UUID do Serviço
- name: Generate UUID Fact
set_fact:
uuid: "{{ 99999999 | random | to_uuid }}"
- name: Set Service UUID
set_fact:
service_uuid: "Local_Mobile_SIM_{{ uuid[0:8] }}"
O que isso faz:
- Gera um UUID aleatório.
- Cria um service_uuid como
Local_Mobile_SIM_a3f2c1d8.
Por que:
- O UUID do serviço é o identificador exclusivo no OCS/CGRateS.
- Usado para todas as operações de cobrança.
- Deve ser globalmente único entre todos os serviços.
Tarefa 6: Criar Conta no OCS
- name: Create account in OCS
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
headers:
Content-Type: "application/json"
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"ActionPlanIds": [],
"ExtraOptions": {
"AllowNegative": false,
"Disabled": false
},
"ReloadScheduler": true
}]
}
register: ocs_create_response
O que isso faz:
- Chama a API JSON-RPC do CGRateS.
- Cria uma nova conta com
service_uuid. - Define a conta como ativa (não desativada).
- Impede saldo negativo (modo pré-pago).
Por que:
- A conta OCS é onde toda a cobrança acontece.
- Saldo (dados, voz, SMS, dinheiro) é armazenado aqui.
- O uso é rastreado e avaliado em tempo real.
Tarefa 7: Adicionar Saldo de Dados
- name: Add 20GB Data Balance
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"BalanceType": "*data",
"Balance": {
"ID": "DATA_20GB_Monthly",
"Value": 21474836480,
"ExpiryTime": "+720h",
"Weight": 10,
"DestinationIDs": "*any"
}
}]
}
O que isso faz:
- Adiciona 20GB de saldo de dados à conta.
- Valor: 21474836480 bytes (20 * 1024 * 1024 * 1024).
- Expira em 720 horas (30 dias).
- Peso 10 (peso mais alto consumido primeiro).
Tarefa 8: Adicionar Voz e SMS Ilimitados
- name: Add Unlimited Voice
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Account": "{{ service_uuid }}",
"BalanceType": "*voice",
"Balance": {
"ID": "VOICE_Unlimited",
"Value": 999999999,
"ExpiryTime": "+720h"
}
}]
}
- Adiciona 999.999.999 segundos de voz (essencialmente ilimitado).
- Expira em 30 dias.
Tarefa 9: Criar Registro de Serviço no CRM
- name: Add Service via API
uri:
url: "{{ crm_config.crm.base_url }}/crm/service/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"product_id": "{{ product_id }}",
"service_name": "Mobile - {{ phone_number }}",
"service_type": "mobile",
"service_uuid": "{{ service_uuid }}",
"service_status": "Active",
"service_provisioned_date": "{{ provision_datetime }}",
"retail_cost": "{{ monthly_cost }}",
"wholesale_cost": "{{ api_response_product.json.wholesale_cost }}",
"icon": "fa-solid fa-sim-card"
}
register: service_creation_response
O que isso cria:
- Registro de serviço vinculado ao cliente.
- Vincula ao OCS via
service_uuid. - Armazena custos de varejo e atacado.
- Define o status como "Ativo".
- Retorna
service_idpara operações subsequentes.
Tarefa 10: Atribuir Inventário ao Serviço
- name: Assign SIM Card to Service
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"service_id": "{{ service_creation_response.json.service_id }}",
"customer_id": "{{ customer_id }}",
"item_state": "Assigned"
}
O que isso faz:
- Atualiza o registro de inventário do cartão SIM.
- Define
service_idpara vincular o SIM ao serviço. - Muda o estado de "Em Estoque" para "Atribuído".
- Repete para o inventário do número de telefone móvel.
Por que:
- Rastreia qual SIM está atribuído a qual cliente.
- Previne a dupla alocação de inventário.
- Permite relatórios e auditorias de inventário.
Tarefa 11: Registrar Transação de Custo de Configuração
- name: Add Setup Cost Transaction
uri:
url: "{{ crm_config.crm.base_url }}/crm/transaction/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_creation_response.json.service_id }}",
"title": "{{ package_name }} - Setup",
"description": "Activation fee",
"retail_cost": "{{ setup_cost }}",
"wholesale_cost": "{{ api_response_product.json.wholesale_setup_cost }}"
}
O que isso faz:
- Registra uma cobrança de configuração de £0.00 ao cliente (varejo).
- Registra um custo de atacado de £1.00.
- Cria um registro de transação para faturamento.
Tarefa 12: Bloco de Resgate (Tratamento de Erros)
rescue:
- name: Remove account in OCS on failure
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.RemoveAccount",
"params": [{
"Account": "{{ service_uuid }}"
}]
}
- name: Fail the provisioning
fail:
msg: "Provisioning failed, rolled back OCS account"
O que isso faz:
- Se qualquer tarefa falhar, o bloco de resgate é executado.
- Exclui a conta OCS que foi parcialmente criada.
- Libera o inventário de volta para "Em Estoque".
- Falha o trabalho de provisão com uma mensagem de erro.
Por que:
- Previne contas órfãs no OCS.
- Garante rollback limpo em erros.
- Mantém a consistência dos dados.
Provisão Completa: O que foi Criado
Após a provisão bem-sucedida, o sistema tem:
1. Conta OCS (CGRateS):
- ID da conta:
Local_Mobile_SIM_a3f2c1d8. - Saldos:
- 20GB de dados (expira em 30 dias).
- Voz ilimitada (999M segundos, expira em 30 dias).
- SMS ilimitados (999M mensagens, expira em 30 dias).
2. Registro de Serviço no CRM:
- ID do serviço: 1234.
- Cliente: John Doe (customer_id: 123).
- Produto: Prepaid Mobile 20GB (product_id: 42).
- Nome do serviço: "Mobile - +44 7700 900123".
- UUID do serviço:
Local_Mobile_SIM_a3f2c1d8. - Status: Ativo.
- Custo Mensal: £15.00 (varejo), £5.00 (atacado).
- Lucro: £10.00/mês.
3. Atribuições de Inventário:
- SIM Card 5001: Atribuído ao serviço 1234, cliente 123.
- Mobile Number 5002: Atribuído ao serviço 1234, cliente 123.
4. Registros de Transação:
- Transação de custo de configuração criada.
- Cobrança do primeiro mês registrada.
5. O Cliente Agora Pode:
- Ver o serviço no portal de autoatendimento.
- Ver saldo de 20GB de dados.
- Fazer chamadas e enviar SMS.
- Recarregar ou adicionar complementos.
- Ver uso em tempo real.
Etapa 3: Adicionando Complementos e Recargas
Após um serviço estar ativo, os clientes podem comprar complementos para melhorar seu serviço.
Fluxo de Provisão de Complementos
Vamos supor que o cliente usou 18GB de sua cota de 20GB e deseja comprar o complemento "5GB Data Boost".
1. Cliente Navega para o Serviço
- Abre a página "Mobile - +44 7700 900123".
- Vê uso atual: 18GB de 20GB usados (90%).
- Clica em "Adicionar Complemento" ou "Recarga".
2. Sistema Filtra Complementos Disponíveis
Mostra apenas complementos onde:
category = "addon".service_type = "mobile"(corresponde ao tipo de serviço).residential = true(se o cliente for residencial).enabled = true.
O cliente vê: "5GB Data Boost - £5.00".
3. Cliente Seleciona Complemento
- Clica em "5GB Data Boost".
- Confirma a compra por £5.00.
- O sistema captura a autorização de pagamento.
4. Provisão do Complemento Iniciada
O sistema chama play_topup_charge_then_action.yaml com variáveis:
{
"product_id": 43, # Produto 5GB Data Boost.
"customer_id": 123,
"service_id": 1234, # Serviço existente.
"access_token": "eyJ...",
"data_gb": 5, # Da variável provisioning_json_vars.
"days": 7 # Da variável provisioning_json_vars.
}
Diferença Chave em Relação ao Autônomo:
service_idestá incluído (serviço existente a ser modificado).- Nenhum inventário necessário.
- Nenhuma criação de serviço (modifica o existente).
Detalhamento do Playbook de Provisão de Complementos
Tarefa 1: Buscar Detalhes do Serviço
- name: Get Service information from CRM API
uri:
url: "http://localhost:5000/crm/service/service_id/{{ service_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_service
- name: Set service facts
set_fact:
service_uuid: "{{ api_response_service.json.service_uuid }}"
customer_id: "{{ api_response_service.json.customer_id }}"
Por que:
- Necessita
service_uuidpara adicionar saldo à conta OCS correta. - Verifica se o serviço existe e está ativo.
- Garante que o serviço pertença ao cliente.
Tarefa 2: Cobrar o Cliente
- name: Get Customer's Default Payment Method
uri:
url: "http://localhost:5000/crm/stripe/customer_id/{{ customer_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_stripe
- name: Get default card ID
set_fact:
customer_stripe_id: "{{ api_response_stripe.json | json_query(query) }}"
vars:
query: "data[?default_payment_method==`true`].customer_stripe_id | [0]"
- name: Charge card
uri:
url: "http://localhost:5000/crm/stripe/charge_card/{{ customer_stripe_id }}"
method: POST
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"retail_cost": 5.00,
"description": "5GB Data Boost",
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_id }}",
"product_id": "{{ product_id }}",
"wholesale_cost": 1.50,
"invoice": true
}
register: charge_response
- name: Assert payment successful
assert:
that:
- charge_response.status == 200
O que isso faz:
- Encontra o método de pagamento padrão do cliente no Stripe.
- Cobra £5.00 do cartão.
- Registra custo de atacado de £1.50 para rastreamento de margem.
- Cria transação vinculada ao serviço.
- Adiciona à próxima fatura.
- Falha na provisão se o pagamento falhar.
Por que cobrar primeiro:
- Nenhum crédito entregue até que o pagamento seja confirmado.
- Previne fraudes.
- Combina pagamento com provisão do complemento.
Tarefa 3: Adicionar Saldo de Dados à Conta OCS
- name: Add 5GB Data Balance
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Account": "{{ service_uuid }}",
"BalanceType": "*data",
"Balance": {
"ID": "DATA_5GB_Boost_{{ uuid }}",
"Value": 5368709120,
"ExpiryTime": "+168h",
"Weight": 20
}
}]
}
O que isso faz:
- Adiciona 5GB (5368709120 bytes) à conta.
- Expira em 168 horas (7 dias).
- Peso 20 (peso mais alto consumido primeiro - boost antes da cota mensal).
Saldo do Cliente Após o Complemento:
- Mensal original: 2GB restantes (expira em 25 dias).
- Novo boost: 5GB (expira em 7 dias).
- Total disponível: 7GB.
- Ordem de uso: Boost consumido primeiro, depois mensal.
Tarefa 4: Registrar Transação
- name: Add Addon Transaction
uri:
url: "http://localhost:5000/crm/transaction/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_id }}",
"title": "5GB Data Boost",
"description": "Additional 5GB data valid for 7 days",
"retail_cost": 5.00,
"wholesale_cost": 1.50
}
O que isso faz:
- Registra uma cobrança de £5.00 ao cliente.
- Registra um custo de atacado de £1.50.
- Vincula a transação ao serviço para relatórios.
Resumo Completo do Fluxo de Complemento
- O cliente seleciona o complemento da lista filtrada.
- Pagamento autorizado e cobrado.
- Saldo de dados adicionado à conta OCS.
- Transação registrada no CRM.
- O cliente imediatamente vê o saldo atualizado: 7GB disponível.
Rastreamento Financeiro:
- Cobrança mensal do serviço: £15 varejo, £5 atacado.
- Compra do complemento: £5 varejo, £1.50 atacado.
Renovação Automática: Complementos Recorrentes
Alguns complementos podem ser configurados para renovação automática (planos de dados mensais, assinaturas, etc.).
Configuração do Produto:
{
"product_name": "Monthly 10GB Data Plan",
"category": "addon",
"retail_cost": 10.00,
"contract_days": 30,
"auto_renew": "true",
"provisioning_play": "play_topup_charge_then_action"
}
Provisão Cria ActionPlan:
- name: Create ActionPlan for Auto-Renewal
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV1.SetActionPlan",
"params": [{
"Id": "ServiceID_{{ service_uuid }}__ProductID_{{ product_id }}__MonthlyRenewal",
"ActionPlan": [{
"ActionsId": "Action_{{ product_slug }}",
"Years": "*any",
"Months": "*any",
"MonthDays": "*any",
"WeekDays": "*any",
"Time": "00:00:00",
"Weight": 10
}],
"Overwrite": false,
"ReloadScheduler": true
}]
}
O que isso faz:
- Cria uma tarefa agendada no OCS.
- Executa
Action_{{ product_slug }}a cada 30 dias. - A ação cobra o cliente e reaplica o saldo de dados.
- Continua até que o cliente cancele.
Gerenciamento do Cliente:
- O cliente vê "Próxima Renovação: 1º de fevereiro de 2025 - £10.00" na visualização do serviço.
- Pode clicar em "Cancelar Renovação Automática" para parar cobranças futuras.
- Pode clicar em "Renovar Agora" para aplicar imediatamente a cota do próximo mês.
Etapa 4: Desprovisionamento de Serviços
Quando um cliente cancela o serviço, o sistema deve remover todos os recursos de forma limpa.
Gatilhos de Desprovisionamento
O desprovisionamento pode ser acionado por:
- Cancelamento do cliente - O cliente clica em "Cancelar Serviço".
- Ação administrativa - A equipe marca o serviço para desativação.
- Não pagamento - O serviço expira devido à falta de renovação.
- Fim do contrato - O contrato de prazo fixo chega à data de término.
Fluxo de Desprovisionamento
1. Cliente Inicia Cancelamento
- Navega até o serviço.
- Clica em "Cancelar Serviço".
- O sistema solicita: "Você tem certeza? Qualquer saldo restante será perdido."
- O cliente confirma.
2. Período de Carência (Opcional)
Alguns operadores implementam um período de carência:
- Serviço marcado como "Cancelamento Pendente".
- Permanece ativo por 7-30 dias.
- O cliente pode reverter o cancelamento durante o período de carência.
- Desprovisionamento automático após o período de carência.
3. Job de Desprovisionamento Criado
O sistema cria um job de provisão com:
{
"action": "deprovision",
"service_id": 1234,
"customer_id": 123,
"service_uuid": "Local_Mobile_SIM_a3f2c1d8"
}
Chama o playbook especificado em service.deprovisioning_play ou bloco de resgate do playbook original.
4. Playbook de Desprovisionamento do Ansible
- name: Deprovision Mobile Service
hosts: localhost
tasks:
- name: Disable OCS Account
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Account": "{{ service_uuid }}",
"ExtraOptions": { "Disabled": true }
}]
}
- name: Remove ActionPlans (stop auto-renewals)
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV1.RemoveActionPlan",
"params": [{
"Id": "ServiceID_{{ service_uuid }}__*"
}]
}
- name: Update Service Status in CRM
uri:
url: "http://localhost:5000/crm/service/{{ service_id }}"
method: PATCH
body:
{
"service_status": "Deactivated",
"service_deactivate_date": "{{ current_datetime }}"
}
- name: Release Inventory to Stock
uri:
url: "http://localhost:5000/crm/inventory/inventory_id/{{ sim_card_id }}"
method: PATCH
body:
{
"service_id": null,
"customer_id": null,
"item_state": "Decommissioned"
}
O que isso faz:
- Desativa a conta OCS - Para todas as cobranças, uso bloqueado.
- Remove ActionPlans - Cancela renovações automáticas.
- Atualiza o serviço no CRM - Status "Desativado", data registrada.
- Libera o inventário - SIM marcado como "Descomissionado", disponível para reutilização (após reforma).
5. Pós-Desprovisionamento
O sistema realiza a limpeza:
- O cliente não vê mais o serviço no portal de autoatendimento.
- O serviço permanece no CRM para relatórios históricos.
- Transações e faturas preservadas para contabilidade.
- O inventário pode ser reformado e reutilizado.
- A conta OCS pode ser arquivada após o período de retenção.
Desprovisionamento Parcial vs Total
Desprovisionamento Parcial (Suspensão):
- Usado para não pagamento ou suspensão temporária.
- Conta OCS desativada, mas não excluída.
- Saldos preservados.
- Pode ser reativada quando o pagamento for recebido.
- name: Suspend Service
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Account": "{{ service_uuid }}",
"ExtraOptions": { "Disabled": true }
}]
}
Desprovisionamento Total (Cancelamento Permanente):
- Usado para cancelamento permanente.
- Conta OCS excluída completamente.
- Saldos perdidos.
- Não pode ser reativada.
- name: Remove OCS Account
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.RemoveAccount",
"params": [{
"Account": "{{ service_uuid }}"
}]
}
Melhores Práticas para Gestão de Produtos
Gestão do Ciclo de Vida do Produto
Estados do Produto:
enabled: true- Produto disponível para novos pedidos.enabled: false- Produto desativado, serviços existentes continuam.
Desativando Produtos:
- Marque o produto como
enabled: falsepara impedir novos pedidos. - Serviços existentes permanecem ativos.
- Os clientes ainda podem renovar/modificar serviços existentes.
- Útil para descontinuar produtos antigos.
Gestão de Inventário
Estados do Inventário:
New- Estoque novo, pronto para atribuição.In Stock- Disponível para provisão.Assigned- Vinculado ao serviço do cliente.Decommissioned- Pode ser reformado e reutilizado.Damaged- Necessita reparo ou descarte.
Reutilizando Inventário:
Após o desprovisionamento:
- Cartões SIM: Reformar e marcar como "Em Estoque".
- Números de telefone: Liberar após o período de portabilidade (30 dias).
- Equipamentos: Testar, reformar, marcar como "Usado".
Métricas de Provisão
Monitorar:
- Taxa de sucesso de provisão.
- Tempo médio de provisão.
- Pontos comuns de falha.
- Rotatividade de inventário.