Estamos revisando estes procedimentos. Pessoas técnicas podem encontrar ajustes em códigos de erro ou mapeamentos de payload; valide com os logs e o OpenAPI mais recente. Pessoas não técnicas podem continuar usando o passo a passo e acionar o time de suporte caso algo pareça diferente do descrito.
🎁 Private Label - Promoções
Este guia apresenta as APIs de Promoções do Private Label, que permitem exibir banners promocionais, campanhas de cashback e informações do programa de fidelidade para os clientes.
🎯 Principais Funcionalidades
- Banners Promocionais: Exibir banners dinâmicos de promoções
- Campanhas de Cashback: Consultar campanhas ativas com regras e valores
- Programa de Fidelidade: Acessar dados do programa de pontos/lealdade
- Gestão de Ofertas: Controlar visualização de ofertas personalizadas
- Integração com Varejistas: Conectar com sistemas de parceiros
URLs Base:
- Produção:
https://api.credsystem.com.br/private-label-app/api/v1 - Homologação:
https://apihml.credsystem.com.br/private-label-app/api/v1
🔐 Autenticação
Todas as requisições exigem autenticação via Bearer Token (JWT):
Authorization: Bearer <seu_token_jwt>
Tokens inválidos ou expirados retornarão erro 401 Unauthorized.
📋 Endpoints Disponíveis
1. Listar Banners Promocionais
Endpoint: GET /banners
Retorna a lista de banners promocionais disponíveis para exibição no aplicativo.
Quando usar
- Ao carregar a tela principal do app
- Para exibir carrossel de promoções
- Ao atualizar ofertas em tempo real
Request
GET /private-label-app/api/v1/promocoes/banners HTTP/1.1
Host: bff-app-privatelabel-hml.credsystem.com.br
Authorization: Bearer <seu_token_jwt>
Accept: application/json
Response - Sucesso (200)
[
{
"url": "https://cdn.exemplo.com/banners/pascoa3.png"
},
{
"url": "https://cdn.exemplo.com/banners/black-friday.png"
}
]
Response - Sem Conteúdo (204)
Quando não há banners disponíveis, a API retorna 204 No Content.
Estrutura da Resposta
| Campo | Tipo | Descrição |
|---|---|---|
url | string | URL da imagem do banner |
Exemplo cURL
curl -X 'GET' \
'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes/banners' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <SEU_TOKEN_JWT>'
2. Consultar Campanhas de Cashback
Endpoint: GET /cashback
Retorna informações detalhadas sobre campanhas de cashback vigentes.
Quando usar
- Na tela de promoções/ofertas
- Para exibir regras de cashback
- Ao verificar elegibilidade do cliente
Request
GET /private-label-app/api/v1/promocoes/cashback HTTP/1.1
Host: bff-app-privatelabel-hml.credsystem.com.br
Authorization: Bearer <seu_token_jwt>
Accept: application/json
Response - Sucesso (200)
{
"nomeLoja": "ZINZANE",
"valorTotalize": "1",
"valorGanha": "10",
"dataInicio": "25/11/2024",
"dataFim": "23/12/2026",
"mensagem": "ou mais",
"teto": "1500",
"tipo": "PORCENTAGEM",
"idCashBackCampanha": "406"
}
Response - Sem Conteúdo (204)
Quando não há campanhas ativas, a API retorna 204 No Content.
Estrutura da Resposta
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
nomeLoja | string | ✅ | Nome da loja parceira |
valorTotalize | string | ✅ | Valor necessário de compras para ganhar cashback |
valorGanha | string | ✅ | Valor do cashback ganho |
dataInicio | string | ✅ | Data de início da campanha (dd/MM/yyyy) |
dataFim | string | ✅ | Data final da campanha (dd/MM/yyyy) |
mensagem | string | ❌ | Texto auxiliar (ex.: "ou mais") |
teto | string | ✅ | Valor máximo de cashback acumulável |
tipo | string | ✅ | Tipo da campanha (PORCENTAGEM ou VALOR) |
idCashBackCampanha | string | ✅ | Identificador único da campanha |
Exemplo cURL
curl -X 'GET' \
'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes/cashback' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <SEU_TOKEN_JWT>'
3. Obter Dados do Programa de Fidelidade
Endpoint: GET /loyalty
Retorna dados do programa de fidelidade/lealdade disponível para o cliente, incluindo informações sobre pontos, módulos e configurações de integração.
Quando usar
- Ao acessar a seção de fidelidade
- Para exibir saldo de pontos
- Ao configurar integrações com parceiros
Request
GET /private-label-app/api/v1/promocoes/loyalty HTTP/1.1
Host: bff-app-privatelabel-hml.credsystem.com.br
Authorization: Bearer <seu_token_jwt>
Accept: application/json
Response - Sucesso (200)
{
"titulo": "Programa de Fidelidade",
"retailerId": "RET001",
"xApiKey": "api-key-12345",
"descricao": "Ganhe pontos em cada compra",
"status": true,
"secretKey": "secret-key-67890",
"statusCode": 200,
"modulos": [
{
"titulo": "Extrato de Pontos",
"icone": "https://cdn.exemplo.com/icons/points.png",
"descricao": "Consulte seu saldo de pontos",
"link": "/pontos/extrato",
"status": true
},
{
"titulo": "Catálogo de Prêmios",
"icone": "https://cdn.exemplo.com/icons/catalog.png",
"descricao": "Troque seus pontos por prêmios",
"link": "/pontos/catalogo",
"status": true
}
]
}
Response - Sem Conteúdo (204)
Quando não há programa de fidelidade configurado, a API retorna 204 No Content.
Estrutura da Resposta
Objeto Principal (Loyalty)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
titulo | string | ✅ | Título do programa de fidelidade |
retailerId | string | ✅ | ID do varejista no programa |
xApiKey | string | ✅ | Chave de API para integração |
descricao | string | ✅ | Descrição do programa |
status | boolean | ✅ | Status do programa (true/false) |
secretKey | string | ✅ | Chave secreta para autenticação |
statusCode | integer | ✅ | Código HTTP da resposta |
modulos | array | ❌ | Lista de módulos disponíveis (opcional) |
Objeto Módulo
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
titulo | string | ✅ | Título do módulo |
icone | string | ❌ | URL do ícone do módulo |
descricao | string | ✅ | Descrição do módulo |
link | string | ✅ | Link/rota para acessar o módulo |
status | boolean | ✅ | Status do módulo (ativo/inativo) |
Exemplo cURL
curl -X 'GET' \
'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes/loyalty' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <SEU_TOKEN_JWT>'
🎨 Exemplos de Implementação
Exemplo 1: Carrossel de Banners
// Carregar e exibir banners promocionais
async function carregarBanners() {
try {
const response = await fetch(
'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes/banners',
{
method: 'GET',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Accept': 'application/json'
}
}
);
if (response.status === 204) {
console.log('Nenhum banner disponível no momento');
ocultarCarrossel();
return;
}
if (!response.ok) {
throw new Error(`Erro ao carregar banners: ${response.status}`);
}
const banners = await response.json();
exibirCarrossel(banners);
} catch (error) {
console.error('Erro ao carregar banners:', error);
exibirMensagemErro('Não foi possível carregar as promoções');
}
}
// Exibir carrossel com os banners
function exibirCarrossel(banners) {
const container = document.getElementById('carousel-banners');
container.innerHTML = '';
banners.forEach((banner, index) => {
const slide = document.createElement('div');
slide.className = 'carousel-slide';
slide.innerHTML = `
<img
src="${banner.url}"
alt="Banner promocional ${index + 1}"
loading="lazy"
onerror="this.src='/img/banner-fallback.png'"
/>
`;
container.appendChild(slide);
});
iniciarCarrossel();
}
// Auto-play do carrossel
function iniciarCarrossel() {
let currentSlide = 0;
const slides = document.querySelectorAll('.carousel-slide');
setInterval(() => {
slides[currentSlide].classList.remove('active');
currentSlide = (currentSlide + 1) % slides.length;
slides[currentSlide].classList.add('active');
}, 5000); // Troca a cada 5 segundos
}
// Executar ao carregar a página
document.addEventListener('DOMContentLoaded', carregarBanners);
Exemplo 2: Card de Campanha de Cashback
// Carregar e exibir campanha de cashback
async function carregarCashback() {
try {
const response = await fetch(
'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes/cashback',
{
method: 'GET',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Accept': 'application/json'
}
}
);
if (response.status === 204) {
console.log('Nenhuma campanha de cashback ativa');
ocultarSecaoCashback();
return;
}
if (!response.ok) {
throw new Error(`Erro ao carregar cashback: ${response.status}`);
}
const campanha = await response.json();
exibirCardCashback(campanha);
} catch (error) {
console.error('Erro ao carregar cashback:', error);
}
}
// Exibir card com informações da campanha
function exibirCardCashback(campanha) {
const container = document.getElementById('cashback-card');
// Calcular dias restantes
const dataFim = parseDate(campanha.dataFim);
const hoje = new Date();
const diasRestantes = Math.ceil((dataFim - hoje) / (1000 * 60 * 60 * 24));
// Formatar valores baseado no tipo
const valorFormatado = campanha.tipo === 'PORCENTAGEM'
? `${campanha.valorGanha}%`
: `R$ ${campanha.valorGanha}`;
container.innerHTML = `
<div class="cashback-card">
<div class="cashback-header">
<h3>💰 Cashback ${campanha.nomeLoja}</h3>
<span class="cashback-badge">${diasRestantes} dias restantes</span>
</div>
<div class="cashback-body">
<div class="cashback-rule">
<p class="rule-label">Compre</p>
<p class="rule-value">R$ ${formatarValor(campanha.valorTotalize)} ${campanha.mensagem || ''}</p>
</div>
<div class="cashback-arrow">→</div>
<div class="cashback-reward">
<p class="reward-label">Ganhe</p>
<p class="reward-value">${valorFormatado}</p>
</div>
</div>
<div class="cashback-footer">
<p class="cashback-limit">Limite máximo: R$ ${formatarValor(campanha.teto)}</p>
<p class="cashback-period">
Válido de ${campanha.dataInicio} até ${campanha.dataFim}
</p>
</div>
<button onclick="verDetalhesCashback('${campanha.idCashBackCampanha}')" class="btn-detalhes">
Ver regulamento completo
</button>
</div>
`;
}
// Funções auxiliares
function parseDate(dateString) {
const [dia, mes, ano] = dateString.split('/');
return new Date(ano, mes - 1, dia);
}
function formatarValor(valor) {
return parseFloat(valor).toLocaleString('pt-BR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
function verDetalhesCashback(idCampanha) {
// Abrir modal ou navegar para página de detalhes
console.log('Exibir detalhes da campanha:', idCampanha);
window.location.href = `/promocoes/cashback/${idCampanha}`;
}
Exemplo 3: Tela de Programa de Fidelidade
// Carregar programa de fidelidade completo
async function carregarProgramaFidelidade() {
try {
const response = await fetch(
'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes/loyalty',
{
method: 'GET',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Accept': 'application/json'
}
}
);
if (response.status === 204) {
exibirMensagem('Programa de fidelidade não disponível');
return;
}
if (!response.ok) {
throw new Error(`Erro ao carregar fidelidade: ${response.status}`);
}
const programa = await response.json();
if (!programa.status) {
exibirMensagem('Programa de fidelidade temporariamente indisponível');
return;
}
exibirProgramaFidelidade(programa);
configurarIntegracao(programa);
} catch (error) {
console.error('Erro ao carregar programa de fidelidade:', error);
exibirMensagemErro('Não foi possível carregar o programa de fidelidade');
}
}
// Exibir informações do programa
function exibirProgramaFidelidade(programa) {
const container = document.getElementById('loyalty-container');
container.innerHTML = `
<div class="loyalty-header">
<h2>${programa.titulo}</h2>
<p class="loyalty-description">${programa.descricao}</p>
</div>
<div class="loyalty-modules">
${renderizarModulos(programa.modulos || [])}
</div>
<div class="loyalty-info">
<p class="retailer-id">
<strong>Código do Varejista:</strong> ${programa.retailerId}
</p>
</div>
`;
}
// Renderizar módulos disponíveis
function renderizarModulos(modulos) {
if (!modulos.length) {
return '<p class="no-modules">Nenhum módulo disponível</p>';
}
return modulos
.filter(modulo => modulo.status)
.map(modulo => `
<div class="loyalty-module-card">
${modulo.icone ? `<img src="${modulo.icone}" alt="${modulo.titulo}" class="module-icon" />` : ''}
<h3>${modulo.titulo}</h3>
<p>${modulo.descricao}</p>
<button onclick="acessarModulo('${modulo.link}')" class="btn-module">
Acessar
</button>
</div>
`).join('');
}
// Configurar integração com API do parceiro
function configurarIntegracao(programa) {
// Armazenar credenciais de integração de forma segura
sessionStorage.setItem('loyalty_api_key', programa.xApiKey);
sessionStorage.setItem('loyalty_retailer_id', programa.retailerId);
// NÃO armazenar a secret key no frontend em produção!
// A secret key deve ser usada apenas no backend
console.log('Integração configurada para retailer:', programa.retailerId);
}
// Acessar módulo do programa
function acessarModulo(link) {
// Verificar se é link externo ou interno
if (link.startsWith('http')) {
window.open(link, '_blank');
} else {
window.location.href = link;
}
}
// Fazer requisição para API do parceiro (exemplo)
async function consultarSaldoPontos() {
const apiKey = sessionStorage.getItem('loyalty_api_key');
const retailerId = sessionStorage.getItem('loyalty_retailer_id');
try {
const response = await fetch(`https://api-parceiro.com/pontos/${retailerId}`, {
headers: {
'x-api-key': apiKey,
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
});
const dados = await response.json();
exibirSaldoPontos(dados.saldo);
} catch (error) {
console.error('Erro ao consultar saldo de pontos:', error);
}
}
Exemplo 4: Cache Inteligente de Promoções
// Sistema de cache para promoções
class PromocaoCache {
constructor() {
this.CACHE_DURATION = 5 * 60 * 1000; // 5 minutos
this.STORAGE_KEY = 'promocoes_cache';
}
// Salvar no cache
salvar(tipo, dados) {
const cache = this.obterCache();
cache[tipo] = {
dados,
timestamp: Date.now()
};
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(cache));
}
// Buscar do cache
buscar(tipo) {
const cache = this.obterCache();
const item = cache[tipo];
if (!item) return null;
// Verificar se o cache expirou
const idade = Date.now() - item.timestamp;
if (idade > this.CACHE_DURATION) {
delete cache[tipo];
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(cache));
return null;
}
return item.dados;
}
// Obter todo o cache
obterCache() {
try {
return JSON.parse(localStorage.getItem(this.STORAGE_KEY)) || {};
} catch {
return {};
}
}
// Limpar cache específico
limpar(tipo) {
const cache = this.obterCache();
delete cache[tipo];
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(cache));
}
// Limpar todo o cache
limparTudo() {
localStorage.removeItem(this.STORAGE_KEY);
}
}
// Usar cache ao carregar promoções
const cachePromocoes = new PromocaoCache();
async function carregarPromocoesComCache(tipo) {
// Tentar buscar do cache primeiro
const dadosCache = cachePromocoes.buscar(tipo);
if (dadosCache) {
console.log(`${tipo} carregado do cache`);
return dadosCache;
}
// Se não houver cache, buscar da API
const endpoint = obterEndpoint(tipo);
try {
const response = await fetch(endpoint, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Accept': 'application/json'
}
});
if (response.status === 204) {
return null;
}
if (!response.ok) {
throw new Error(`Erro ${response.status}`);
}
const dados = await response.json();
// Salvar no cache
cachePromocoes.salvar(tipo, dados);
return dados;
} catch (error) {
console.error(`Erro ao carregar ${tipo}:`, error);
throw error;
}
}
function obterEndpoint(tipo) {
const baseUrl = 'https://bff-app-privatelabel-hml.credsystem.com.br/private-label-app/api/v1/promocoes';
const endpoints = {
'banners': `${baseUrl}/banners`,
'cashback': `${baseUrl}/cashback`,
'loyalty': `${baseUrl}/loyalty`
};
return endpoints[tipo];
}
// Exemplo de uso
async function inicializarPromocoes() {
try {
const [banners, cashback, loyalty] = await Promise.all([
carregarPromocoesComCache('banners'),
carregarPromocoesComCache('cashback'),
carregarPromocoesComCache('loyalty')
]);
if (banners) exibirCarrossel(banners);
if (cashback) exibirCardCashback(cashback);
if (loyalty) exibirProgramaFidelidade(loyalty);
} catch (error) {
console.error('Erro ao inicializar promoções:', error);
}
}
// Forçar atualização (pull-to-refresh)
function atualizarPromocoes() {
cachePromocoes.limparTudo();
inicializarPromocoes();
}
⚠️ Tratamento de Erros
Erros Comuns
| Código | Erro | Causa | Solução |
|---|---|---|---|
| 400 | Bad Request | Authorization header ausente | Incluir header Authorization |
| 401 | Unauthorized | Token inválido ou expirado | Renovar token de autenticação |
| 204 | No Content | Sem promoções/campanhas disponíveis | Exibir mensagem amigável ao usuário |
| 500 | Internal Server Error | Erro no servidor | Tentar novamente mais tarde |
Exemplo de Tratamento
async function buscarDadosPromocao(tipo) {
try {
const endpoint = obterEndpoint(tipo);
const response = await fetch(endpoint, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Accept': 'application/json'
}
});
// Sem conteúdo disponível
if (response.status === 204) {
exibirMensagem(`Nenhuma ${tipo} disponível no momento`);
return null;
}
// Token expirado
if (response.status === 401) {
await renovarToken();
return buscarDadosPromocao(tipo); // Tentar novamente
}
// Bad Request
if (response.status === 400) {
const erro = await response.json();
console.error('Erro de requisição:', erro.error.message);
throw new Error(erro.error.message);
}
// Outros erros
if (!response.ok) {
throw new Error(`Erro ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error(`Erro ao buscar ${tipo}:`, error);
exibirMensagemErro(`Não foi possível carregar ${tipo}`);
return null;
}
}
🎯 Casos de Uso
1. Tela Inicial com Promoções
Carregar e exibir banners promocionais automaticamente ao abrir o app:
// Inicializar promoções na tela inicial
async function inicializarTelaInicial() {
mostrarLoading();
try {
// Carregar banners em paralelo com outros dados
const [banners, ofertas] = await Promise.all([
carregarPromocoesComCache('banners'),
carregarOutrosConteudos()
]);
if (banners && banners.length > 0) {
exibirCarrossel(banners);
} else {
ocultarSecaoBanners();
}
} catch (error) {
console.error('Erro ao inicializar tela:', error);
} finally {
ocultarLoading();
}
}
2. Seção de Cashback Dinâmica
Exibir campanhas de cashback com contagem regressiva:
// Monitorar e atualizar campanha de cashback
function monitorarCashback() {
carregarCashback();
// Atualizar contagem regressiva a cada minuto
setInterval(() => {
atualizarContagemRegressiva();
}, 60000);
// Recarregar dados a cada hora
setInterval(() => {
cachePromocoes.limpar('cashback');
carregarCashback();
}, 3600000);
}
3. Integração com Programa de Pontos
Conectar com sistema de fidelidade de parceiros:
// Integração completa com programa de fidelidade
async function configurarFidelidade() {
const programa = await carregarPromocoesComCache('loyalty');
if (!programa || !programa.status) {
console.log('Programa de fidelidade indisponível');
return;
}
// Configurar SDK do parceiro
await inicializarSDKParceiro({
apiKey: programa.xApiKey,
retailerId: programa.retailerId
});
// Carregar módulos disponíveis
renderizarModulosFidelidade(programa.modulos);
}
💡 Boas Práticas
1. Cache Eficiente
// Implementar cache com validade
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutos
function verificarCacheValido(timestamp) {
return (Date.now() - timestamp) < CACHE_DURATION;
}
2. Lazy Loading de Imagens
<!-- Carregar imagens sob demanda -->
<img src="${banner.url}" loading="lazy" alt="Banner promocional" />
3. Fallback para Imagens
// Tratamento de erro em imagens
function carregarBannerComFallback(url) {
return `
<img
src="${url}"
onerror="this.src='/img/banner-placeholder.png'"
alt="Banner promocional"
/>
`;
}
4. Pré-carregar Recursos
// Pré-carregar banners ao detectar rede rápida
if (navigator.connection && navigator.connection.effectiveType === '4g') {
preCarregarBanners();
}
5. Analytics de Promoções
// Rastrear visualizações de promoções
function registrarVisualizacaoBanner(bannerUrl) {
analytics.track('banner_visualizado', {
url: bannerUrl,
timestamp: new Date().toISOString()
});
}
6. Segurança de Credenciais
// NUNCA expor secret keys no frontend
// Usar apenas xApiKey para chamadas client-side
// Secret keys devem ficar apenas no backend
// ❌ ERRADO
localStorage.setItem('secret_key', programa.secretKey);
// ✅ CORRETO
// Usar secret key apenas em requisições server-side
📖 Glossário
| Termo | Definição |
|---|---|
| Banner | Imagem promocional exibida no aplicativo |
| Cashback | Devolução de valor em compras realizadas |
| Campanha | Promoção com regras e período definidos |
| Loyalty | Programa de fidelidade/pontos |
| Retailer ID | Identificador único do varejista no programa |
| API Key | Chave pública para autenticação em APIs de parceiros |
| Secret Key | Chave secreta para autenticação (uso apenas server-side) |
| Módulo | Funcionalidade específica do programa de fidelidade |
| Teto | Valor máximo acumulável em campanha de cashback |
| Bearer Token | Token JWT usado para autenticação nas requisições |
❓ Perguntas Frequentes (FAQ)
1. O que fazer quando não há banners disponíveis?
Quando a API retorna 204 No Content, você deve ocultar a seção de banners ou exibir conteúdo alternativo.
if (response.status === 204) {
ocultarSecaoBanners();
// ou exibir conteúdo padrão
}
2. Como calcular o cashback baseado no tipo?
Verifique o campo tipo:
PORCENTAGEM: Multiplique o valor da compra pelo percentualVALOR: Use o valor fixo informado
function calcularCashback(valorCompra, campanha) {
if (campanha.tipo === 'PORCENTAGEM') {
const percentual = parseFloat(campanha.valorGanha);
return (valorCompra * percentual) / 100;
}
return parseFloat(campanha.valorGanha);
}
3. Posso armazenar a Secret Key no localStorage?
NÃO! A secretKey deve ser usada apenas no backend. No frontend, use apenas a xApiKey para requisições permitidas.
4. Com que frequência devo atualizar os banners?
Recomenda-se:
- Cache de 5-10 minutos para banners
- Atualização ao retornar para a tela (pull-to-refresh)
- Recarregar ao detectar mudança de rede
5. Como tratar múltiplas campanhas de cashback?
A API atual retorna um objeto único. Se houver múltiplas campanhas no futuro, implemente:
function exibirMultiplasCampanhas(campanhas) {
return campanhas.map(campanha =>
exibirCardCashback(campanha)
).join('');
}
6. Os módulos do programa de fidelidade são obrigatórios?
Não, o campo modulos é opcional. Sempre verifique sua existência:
const modulos = programa.modulos || [];
if (modulos.length > 0) {
renderizarModulos(modulos);
}
7. Como implementar analytics para promoções?
Rastreie eventos importantes:
// Visualização de banner
analytics.track('banner_viewed', { url: banner.url });
// Clique em campanha de cashback
analytics.track('cashback_clicked', {
campaignId: campanha.idCashBackCampanha
});
// Acesso a módulo de fidelidade
analytics.track('loyalty_module_accessed', {
module: modulo.titulo
});
8. Preciso validar o período da campanha no frontend?
Sim, é uma boa prática exibir status visual:
function verificarCampanhaAtiva(campanha) {
const hoje = new Date();
const inicio = parseDate(campanha.dataInicio);
const fim = parseDate(campanha.dataFim);
return hoje >= inicio && hoje <= fim;
}
📞 Suporte
Para dúvidas ou problemas com a integração, entre em contato com a equipe de suporte técnico.