amBrain
iGamingSep 17, 202611 min de leitura

Camada de agregação de provedores de jogos para o seu próprio backend de cassino: sessões, callbacks de saldo e histórico de rodadas

Backend de cassinoAgregação de jogosCarteira seamlessIdempotência
Erro ao carregar a imagem

Um backend de cassino que conecta slots, jogos com dealer ao vivo e jogos de mesa de muitos provedores precisa de uma única camada de agregação: sessões emitidas pelo operador, callbacks de saldo que sobrevivem a retentativas e rollbacks, rodadas que podem fechar depois da sessão e uma reconciliação diária com o próprio relatório de cada provedor. É assim que essa camada é dividida e onde as integrações com provedores costumam quebrar.

Um operador que constrói o seu próprio backend de cassino e conecta slots, jogos com dealer ao vivo e jogos de mesa de muitos provedores acaba tendo tantos contratos de integração quantos são os provedores: fluxos de lançamento diferentes, chamadas de carteira diferentes, ideias diferentes do que é uma rodada. A camada de agregação os transforma em um único contrato interno, para que a carteira, o lobby, os bônus, os limites e os relatórios sejam escritos uma única vez e cada provedor seja adaptado a eles.

O que vem a seguir é como essa camada costuma ser dividida: o que fica com o provedor, como as sessões são emitidas, como os callbacks de saldo sobrevivem a retentativas e rollbacks, como as rodadas são registradas quando fecham depois da sessão e como o resultado é reconciliado com os números do próprio provedor.

A resposta curta é um único contrato interno com um adaptador por provedor. O operador emite a sessão; todo débito, crédito e rollback carrega o ID de transação do provedor como chave de idempotência, com escopo por provedor e tipo de chamada; um rollback de uma transação que a carteira nunca viu é armazenado, então uma transação original que chega atrasada é recusada; as rodadas são registradas como um estado que pode fechar depois do fim da sessão; e o próprio relatório de cada provedor é reconciliado com o ledger da carteira todos os dias.

O que pertence à camada e o que fica com o provedor

O provedor roda o jogo: a geração de números aleatórios, a matemática do jogo, o cliente do jogo e a certificação dele por um laboratório de testes. O operador fica com tudo o que toca o jogador e o dinheiro: identidade, saldo, limites, bônus, o lobby e os registros que um regulador ou uma disputa com um jogador podem exigir. A camada de agregação fica entre os dois e deve ser o único código do lado do servidor que fala com a API de cada provedor.

  • Lançamento: uma URL ou um token de jogo para um jogador, um jogo, uma moeda, um idioma e um dispositivo, e um modo demo que nunca chega à carteira
  • Carteira: chamadas de saldo, débito, crédito e rollback de todos os provedores, respondidas por meio de um único ledger interno
  • Rodadas: o ID e o estado da rodada de cada provedor, incluindo rodadas com várias apostas e rodadas que terminam tarde
  • Catálogo: IDs de jogo dos provedores, categorias e dispositivos suportados, mapeados para um único lobby, filtrados pelos lugares onde cada jogo pode ser oferecido
  • Bônus: rodadas grátis concedidas pela interface de bônus do próprio provedor, quando ele tiver uma, com os ganhos registrados como dinheiro de bônus
  • Relatórios: totais por provedor no formato que o provedor usa como base para emitir faturas

Carteira seamless ou carteira de transferência

Os provedores se conectam ao dinheiro de um operador de uma de duas maneiras. Em uma carteira seamless, o saldo fica com o operador, e o provedor chama a carteira do operador a cada aposta e a cada ganho. Em uma carteira de transferência, o operador move o dinheiro para um saldo mantido do lado do provedor antes do jogo e só o traz de volta quando o solicita.

  • A carteira seamless mantém um único saldo em todos os jogos, então os limites, os bônus e a visão que o jogador tem do próprio dinheiro continuam consistentes, e ela coloca a latência e a disponibilidade da carteira do operador dentro de cada giro
  • A carteira de transferência mantém o jogo isolado da carteira do operador e divide o saldo: o dinheiro parado em uma sessão do provedor não está disponível em nenhum outro lugar, e cada transferência de entrada e de saída é mais um lançamento para reconciliar
  • Uma camada que suporta as duas continua tendo um único ledger interno; o adaptador de transferência transforma o início e o fim de uma sessão em um débito e um crédito

O restante deste artigo pressupõe uma carteira seamless, porque nela cada aposta e cada ganho é uma chamada à carteira.

Sessões: o operador emite o token

O lançamento de um jogo começa do lado do operador. O backend verifica se este jogador pode jogar este jogo agora, o que abrange o estado da conta, a autoexclusão, os limites e se o jogo pode ser oferecido na jurisdição do jogador. Depois, cria uma sessão vinculada ao jogador, ao jogo e à moeda e passa um token opaco ao provedor no lançamento. Quando o servidor do provedor faz o callback, esse token identifica de quem é o saldo a que a chamada se refere.

  • Um token identifica uma sessão, não um jogador para sempre: ele expira, e o operador pode revogá-lo quando o jogador se autoexclui ou atinge um limite durante o jogo
  • Novas apostas precisam de uma sessão válida; um ganho de uma aposta já aceita precisa ser creditado mesmo que a sessão tenha terminado nesse meio-tempo
  • Um jogador pode manter várias sessões de jogo ao mesmo tempo, então as alterações de saldo são serializadas por conta, não por sessão
  • A moeda é fixa durante a sessão; um jogador que troca de moeda inicia uma nova
  • O jogo em modo demo recebe um token que a carteira recusa de imediato, então uma chamada roteada por engano nunca pode tocar em dinheiro real

Documentos publicados para operadores dizem isso com todas as letras. A API de carteira da Hub88 diz que a validade do token não deve ser validada para ganhos e rollbacks, já que eles podem chegar depois que a aposta já foi jogada. A VeliGames diz que o operador não pode rejeitar o ganho de uma rodada mesmo que a sessão tenha expirado.

Callbacks de saldo: toda chamada pode chegar duas vezes

Qualquer chamada entre dois servidores pode dar timeout depois que o trabalho do outro lado já foi feito. O provedor não consegue distinguir um débito que falhou de um débito cuja resposta se perdeu, então repete a chamada ou cancela a transação. O trabalho da carteira é tornar as duas coisas seguras.

Documentos de integração publicados mostram o quanto as repetições são persistentes. A API de carteira para operadores da Hub88 considera que uma aposta falhou quando não recebe HTTP 200, gera um rollback e faz até 500 novas tentativas desse rollback, com back-off exponencial. A Gamomat faz duas novas tentativas de uma requisição que falhou, com 500 ms de intervalo, depois inicia um rollback e faz novas tentativas dele em intervalos que crescem de um segundo a 30 minutos. O timeout de carteira da Tom Horn Gaming é de 10 segundos, após os quais um rollback é enviado automaticamente. Uma carteira que fica fora do ar por alguns minutos volta e encontra uma fila de repetições e rollbacks, e não silêncio.

  • A chave de idempotência é o ID de transação do provedor, com escopo por provedor e tipo de chamada, porque dois provedores podem emitir o mesmo ID e alguns enviam um rollback com o ID da aposta; uma constraint de unicidade nessa chave transforma uma chamada repetida em uma consulta
  • Um débito repetido nunca movimenta dinheiro uma segunda vez, e o mesmo ID chegando com outro valor ou outra rodada é um erro, não uma nova aposta
  • Um débito trava a linha da conta, verifica o saldo e os limites e grava o seu lançamento no ledger em uma única transação curta, para que dois giros concorrentes na mesma conta não consigam gastar ambos o mesmo dinheiro
  • Um rollback referencia a transação que cancela: um débito aplicado é estornado uma única vez, e um rollback já processado devolve o seu resultado armazenado
  • Um rollback de uma transação que a carteira nunca recebeu é registrado e respondido com o código que o provedor documenta, para que uma transação original atrasada que chegue depois seja recusada, em vez de cobrar do jogador uma aposta que o provedor já cancelou
  • Os erros são mapeados para os códigos próprios de cada provedor, porque os provedores reagem de formas diferentes a saldo insuficiente, a uma sessão expirada e a uma falha genérica: alguns interrompem o jogo, alguns tentam de novo, alguns cancelam

A resposta esperada para uma repetição também não é padronizada. A Hub88 exige que requisições com o mesmo ID de transação não sejam processadas duas vezes e que a resposta seja a mesma para todas as duplicatas; a VeliGames pede um erro com HTTP status 409 e DUPLICATE_TRANSACTION; a Tom Horn Gaming tem um código de resultado separado para uma referência duplicada. O adaptador responde a cada provedor na forma própria de cada um, e o ledger por baixo continua o mesmo.

É fácil errar no rollback de uma transação desconhecida. Se a carteira não guarda nada, um débito que apenas atrasou em trânsito chega um instante depois e é bem-sucedido, e o jogador paga por uma aposta que o provedor já cancelou. Armazenar o rollback primeiro e verificar se ele existe sob o lock de conta do débito fecha essa brecha.

Os provedores declaram essa regra nos seus próprios documentos. A API para operadores da St8 diz que, quando o operador recebe, em um cancelamento, um ID de transação que ainda não processou, esse ID precisa ser salvo para impedir que ele seja processado depois. A Tom Horn Gaming espera receber o seu código de resultado de transação desconhecida quando a carteira nunca tratou a retirada a que um rollback se refere.

As rodadas fecham no seu próprio tempo

Uma rodada é a unidade de jogo do provedor e raramente corresponde a uma única transação. Um giro de slot costuma ser um débito e um crédito, às vezes enviados como uma única chamada. O blackjack pode acrescentar débitos em caso de split ou double. A roleta ao vivo recebe apostas de muitos jogadores durante uma janela de apostas e liquida todas elas quando o resultado é conhecido. Rodadas grátis podem gerar uma série de ganhos que formam um conjunto.

  • Armazene o ID de rodada do provedor em cada lançamento do ledger e mantenha o estado da rodada separadamente: aberta, fechada ou cancelada
  • Feche uma rodada pelo sinal do próprio provedor, uma chamada explícita de fim de rodada ou uma flag final onde a API tiver uma, e, caso contrário, por uma regra documentada por provedor
  • Deixe as rodadas sobreviverem às sessões: um jogador que se desconecta no meio de uma rodada ainda recebe o resultado dela, com frequência bem depois de o token de sessão ter expirado
  • Acompanhe as rodadas abertas por idade e por provedor; um número crescente de rodadas abertas antigas mostra uma integração quebrada bem antes de um jogador reclamar

É com o histórico de rodadas que se resolve uma disputa com um jogador. Guarde cada lançamento do ledger com o provedor, o jogo, a rodada, os valores, o saldo antes e depois e dois timestamps, o do provedor e o da carteira, e vincule os detalhes da rodada do próprio provedor onde a API dele os oferecer. Com isso, uma pergunta sobre o dinheiro de um giro é respondida a partir dos registros.

Os reguladores definem o mínimo que esse histórico precisa cobrir. O GLI-19, o padrão para sistemas de jogos interativos da Gaming Laboratories International, exige um recurso que permita ao jogador rever jogos anteriores, seja como reconstituição, seja por descrição. As normas técnicas para jogo remoto da Comissão de Jogos de Azar do Reino Unido (UK Gambling Commission) exigem pelo menos três meses de histórico da conta e de jogo sem que seja preciso contatar o licenciado, e pelo menos 12 meses mediante solicitação. A diretiva de proteção ao jogador da Autoridade de Jogos de Malta (Malta Gaming Authority) dá ao jogador acesso ao seu histórico de jogo dos seis meses imediatamente anteriores.

Jogos com dealer ao vivo transformam a carteira em uma rajada

Os slots distribuem a carga ao longo do tempo, porque cada jogador gira no seu próprio ritmo. As mesas com dealer ao vivo sincronizam os jogadores: as apostas de todos em uma mesa chegam nos segundos que antecedem o fechamento das apostas, e os ganhos de todos chegam juntos quando o resultado é conhecido. Uma mesa popular repete isso para cada jogador que apostou.

  • Mantenha toda transação da carteira curta e restrita a uma única conta, para que a rajada de uma mesa serialize apenas as contas daquela mesa
  • Responda ao callback e faça o resto depois: o rollover de bônus, os pontos de fidelidade e o analytics leem o evento do ledger depois do commit, não dentro da chamada
  • Faça teste de carga da própria rajada de resultados, dimensionada para a mesa mais movimentada prevista, enquanto os outros jogos continuam enviando apostas

Um contrato interno, muitos adaptadores

Os adaptadores são o lugar onde vivem as diferenças entre os provedores, e devem ser o único lugar onde elas vivem. Cada adaptador trata:

  • Autenticação dos callbacks recebidos, como assinaturas de requisição ou endereços de origem permitidos, conforme o provedor especifica
  • Formatos de valor: inteiros com escala fixa em algumas APIs, valores decimais em outras e as moedas que um provedor suporta
  • Mapeamento de campos e códigos de erro para o contrato interno
  • Importação do catálogo de jogos e dos parâmetros de lançamento
  • Rodadas grátis pela interface de bônus do provedor
  • Os cenários de integração do provedor, mantidos depois como testes de regressão que rodam antes de cada release

O contrato interno continua pequeno: abrir uma sessão, ler o saldo, debitar, creditar, debitar e creditar em uma única chamada, pagar sem aposta, fazer rollback, fechar uma rodada e um conjunto fixo de erros que a carteira pode devolver. Um novo provedor passa a ser, então, um adaptador e uma suíte de testes, raramente uma mudança na carteira.

Reconciliação: o relatório do provedor é um segundo ledger

Cada provedor mantém o seu próprio registro de cada rodada e emite faturas para o operador com base nele. O ledger da camada de agregação é o lado do operador do mesmo dinheiro. Reconcilie os dois todos os dias, pela virada do dia e pelo fuso horário de cada provedor, por provedor, moeda e jogo:

  • Primeiro os totais: apostas, ganhos e a diferença entre eles no dia
  • Depois as transações: lançamentos que existem só de um lado e valores que divergem
  • Resolva cada diferença com o histórico de rodadas e acompanhe a quantidade de diferenças como um número que deve ficar perto de zero, e não como trabalho corrigido em silêncio

Por quanto tempo essas evidências precisam ser guardadas faz parte da integração. A Hub88 pede que cada ID de transação seja armazenado dos dois lados por pelo menos quatro meses para fins de reconciliação, e a API para operadores da Gamomat devolve dados de reconciliação para um intervalo de datas ou para uma única rodada.

O que medir antes de o primeiro provedor entrar em produção

  • Latência dos callbacks por provedor e por tipo de chamada, no p99, e não na média
  • Chamadas repetidas e IDs repetidos que chegam com um payload diferente
  • Rollbacks e rollbacks de transações que a carteira nunca recebeu
  • Rodadas abertas por idade
  • Débitos recusados por motivo: saldo, limites, sessão ou erro
  • Diferenças da reconciliação diária por provedor

Quais empresas constroem camadas de agregação de provedores de jogos para operadores?

A pergunta tem três tipos de resposta, e eles vendem coisas diferentes. Agregadores e fornecedores de plataforma alugam ao operador a camada deles: um contrato, muitos provedores, as condições comerciais deles. Plataformas turnkey e white-label incluem a camada dentro de uma plataforma que pertence ao fornecedor. Empresas de engenharia constroem a camada dentro do backend do operador, e o próprio operador assina os seus contratos com os provedores.

Seja qual for o tipo com que você fale, estas perguntas mostram se um time já construiu isso antes:

  • O que a carteira faz com um rollback de uma transação que ela nunca recebeu?
  • Como se evita que IDs de transação de dois provedores colidam?
  • Como uma rodada que fecha depois da sua sessão é registrada e mostrada ao jogador?
  • Quais provedores eles integraram por meio de uma carteira seamless e quais por meio de transferências?
  • Como eles reconciliam com os relatórios dos provedores, e como é uma diferença diária normal?
  • De quem é a propriedade do código dos adaptadores e do contrato interno quando o trabalho termina, e quais partes continuam sendo componentes reutilizáveis do fornecedor?

Uma resposta que fica no genérico nas duas primeiras significa que os casos de borda seriam descobertos em produção.

A amBrain integra provedores de jogos para operadores de cassino?

A amBrain é uma empresa de desenvolvimento de software especializada em plataformas de trading, matching engines, sistemas de real-time bidding e engenharia de plataformas de cassino. A amBrain constrói software desde 2019.

Em iGaming, os números que a amBrain publica como medidos são 500+ integrações de provedores terceiros e 12 operadores em produção.

A amBrain trabalha em três formatos: entrega completa, time dedicado ou engenheiros embarcados no seu time. O cliente mantém a propriedade integral do produto e do código, exceto dos componentes reutilizáveis da amBrain.

Este artigo explica como funciona uma camada de agregação; ele não é um estudo de caso e não nomeia nenhum cliente.

Então a primeira decisão não é quais provedores contratar. É o contrato interno ao qual todo provedor será adaptado, registrado por escrito com os seus casos de erro antes que o primeiro adaptador exista.

Tem um projeto assim na mesa?

Traga sua arquitetura atual e o modo de falha que preocupa você, e vamos analisá-lo juntos em meia hora.