Pular para o conteúdo

Incorporação (iframe)

O sportsbook roda em um iframe na sua página. O SDK de incorporação cria o iframe, passa o launch token, ajusta o tamanho, confere a origem de cada mensagem e oferece callbacks para o que acontece lá dentro. Não tem dependências e pesa cerca de 5 KB.

<div id="sportsbook"></div>
<script src="https://sportsbook.example.com/embed/v1.js"></script>
<script>
const sb = BookmakerSportsbook.mount('#sportsbook', {
url: 'https://sportsbook.example.com',
tenant: 'seu-tenant',
launchToken: '<launch token vindo do seu servidor>', // omita para navegação anônima
height: matchMedia('(max-width: 899px)').matches ? 'fill' : 'auto',
onLoginRequired: () => abrirSeuLogin(),
onDepositRequested: () => abrirSeuCaixa(),
onBalanceChanged: ({ balance, currency }) => atualizarSeuCabecalho(balance, currency),
onSessionExpired: () => buscarLaunchTokenNoSeuServidor(), // uma string, uma promise de string, ou null
});
</script>

/embed/v1.js é o SDK da versão 1 do protocolo. Ele recebe correções compatíveis na mesma URL e é servido com Cache-Control: public, max-age=3600, stale-while-revalidate=86400 e Access-Control-Allow-Origin: *. Não use o atributo integrity: a próxima atualização compatível o quebraria.

Opção Tipo
url string URL base do sportsbook. A origem dela é a única com que o SDK conversa. Obrigatória.
tenant string O id do seu tenant. Obrigatório.
launchToken string Vindo do seu servidor (Sessões de jogador). Sem ele, o jogador navega anônimo.
path string Primeira rota, veja links diretos.
locale 'en' | 'pt-BR' Idioma; padrão: o do tenant.
height 'auto' | 'fill' Modo de tamanho. Padrão 'fill'.
minHeight number Modo auto: altura em px até o primeiro evento resize. Padrão 600.
scrollOffset number | false Modo auto: quando o jogador abre outra página do sportsbook com o topo do iframe fora da tela, o SDK rola a sua página de volta até ele, deixando esta quantidade de pixels para o seu cabeçalho fixo. Padrão 0; false desliga.
title string Nome acessível do iframe. Padrão Sportsbook.
onReady, onLoginRequired, onDepositRequested, onBalanceChanged, onBetPlaced, onBetSettled, onRouteChange, onResize, onError function Um callback por evento, chamado com o payload dele.
onSessionExpired function Devolva um launch token novo (ou uma promise dele) e o SDK envia set_launch_token; devolva null para manter o jogador deslogado. Uma chamada por vez.
onEvent function (type, payload) para todo evento, depois do callback específico.

Um callback que lança exceção é reportado com console.error e não impede os demais.

Membro
setLaunchToken(token) Faz o login do jogador, ou substitui uma sessão expirada, sem recarregar o iframe.
navigate(path) Vai para um link direto.
setLocale(locale) en ou pt-BR.
refreshBalance() Relê o saldo da sua carteira, por exemplo depois de um depósito no seu caixa. O iframe responde com balance_changed.
logout() Encerra a sessão do sportsbook (chame quando o jogador sair do seu site).
on(type, handler) Assina um tipo de evento; devolve a função para cancelar.
ready Promise do payload de ready.
iframe, origin O elemento iframe e a origem do sportsbook.
destroy() Remove o iframe e todos os listeners.

Comandos enviados antes de o sportsbook estar pronto ficam em fila e são enviados depois do ready.

Qualquer página pode enquadrar o sportsbook e falar o protocolo postMessage diretamente. Use a launchUrl devolvida por integration/sessions, ou monte a URL:

https://sportsbook.example.com/?tenant=<tenant>&launch=<launchToken>&path=/live&locale=pt-BR&height=fill&origin=https%3A%2F%2Fwww.seu-site.example
Parâmetro
tenant Obrigatório. Também diz ao servidor qual frame-ancestors enviar.
launch O launch token de uso único. Removido do endereço do iframe na hora.
path Primeira rota (links diretos). Um caminho inválido é ignorado e reportado com um evento error.
locale en ou pt-BR.
height auto ou fill (padrão). Em auto a página não pode depender da altura da viewport, por isso informe ao sportsbook.
origin A origem da sua página. Navegadores sem location.ancestorOrigins (Firefox) usam este valor, ou o Referer, para saber quem é o pai. É conferida contra as suas origens permitidas como qualquer outra.
token Obsoleto: o próprio token de sessão na URL. Ainda aceito em integrações existentes; use launch.
<iframe id="sb" title="Sportsbook" style="width: 100%; height: 100%; border: 0"
src="https://sportsbook.example.com/?tenant=seu-tenant&launch=lt_…&origin=https%3A%2F%2Fwww.seu-site.example"></iframe>
<script>
const SB = 'https://sportsbook.example.com';
const frame = document.getElementById('sb');
window.addEventListener('message', (e) => {
// só o nosso iframe, só a origem do sportsbook, só o protocolo v1
if (e.source !== frame.contentWindow || e.origin !== SB) return;
const m = e.data;
if (!m || m.source !== 'bookmaker-sportsbook' || m.v !== 1) return;
if (m.type === 'login_required') abrirSeuLogin();
if (m.type === 'balance_changed') atualizarSeuCabecalho(m.payload.balance, m.payload.currency);
});
function send(type, payload = {}) {
// sempre a origem exata do sportsbook, nunca '*'
frame.contentWindow.postMessage({ source: 'bookmaker-host', v: 1, type, payload }, SB);
}
// por exemplo, depois do seu login: send('set_launch_token', { launchToken });
</script>
auto fill
Altura O iframe cresce com o conteúdo: o SDK aplica a altura de cada evento resize. O iframe preenche o contêiner (height: 100%); dê uma altura ao contêiner.
Rolagem A sua página rola; o iframe não tem barra de rolagem. O sportsbook rola dentro do iframe.
Indicado para Páginas de desktop com o seu cabeçalho e rodapé em volta do sportsbook. Celulares e layouts no estilo de app.
Partes fixas O cabeçalho e o boletim do sportsbook rolam junto com a página. Cabeçalho, boletim e navegação inferior ficam sempre à vista.
/* fill: o sportsbook ocupa a tela abaixo do seu cabeçalho */
#sportsbook { height: calc(100dvh - var(--altura-do-seu-cabecalho)); }

Em telas com menos de 900 px o sportsbook muda para o layout móvel: uma barra de navegação inferior e um boletim em bottom sheet, ambos fixos na base da viewport do iframe. No modo auto essa viewport tem a altura do sportsbook inteiro, então eles ficariam muito abaixo da tela. Use fill em celulares, com altura em dvh para considerar as barras do navegador. O operador de referência escolhe por dispositivo:

height: matchMedia('(max-width: 899px)').matches ? 'fill' : 'auto',
Caminho Abre
/ Início: ao vivo agora e cupons em destaque
/live, /live/{sportId} Ao vivo, todos os esportes ou um (football, basketball, tennis)
/sport/{sportId} Competições e eventos de um esporte
/competition/{competitionId} Uma competição, por exemplo /competition/br-serie-a
/event/{eventId} Um evento com todos os mercados
/my-bets As apostas abertas e liquidadas do jogador (anônimo: login_required)

Abra um deles na inicialização com path e depois com navigate(path). O iframe informa cada navegação com um evento route ({path, title}); espelhe no seu próprio endereço para tornar as páginas do sportsbook compartilháveis, e devolva como path no próximo carregamento:

onRouteChange: ({ path, title }) => {
const url = new URL(location.href);
url.searchParams.set('sb', path);
history.replaceState(null, '', url);
document.title = `${title} · Seu Cassino`;
},
path: new URLSearchParams(location.search).get('sb') ?? undefined,

Hoje estão disponíveis en e pt-BR. Passe locale ao montar, ou troque a qualquer momento com setLocale(); o sportsbook é redesenhado no lugar e mantém a rota e o boletim. Sem nenhum dos dois, vale o idioma padrão do tenant.

Só os seus sites podem enquadrar o sportsbook e conversar com ele. Liste as origens exatas (esquema, host e porta, sem caminho, sem curingas) no embedOrigins do seu tenant:

  • A API envia Content-Security-Policy: frame-ancestors 'self' <suas origens> em toda página do sportsbook do seu tenant (só 'self' quando a lista está vazia), e os navegadores se recusam a exibi-lo dentro de qualquer outro site.
  • O iframe lê a mesma lista em GET /api/v1/config (tenant.embedOrigins), só aceita comandos de uma página pai em uma dessas origens e só envia eventos para essa origem verificada, nunca para '*'.
  • A própria origem do sportsbook é sempre permitida (para pré-visualizações e esta documentação).

Configure no back office em Configurações → Integração, ou pela API (token de staff):

PUT /api/v1/admin/tenant
Authorization: Bearer <token de staff>
Content-Type: application/json
{"embedOrigins": ["https://www.seu-cassino.example", "https://m.seu-cassino.example"]}

Se o seu site envia uma Content Security Policy, libere a origem do sportsbook para o script e para o frame:

script-src 'self' https://sportsbook.example.com; frame-src https://sportsbook.example.com
No sportsbook Quando incorporado
Cadastro, login, conta, depósitos, saques Ocultos: são seus.
Saldo no cabeçalho O saldo da sua carteira, identificado como tal.
Botão Depositar Envia deposit_requested; abra o seu caixa.
Botão Entrar, Entre para apostar, Minhas Apostas anônimo Enviam login_required com um reason; abra o seu login.
Fim da sessão session_expired; nenhum diálogo dentro do iframe.